From c551ff588b48cc4c286922779651890da0f3c22c Mon Sep 17 00:00:00 2001
From: KWSys Upstream <kwrobot@kitware.com>
Date: Tue, 10 Oct 2017 08:43:01 -0400
Subject: KWSys 2017-10-10 (239bc737)

Code extracted from:

    https://gitlab.kitware.com/utils/kwsys.git

at commit 239bc737543886a72c5e9e3445d51e17f7e26abe (master).

Upstream Shortlog
-----------------

Matthias Maennich (5):
      6599eda6 testRobustEncoding: restore format flags for std::cout before exiting
      862562ce SystemInformation: fix potential off-by-one write
      13e02b76 processUNIX: close intermediate file descriptor in error case
      73c491e8 processUNIX: fix not null terminated buffer during error reporting
      ce55a255 testSystemTools: fix some copy'n'paste issues

Rolf Eike Beer (5):
      6ca15069 SystemTools: make Getcwd() more efficient on Windows
      6d7eb3a1 CommandLineArguments: do not check variable before delete[]
      3b8fefea remove pointer checks before calling free()
      cf8beae3 ProcessUNIX: use strdup() instead of open coding it
      5d2aff9d ProcessWin32: use strdup() instead of open coding it
---
 CommandLineArguments.cxx |  5 +----
 ProcessUNIX.c            | 20 +++++++-------------
 ProcessWin32.c           | 15 ++++-----------
 SystemInformation.cxx    |  2 +-
 SystemTools.cxx          | 17 +++++++++++------
 testEncoding.cxx         |  5 +++++
 testProcess.c            |  4 +---
 testSystemTools.cxx      | 10 +++++-----
 8 files changed, 35 insertions(+), 43 deletions(-)

diff --git a/CommandLineArguments.cxx b/CommandLineArguments.cxx
index 5613bd7..5498377 100644
--- a/CommandLineArguments.cxx
+++ b/CommandLineArguments.cxx
@@ -649,10 +649,7 @@ void CommandLineArguments::PopulateVariable(double* variable,
 void CommandLineArguments::PopulateVariable(char** variable,
                                             const std::string& value)
 {
-  if (*variable) {
-    delete[] * variable;
-    *variable = 0;
-  }
+  delete[] * variable;
   *variable = new char[value.size() + 1];
   strcpy(*variable, value.c_str());
 }
diff --git a/ProcessUNIX.c b/ProcessUNIX.c
index 3b32ca7..1431f30 100644
--- a/ProcessUNIX.c
+++ b/ProcessUNIX.c
@@ -359,9 +359,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
-  if (cp->CommandExitCodes) {
-    free(cp->CommandExitCodes);
-  }
+  free(cp->CommandExitCodes);
   free(cp->ProcessResults);
   free(cp);
 }
@@ -498,11 +496,10 @@ int kwsysProcess_SetWorkingDirectory(kwsysProcess* cp, const char* dir)
     cp->WorkingDirectory = 0;
   }
   if (dir) {
-    cp->WorkingDirectory = (char*)malloc(strlen(dir) + 1);
+    cp->WorkingDirectory = strdup(dir);
     if (!cp->WorkingDirectory) {
       return 0;
     }
-    strcpy(cp->WorkingDirectory, dir);
   }
   return 1;
 }
@@ -531,11 +528,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int prPipe, const char* file)
     *pfile = 0;
   }
   if (file) {
-    *pfile = (char*)malloc(strlen(file) + 1);
+    *pfile = strdup(file);
     if (!*pfile) {
       return 0;
     }
-    strcpy(*pfile, file);
   }
 
   /* If we are redirecting the pipe, do not share it or use a native
@@ -1514,9 +1510,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
   oldForkPIDs = cp->ForkPIDs;
   cp->ForkPIDs = (volatile pid_t*)malloc(sizeof(volatile pid_t) *
                                          (size_t)(cp->NumberOfCommands));
-  if (oldForkPIDs) {
-    kwsysProcessVolatileFree(oldForkPIDs);
-  }
+  kwsysProcessVolatileFree(oldForkPIDs);
   if (!cp->ForkPIDs) {
     return 0;
   }
@@ -1524,9 +1518,7 @@ static int kwsysProcessInitialize(kwsysProcess* cp)
     cp->ForkPIDs[i] = 0; /* can't use memset due to volatile */
   }
 
