diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c index f4edc287e8a..e8cba58ac7f 100644 --- a/dlls/msvcrt/dir.c +++ b/dlls/msvcrt/dir.c @@ -1656,8 +1656,9 @@ range: */ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) { - char*envVal, *penv; - char curPath[MAX_PATH]; + char*envVal, *penv, *end; + char path[MAX_PATH]; + MSVCRT_size_t path_len, fname_len = strlen(file); *buf = '\0'; @@ -1665,8 +1666,6 @@ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) if (GetFileAttributesA( file ) != INVALID_FILE_ATTRIBUTES) { GetFullPathNameA( file, MAX_PATH, buf, NULL ); - /* Sigh. This error is *always* set, regardless of success */ - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); return; } @@ -1681,35 +1680,31 @@ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) penv = envVal; TRACE(":searching for %s in paths %s\n", file, envVal); - do + for(; *penv; penv = (*end ? end + 1 : end)) { - char *end = penv; - + end = penv; while(*end && *end != ';') end++; /* Find end of next path */ - if (penv == end || !*penv) + path_len = end - penv; + if (!path_len || path_len >= MAX_PATH) + continue; + + memcpy(path, penv, path_len); + if (path[path_len - 1] != '/' && path[path_len - 1] != '\\') + path[path_len++] = '\\'; + if (path_len + fname_len >= MAX_PATH) + continue; + + memcpy(path + path_len, file, fname_len + 1); + TRACE("Checking for file %s\n", path); + if (GetFileAttributesA( path ) != INVALID_FILE_ATTRIBUTES) { - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + memcpy(buf, path, path_len + fname_len + 1); 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'; + } - strcat(curPath, file); - TRACE("Checking for file %s\n", curPath); - if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) - { - strcpy(buf, curPath); - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); - return; /* Found */ - } - penv = *end ? end + 1 : end; - } while(1); + msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + return; } /********************************************************************* @@ -1717,13 +1712,18 @@ void CDECL MSVCRT__searchenv(const char* file, const char* env, char *buf) */ int CDECL MSVCRT__searchenv_s(const char* file, const char* env, char *buf, MSVCRT_size_t count) { - char*envVal, *penv; - char curPath[MAX_PATH]; + char *envVal, *penv, *end; + char path[MAX_PATH]; + MSVCRT_size_t path_len, fname_len; if (!MSVCRT_CHECK_PMT(file != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(buf != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(count > 0)) return MSVCRT_EINVAL; + if (count > MAX_PATH) + FIXME("count > MAX_PATH not supported\n"); + + fname_len = strlen(file); *buf = '\0'; /* Try CWD first */ @@ -1745,39 +1745,36 @@ int CDECL MSVCRT__searchenv_s(const char* file, const char* env, char *buf, MSVC penv = envVal; TRACE(":searching for %s in paths %s\n", file, envVal); - do + for(; *penv; penv = (*end ? end + 1 : end)) { - char *end = penv; - + 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] != '\\') - { - curPath[end - penv] = '\\'; - curPath[end - penv + 1] = '\0'; - } - else - curPath[end - penv] = '\0'; + path_len = end - penv; + if (!path_len || path_len >= MAX_PATH) + continue; - strcat(curPath, file); - TRACE("Checking for file %s\n", curPath); - if (GetFileAttributesA( curPath ) != INVALID_FILE_ATTRIBUTES) + memcpy(path, penv, path_len); + if (path[path_len - 1] != '/' && path[path_len - 1] != '\\') + path[path_len++] = '\\'; + if (path_len + fname_len >= MAX_PATH) + continue; + + memcpy(path + path_len, file, fname_len + 1); + TRACE("Checking for file %s\n", path); + if (GetFileAttributesA( path ) != INVALID_FILE_ATTRIBUTES) { - if (strlen(curPath) + 1 > count) + if (path_len + fname_len + 1 > count) { - MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); - return MSVCRT_ERANGE; + MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); + return MSVCRT_ERANGE; } - strcpy(buf, curPath); + memcpy(buf, path, path_len + fname_len + 1); return 0; } - penv = *end ? end + 1 : end; - } while(1); + } + + *MSVCRT__errno() = MSVCRT_ENOENT; + return MSVCRT_ENOENT; } /********************************************************************* @@ -1787,8 +1784,9 @@ int CDECL MSVCRT__searchenv_s(const char* file, const char* env, char *buf, MSVC */ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* env, MSVCRT_wchar_t *buf) { - MSVCRT_wchar_t *envVal, *penv; - MSVCRT_wchar_t curPath[MAX_PATH]; + MSVCRT_wchar_t *envVal, *penv, *end; + MSVCRT_wchar_t path[MAX_PATH]; + MSVCRT_size_t path_len, fname_len = strlenW(file); *buf = '\0'; @@ -1796,8 +1794,6 @@ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* if (GetFileAttributesW( file ) != INVALID_FILE_ATTRIBUTES) { GetFullPathNameW( file, MAX_PATH, buf, NULL ); - /* Sigh. This error is *always* set, regardless of success */ - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); return; } @@ -1812,35 +1808,31 @@ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* penv = envVal; TRACE(":searching for %s in paths %s\n", debugstr_w(file), debugstr_w(envVal)); - do + for(; *penv; penv = (*end ? end + 1 : end)) { - MSVCRT_wchar_t *end = penv; - + end = penv; while(*end && *end != ';') end++; /* Find end of next path */ - if (penv == end || !*penv) + path_len = end - penv; + if (!path_len || path_len >= MAX_PATH) + continue; + + memcpy(path, penv, path_len * sizeof(MSVCRT_wchar_t)); + if (path[path_len - 1] != '/' && path[path_len - 1] != '\\') + path[path_len++] = '\\'; + if (path_len + fname_len >= MAX_PATH) + continue; + + memcpy(path + path_len, file, (fname_len + 1) * sizeof(MSVCRT_wchar_t)); + TRACE("Checking for file %s\n", debugstr_w(path)); + if (GetFileAttributesW( path ) != INVALID_FILE_ATTRIBUTES) { - msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + memcpy(buf, path, (path_len + fname_len + 1) * sizeof(MSVCRT_wchar_t)); 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'; + } - 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 */ - } - penv = *end ? end + 1 : end; - } while(1); + msvcrt_set_errno(ERROR_FILE_NOT_FOUND); + return; } /********************************************************************* @@ -1849,13 +1841,18 @@ void CDECL MSVCRT__wsearchenv(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* int CDECL MSVCRT__wsearchenv_s(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* env, MSVCRT_wchar_t *buf, MSVCRT_size_t count) { - MSVCRT_wchar_t* envVal, *penv; - MSVCRT_wchar_t curPath[MAX_PATH]; + MSVCRT_wchar_t *envVal, *penv, *end; + MSVCRT_wchar_t path[MAX_PATH]; + MSVCRT_size_t path_len, fname_len; if (!MSVCRT_CHECK_PMT(file != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(buf != NULL)) return MSVCRT_EINVAL; if (!MSVCRT_CHECK_PMT(count > 0)) return MSVCRT_EINVAL; + if (count > MAX_PATH) + FIXME("count > MAX_PATH not supported\n"); + + fname_len = strlenW(file); *buf = '\0'; /* Try CWD first */ @@ -1877,37 +1874,34 @@ int CDECL MSVCRT__wsearchenv_s(const MSVCRT_wchar_t* file, const MSVCRT_wchar_t* penv = envVal; TRACE(":searching for %s in paths %s\n", debugstr_w(file), debugstr_w(envVal)); - do + for(; *penv; penv = (*end ? end + 1 : end)) { - MSVCRT_wchar_t *end = penv; - + 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] != '\\') - { - curPath[end - penv] = '\\'; - curPath[end - penv + 1] = '\0'; - } - else - curPath[end - penv] = '\0'; + path_len = end - penv; + if (!path_len || path_len >= MAX_PATH) + continue; - strcatW(curPath, file); - TRACE("Checking for file %s\n", debugstr_w(curPath)); - if (GetFileAttributesW( curPath ) != INVALID_FILE_ATTRIBUTES) + memcpy(path, penv, path_len * sizeof(MSVCRT_wchar_t)); + if (path[path_len - 1] != '/' && path[path_len - 1] != '\\') + path[path_len++] = '\\'; + if (path_len + fname_len >= MAX_PATH) + continue; + + memcpy(path + path_len, file, (fname_len + 1) * sizeof(MSVCRT_wchar_t)); + TRACE("Checking for file %s\n", debugstr_w(path)); + if (GetFileAttributesW( path ) != INVALID_FILE_ATTRIBUTES) { - if (strlenW(curPath) + 1 > count) + if (path_len + fname_len + 1 > count) { - MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); - return MSVCRT_ERANGE; + MSVCRT_INVALID_PMT("buf[count] is too small", MSVCRT_ERANGE); + return MSVCRT_ERANGE; } - strcpyW(buf, curPath); + memcpy(buf, path, (path_len + fname_len + 1) * sizeof(MSVCRT_wchar_t)); return 0; } - penv = *end ? end + 1 : end; - } while(1); + } + + *MSVCRT__errno() = MSVCRT_ENOENT; + return MSVCRT_ENOENT; }