Browse Source

Use secure versions of CRT getenv etc. when compiling with MSVC

rdb 3 years ago
parent
commit
21377c8de5

+ 39 - 6
dtool/src/dtoolutil/executionEnvironment.cxx

@@ -259,10 +259,14 @@ ns_has_environment_variable(const string &var) const {
     return true;
   }
 
-#ifndef PREREAD_ENVIRONMENT
-  return getenv(var.c_str()) != nullptr;
-#else
+#ifdef PREREAD_ENVIRONMENT
   return false;
+#elif defined(_MSC_VER)
+  size_t size = 0;
+  getenv_s(&size, nullptr, 0, var.c_str());
+  return size != 0;
+#else
+  return getenv(var.c_str()) != nullptr;
 #endif
 }
 
@@ -301,11 +305,24 @@ ns_get_environment_variable(const string &var) const {
   }
 
 #ifndef PREREAD_ENVIRONMENT
+#ifdef _MSC_VER
+  std::string value(128, '\0');
+  size_t size = value.size();
+  while (getenv_s(&size, &value[0], size, var.c_str()) == ERANGE) {
+    value.resize(size);
+  }
+  if (size != 0) {
+    // Strip off the trailing null byte.
+    value.resize(size - 1);
+    return value;
+  }
+#else
   const char *def = getenv(var.c_str());
   if (def != nullptr) {
     return def;
   }
 #endif
+#endif
 
 #ifdef _WIN32
   // On Windows only, we also simulate several standard folder names as