-  if (cp->CommandExitCodes) {
-    free(cp->CommandExitCodes);
-  }
+  free(cp->CommandExitCodes);
   cp->CommandExitCodes =
     (int*)malloc(sizeof(int) * (size_t)(cp->NumberOfCommands));
   if (!cp->CommandExitCodes) {
@@ -1938,6 +1930,7 @@ static int kwsysProcessSetupOutputPipeFile(int* p, const char* name)
 
   /* Set close-on-exec flag on the pipe's end.  */
   if (fcntl(fout, F_SETFD, FD_CLOEXEC) < 0) {
+    close(fout);
     return 0;
   }
 
@@ -2290,6 +2283,7 @@ static void kwsysProcessChildErrorExit(int errorPipe)
   char buffer[KWSYSPE_PIPE_BUFFER_SIZE];
   kwsysProcess_ssize_t result;
   strncpy(buffer, strerror(errno), KWSYSPE_PIPE_BUFFER_SIZE);
+  buffer[KWSYSPE_PIPE_BUFFER_SIZE - 1] = '\0';
 
   /* Report the error to the parent through the special pipe.  */
   result = write(errorPipe, buffer, strlen(buffer));
diff --git a/ProcessWin32.c b/ProcessWin32.c
index 5183e3d..945fa28 100644
--- a/ProcessWin32.c
+++ b/ProcessWin32.c
@@ -523,9 +523,7 @@ void kwsysProcess_Delete(kwsysProcess* cp)
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDIN, 0);
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDOUT, 0);
   kwsysProcess_SetPipeFile(cp, kwsysProcess_Pipe_STDERR, 0);
-  if (cp->CommandExitCodes) {
-    free(cp->CommandExitCodes);
-  }
+  free(cp->CommandExitCodes);
   free(cp->ProcessResults);
   free(cp);
 }
@@ -713,11 +711,10 @@ int kwsysProcess_SetPipeFile(kwsysProcess* cp, int pipe, const char* file)
     *pfile = 0;
   }
   if (file) {
-    *pfile = (char*)malloc(strlen(file) + 1);
+    *pfile = strdup(file);
     if (!*pfile) {
       return 0;
     }
-    strcpy(*pfile, file);
   }
 
   /* If we are redirecting the pipe, do not share it or use a native
@@ -1607,9 +1604,7 @@ int kwsysProcessInitialize(kwsysProcess* cp)
   }
   ZeroMemory(cp->ProcessInformation,
              sizeof(PROCESS_INFORMATION) * cp->NumberOfCommands);
-  if (cp->CommandExitCodes) {
-    free(cp->CommandExitCodes);
-  }
+  free(cp->CommandExitCodes);
   cp->CommandExitCodes = (DWORD*)malloc(sizeof(DWORD) * cp->NumberOfCommands);
   if (!cp->CommandExitCodes) {
     return 0;
@@ -2362,9 +2357,7 @@ static int kwsysProcess_List__New_NT4(kwsysProcess_List* self)
 static void kwsysProcess_List__Delete_NT4(kwsysProcess_List* self)
 {
   /* Free the process information buffer.  */
-  if (self->Buffer) {
-    free(self->Buffer);
-  }
+  free(self->Buffer);
 }
 
 static int kwsysProcess_List__Update_NT4(kwsysProcess_List* self)
diff --git a/SystemInformation.cxx b/SystemInformation.cxx
index 86fdccd..366fe30 100644
--- a/SystemInformation.cxx
+++ b/SystemInformation.cxx
@@ -1346,7 +1346,7 @@ std::string SymbolProperties::GetBinary() const
     std::string binary;
     char buf[1024] = { '\0' };
     ssize_t ll = 0;
