[PATCH 4/4] msvcrt: Fix _wsearchenv and _wsearchenv_s

Kirill Erofeev erofeev.info at gmail.com
Wed Feb 14 06:28:17 CST 2018


 - in some cases the last '\' was not appended to curPath.
   (reason char next to the last one was checked for delimiter)
 - not all PATH list elements processed in case leading ';' or double ';'
   are present in environment variable. I.e empty element stops further
   processing.

Signed-off-by: Kirill Erofeev <erofeev.info at gmail.com>
---
 dlls/msvcrt/dir.c | 88 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 48 insertions(+), 40 deletions(-)

diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index b864a75..5f094e1 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -1798,6 +1798,8 @@ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t*
 {
   MSVCRT_wchar_t *envVal, *penv;
   MSVCRT_wchar_t curPath[MAX_PATH];
+  MSVCRT_size_t path_len;
+  const MSVCRT_size_t fname_len = strlenW(file);
 
   *buf = '\0';
 
@@ -1826,30 +1828,31 @@ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t*
     MSVCRT_wchar_t *end = penv;
 
     while(*end && *end != ';') end++; /* Find end of next path */
-    if (penv == end || !*penv)
-    {
-      msvcrt_set_errno(ERROR_FILE_NOT_FOUND);
-      return;
-    }
-    memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t));
-    if (curPath[end - penv] != '/' && curPath[end - penv] != '\\')
+    path_len = end - penv;
+    if (penv != end && *penv &&
+       (path_len + fname_len) < MAX_PATH)/*If temporary buffer is not enough just skip. Other way is to use dynamic memory. We will not.*/
     {
-      curPath[end - penv] = '\\';
-      curPath[end - penv + 1] = '\0';
-    }
-    else
-      curPath[end - penv] = '\0';
+      memcpy(curPath, penv, path_len * sizeof(MSVCRT_wchar_t));
+      if (curPath[path_len - 1] != '/' && curPath[path_len - 1] != '\\')
+      {
+        curPath[path_len] = '\\';
+        curPath[path_len + 1] = '\0';
+      }
+      else
+        curPath[end - penv] = '\0';
 
-    strcatW(curPath, file);
-    TRACE("Checking for file %s\n", debugstr_w(curPath));
-    if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES)
-    {
-      strcpyW(buf, curPath);
-      msvcrt_set_errno(ERROR_FILE_NOT_FOUND);
-      return; /* Found */
+      strcatW(curPath, file);
+      TRACE("Checking for file %s\n", debugstr_w(curPath));
+      if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES)
+      {
+        strcpyW(buf, curPath);
+        break; /* Found */
+      }
     }
     penv = *end ? end + 1 : end;
-  } while(1);
+  } while(*penv);
+  msvcrt_set_errno(ERROR_FILE_NOT_FOUND);
+  return;
 }
 
 /*********************************************************************
@@ -1860,6 +1863,8 @@ int CDECL MSVCRT__wsearchenv_s(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t*
 {
   MSVCRT_wchar_t*       envVal, *penv;
   MSVCRT_wchar_t        curPath[MAX_PATH];
+  MSVCRT_size_t path_len;
+  const MSVCRT_size_t fname_len = strlenW(file);
 
   if (!MSVCRT_CHECK_PMT(file != NULL)) return MSVCRT_EINVAL;
   if (!MSVCRT_CHECK_PMT(buf != NULL)) return MSVCRT_EINVAL;
@@ -1891,32 +1896,35 @@ int CDECL MSVCRT__wsearchenv_s(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t*
     MSVCRT_wchar_t *end = penv;
 
     while(*end && *end != ';') end++; /* Find end of next path */
-    if (penv == end || !*penv)
-    {
-      *MSVCRT__errno() = MSVCRT_ENOENT;
-      return MSVCRT_ENOENT;
-    }
-    memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t));
-    if (curPath[end - penv] != '/' && curPath[end - penv] != '\\')
+    path_len = end - penv;
+    if (penv != end && *penv &&
+       (path_len + fname_len) < MAX_PATH)/*If temporary buffer is not enough just skip. Other way is to use dynamic memory. We will not.*/
     {
-      curPath[end - penv] = '\\';
-      curPath[end - penv + 1] = '\0';
-    }
-    else
-      curPath[end - penv] = '\0';
+      memcpy(curPath, penv, path_len * sizeof(MSVCRT_wchar_t));
+      if (curPath[path_len - 1] != '/' && curPath[path_len - 1] != '\\')
+      {
+        curPath[path_len] = '\\';
+        curPath[path_len + 1] = '\0';
+      }
+      else
+        curPath[path_len] = '\0';
 
-    strcatW(curPath, file);
-    TRACE("Checking for file %s\n", debugstr_w(curPath));
-    if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES)
-    {
-      if (strlenW(curPath) + 1 > count)
+      strcatW(curPath, file);
+      TRACE("Checking for file %s\n", debugstr_w(curPath));
+      if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES)
       {
+        if (strlenW(curPath) + 1 > count)
+        {
           MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE);
           return MSVCRT_ERANGE;
+        }
+        strcpyW(buf, curPath);
+        return 0;
       }
-      strcpyW(buf, curPath);
-      return 0;
     }
     penv = *end ? end + 1 : end;
-  } while(1);
+  } while(*penv);
+  *MSVCRT__errno() = MSVCRT_ENOENT;
+  return MSVCRT_ENOENT;
 }
+
-- 
2.7.4




More information about the wine-devel mailing list