@@ -414,14 +431,15 @@ ns_get_environment_variable(const string &var) const {
 void ExecutionEnvironment::
 ns_set_environment_variable(const string &var, const string &value) {
   _variables[var] = value;
+
+#ifdef _MSC_VER
+  _putenv_s(var.c_str(), value.c_str());
+#else
   string putstr = var + "=" + value;
 
   // putenv() requires us to malloc a new C-style string.
   char *put = (char *)malloc(putstr.length() + 1);
   strcpy(put, putstr.c_str());
-#ifdef _MSC_VER
-  _putenv(put);
-#else
   putenv(put);
 #endif
 }
@@ -447,12 +465,27 @@ ns_clear_shadow(const string &var) {
 
 #ifdef PREREAD_ENVIRONMENT
   // Now we have to replace the value in the table.
+#ifdef _MSC_VER
+  std::string value(128, '\0');
+  size_t size = value.size();
+  while (getenv_s(&size, &value[0], size, var.c_str()) == ERANGE) {
+    value.resize(size);
+  }
+  if (size != 0) {
+    // Strip off the trailing null byte.
+    value.resize(size - 1);
+    (*vi).second = std::move(value);
+  } else {
+    _variables.erase(vi);
+  }
+#else
   const char *def = getenv(var.c_str());
   if (def != nullptr) {
     (*vi).second = def;
   } else {
     _variables.erase(vi);
   }
+#endif
 #endif  // PREREAD_ENVIRONMENT
 }
 

+ 12 - 0
dtool/src/dtoolutil/filename.cxx

@@ -152,10 +152,22 @@ get_panda_root() {
 
   if (panda_root == nullptr) {
     panda_root = new string;
+
+#ifdef _MSC_VER
+    char *envvar = nullptr;
+    size_t size = 0;
+    while (getenv_s(&size, envvar, size, "PANDA_ROOT") == ERANGE) {
+      envvar = (char *)alloca(size);
+    }
+    if (size != 0) {
+      (*panda_root) = front_to_back_slash(envvar);
+    }
+#else
     const char *envvar = getenv("PANDA_ROOT");
     if (envvar != nullptr) {
       (*panda_root) = front_to_back_slash(envvar);
     }
+#endif
 
     // Ensure the string ends in a backslash.  If PANDA_ROOT is empty or
     // undefined, this function must return a single backslash--not an empty

+ 10 - 2
dtool/src/dtoolutil/panda_getopt_impl.cxx

@@ -140,6 +140,10 @@ PandaGetopt(int argc, char *const argv[], const char *optstring,
   // _options[0] is used for invalid characters.
   _options.push_back(Option('?', no_argument));
 
+#ifdef _MSC_VER
+  size_t size;
+#endif
+
   if (optstring[0] == '-') {
     // RETURN_IN_ORDER: Non-option arguments (operands) are handled as if they
     // were the argument to an option with the value 1 ('\001').
@@ -154,8 +158,12 @@ PandaGetopt(int argc, char *const argv[], const char *optstring,
     // argument is reached, or when the element of argv is "--".
     ++optstring;
     _require_order = true;
-
-  } else if (getenv("POSIXLY_CORRECT") != nullptr) {
+  }
+#ifdef _MSC_VER
+  else if (getenv_s(&size, nullptr, 0, "POSIXLY_CORRECT") == 0 && size != 0) {
+#else
+  else if (getenv("POSIXLY_CORRECT") != nullptr) {
+#endif
     // REQUIRE_ORDER.
     _require_order = true;
 

+ 3 - 4
dtool/src/dtoolutil/pfstreamBuf.cxx

@@ -331,8 +331,9 @@ open_pipe(const string &cmd) {
 
   // Both WinExec() and CreateProcess() want a non-const char pointer.  Maybe
   // they change it, and maybe they don't.  I'm not taking chances.
-  char *cmdline = new char[cmd.length() + 1];
-  strcpy(cmdline, cmd.c_str());
+  char *cmdline = (char *)alloca(cmd.size() + 1);
+  memcpy(cmdline, cmd.data(), cmd.size());
+  cmdline[cmd.size()] = 0;
 
   // We should be using CreateProcess() instead of WinExec(), but that seems
   // to be likely to crash Win98.  WinExec() seems better behaved, and it's
@@ -345,8 +346,6 @@ open_pipe(const string &cmd) {
     // Don't return yet, since we still need to clean up.
   }
 
-  delete[] cmdline;
-
   // Now restore our own stdout, up here in the parent process.
   if (!SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
 #ifndef NDEBUG

+ 7 - 0
dtool/src/interrogate/interrogate.cxx

@@ -547,8 +547,15 @@ main(int argc, char **argv) {
   // We allow overriding this value by setting SOURCE_DATE_EPOCH to support
   // reproducible builds.
   int file_identifier;
+#ifdef _MSC_VER
+  char source_date_epoch[64];
+  size_t source_date_epoch_size = 0;
+  if (getenv_s(&source_date_epoch_size, source_date_epoch,
+               sizeof(source_date_epoch), "SOURCE_DATE_EPOCH"), source_date_epoch_size > 1) {
+#else
   const char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
   if (source_date_epoch != nullptr && source_date_epoch[0] != 0) {
+#endif
     file_identifier = atoi(source_date_epoch);
   } else {
     file_identifier = time(nullptr);

+ 7 - 0
panda/src/downloadertools/multify.cxx

@@ -792,8 +792,15 @@ main(int argc, char **argv) {
     }
   }
 
+#ifdef _MSC_VER
+  char source_date_epoch_str[64];
+  size_t source_date_epoch_size = 0;
+  if (getenv_s(&source_date_epoch_size, source_date_epoch_str,
+               sizeof(source_date_epoch_str), "SOURCE_DATE_EPOCH"), source_date_epoch_size > 1) {
+#else
   const char *source_date_epoch_str = getenv("SOURCE_DATE_EPOCH");
   if (source_date_epoch_str != nullptr && source_date_epoch_str[0] != 0) {
+#endif
     source_date_epoch = (time_t)strtoll(source_date_epoch_str, nullptr, 10);
   }
 

+ 12 - 0
panda/src/express/zipArchive.cxx

@@ -2018,7 +2018,13 @@ write_index(std::ostream &write, streampos &fpos) {
 
   if (_timestamp > dos_epoch) {
     // Convert from UNIX timestamp to DOS/FAT timestamp.
+#ifdef _MSC_VER
+    struct tm time_data;
+    struct tm *time = &time_data;
+    localtime_s(time, &_timestamp);
+#else
     struct tm *time = localtime(&_timestamp);
+#endif
     writer.add_uint16((time->tm_sec >> 1)
                     | (time->tm_min << 5)
                     | (time->tm_hour << 11));
@@ -2120,7 +2126,13 @@ write_header(std::ostream &write, std::streampos &fpos) {
 
   if (_timestamp > 315532800) {
     // Convert from UNIX timestamp to DOS/FAT timestamp.
+#ifdef _MSC_VER
+    struct tm time_data;
+    struct tm *time = &time_data;
+    localtime_s(time, &_timestamp);
+#else
     struct tm *time = localtime(&_timestamp);
+#endif
     writer.add_uint16((time->tm_sec >> 1)
                     | (time->tm_min << 5)
                     | (time->tm_hour << 11));