-    if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0) {
+    if ((ll = readlink("/proc/self/exe", buf, 1024)) > 0 && ll < 1024) {
       buf[ll] = '\0';
       binary = buf;
     } else {
diff --git a/SystemTools.cxx b/SystemTools.cxx
index ecfa331..a24a326 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -20,6 +20,7 @@
 #include KWSYS_HEADER(SystemTools.hxx)
 #include KWSYS_HEADER(Directory.hxx)
 #include KWSYS_HEADER(FStream.hxx)
+#include KWSYS_HEADER(Encoding.h)
 #include KWSYS_HEADER(Encoding.hxx)
 
 #include <fstream>
@@ -227,13 +228,17 @@ inline const char* Getcwd(char* buf, unsigned int len)
 {
   std::vector<wchar_t> w_buf(len);
   if (_wgetcwd(&w_buf[0], len)) {
-    // make sure the drive letter is capital
-    if (wcslen(&w_buf[0]) > 1 && w_buf[1] == L':') {
-      w_buf[0] = towupper(w_buf[0]);
+    size_t nlen = kwsysEncoding_wcstombs(buf, &w_buf[0], len);
+    if (nlen == static_cast<size_t>(-1)) {
+      return 0;
+    }
+    if (nlen < len) {
+      // make sure the drive letter is capital
+      if (nlen > 1 && buf[1] == ':') {
+        buf[0] = toupper(buf[0]);
+      }
+      return buf;
     }
-    std::string tmp = KWSYS_NAMESPACE::Encoding::ToNarrow(&w_buf[0]);
-    strcpy(buf, tmp.c_str());
-    return buf;
   }
   return 0;
 }
diff --git a/testEncoding.cxx b/testEncoding.cxx
index 2c5ef46..2742fe4 100644
--- a/testEncoding.cxx
+++ b/testEncoding.cxx
@@ -75,6 +75,10 @@ static int testRobustEncoding()
   // test that the conversion functions handle invalid
   // unicode correctly/gracefully
 
+  // we manipulate the format flags of stdout, remember
+  // the original state here to restore before return
+  std::ios::fmtflags const& flags = std::cout.flags();
+
   int ret = 0;
   char cstr[] = { (char)-1, 0 };
   // this conversion could fail
@@ -120,6 +124,7 @@ static int testRobustEncoding()
     ret++;
   }
 
+  std::cout.flags(flags);
   return ret;
 }
 
diff --git a/testProcess.c b/testProcess.c
index 092dd03..cd817d9 100644
--- a/testProcess.c
+++ b/testProcess.c
@@ -687,9 +687,7 @@ int main(int argc, const char* argv[])
     fflush(stdout);
     fflush(stderr);
 #if defined(_WIN32)
-    if (argv0) {
-      free(argv0);
-    }
+    free(argv0);
 #endif
     return r;
   } else if (argc > 2 && strcmp(argv[1], "0") == 0) {
diff --git a/testSystemTools.cxx b/testSystemTools.cxx
index 768eb4d..3b694c9 100644
--- a/testSystemTools.cxx
+++ b/testSystemTools.cxx
@@ -254,22 +254,22 @@ static bool CheckFileOperations()
   }
   // should work, was created as new file before
   if (!kwsys::SystemTools::FileExists(testNewFile)) {
-    std::cerr << "Problem with FileExists for: " << testNewDir << std::endl;
+    std::cerr << "Problem with FileExists for: " << testNewFile << std::endl;
     res = false;
   }
   if (!kwsys::SystemTools::FileExists(testNewFile.c_str())) {
-    std::cerr << "Problem with FileExists as C string for: " << testNewDir
+    std::cerr << "Problem with FileExists as C string for: " << testNewFile
               << std::endl;
     res = false;
   }
   if (!kwsys::SystemTools::FileExists(testNewFile, true)) {
-    std::cerr << "Problem with FileExists as file for: " << testNewDir
+    std::cerr << "Problem with FileExists as file for: " << testNewFile
               << std::endl;
     res = false;
   }
   if (!kwsys::SystemTools::FileExists(testNewFile.c_str(), true)) {
     std::cerr << "Problem with FileExists as C string and file for: "
-              << testNewDir << std::endl;
+              << testNewFile << std::endl;
     res = false;
   }
 
@@ -285,7 +285,7 @@ static bool CheckFileOperations()
   }
   // should work, was created as new file before
   if (!kwsys::SystemTools::PathExists(testNewFile)) {
-    std::cerr << "Problem with PathExists for: " << testNewDir << std::endl;
+    std::cerr << "Problem with PathExists for: " << testNewFile << std::endl;
     res = false;
   }
 
-- 
cgit v0.12