- 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(a)gmail.com> --- dlls/msvcrt/dir.c | 177 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 80 deletions(-) diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index f4edc28..5f094e1 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -1658,6 +1658,8 @@ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) { char*envVal, *penv; char curPath[MAX_PATH]; + MSVCRT_size_t path_len; + const MSVCRT_size_t fname_len = strlen(file); *buf = '\0'; @@ -1686,30 +1688,33 @@ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) char *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); - if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') - { - curPath[end - penv] = '\\'; - curPath[end - penv + 1] = '\0'; - } - else - curPath[end - penv] = '\0'; + path_len = end - penv; - strcat(curPath, file); - TRACE("Checking for file %s\n", curPath); - if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) + 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.*/ { - strcpy(buf, curPath); - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); - return; /* Found */ + memcpy(curPath, penv, path_len); + if (curPath[path_len - 1] != '/' && curPath[path_len - 1] != '\\') + { + curPath[path_len] = '\\'; + curPath[path_len + 1] = '\0'; + } + else + curPath[path_len] = '\0'; + + strcat(curPath, file); + TRACE("Checking for file %s\n", curPath); + if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) + { + strcpy(buf, curPath); + break; /* Found */ + } } penv = *end ? end + 1 : end; - } while(1); + } while(*penv); + + msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + return; } /********************************************************************* @@ -1719,6 +1724,8 @@ int CDECL MSVCRT__searchenv_s(const char* file, const char* env, char *buf, MSVC { char*envVal, *penv; char curPath[MAX_PATH]; + MSVCRT_size_t path_len; + const MSVCRT_size_t fname_len = strlen(file); if (!MSVCRT_CHECK_PMT(file != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(buf != NULL)) return MSVCRT_EINVAL; @@ -1750,34 +1757,36 @@ int CDECL MSVCRT__searchenv_s(const char* file, const char* env, char *buf, MSVC char *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); - 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); + if (curPath[path_len - 1] != '/' && curPath[path_len - 1] != '\\') + { + curPath[path_len] = '\\'; + curPath[path_len + 1] = '\0'; + } + else + curPath[path_len] = '\0'; - strcat(curPath, file); - TRACE("Checking for file %s\n", curPath); - if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) - { - if (strlen(curPath) + 1 > count) + strcat(curPath, file); + TRACE("Checking for file %s\n", curPath); + if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) { + if (strlen(curPath) + 1 > count) + { MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); return MSVCRT_ERANGE; + } + strcpy(buf, curPath); + return 0; } - strcpy(buf, curPath); - return 0; } penv = *end ? end + 1 : end; - } while(1); + } while(*penv); + *MSVCRT__errno() = MSVCRT_ENOENT; + return MSVCRT_ENOENT; } /********************************************************************* @@ -1789,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'; @@ -1817,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) + 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.*/ { - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); - return; - } - memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t)); - if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') - { - 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; } /********************************************************************* @@ -1851,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; @@ -1882,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) + 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.*/ { - *MSVCRT__errno() = MSVCRT_ENOENT; - return MSVCRT_ENOENT; - } - memcpy(curPath, penv, (end - penv) * sizeof(MSVCRT_wchar_t)); - if (curPath[end - penv] != '/' && curPath[end - penv] != '\\') - { - 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