From: Anatol Belski Date: Fri, 14 Jul 2017 11:23:24 +0000 (+0200) Subject: Fixed bug #74923 Crash when crawling through network share X-Git-Tag: php-7.1.8RC1~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d15fdc4a4db22552105e8275b6d3ef417219d66;p=php Fixed bug #74923 Crash when crawling through network share --- diff --git a/win32/ioutil.h b/win32/ioutil.h index f0c1f53c76..9aac1c435a 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -112,6 +112,10 @@ typedef enum { #define PHP_WIN32_IOUTIL_IS_LONG_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW \ && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW)) +#define PHP_WIN32_IOUTIL_IS_UNC_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW \ + && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_UNC_PATH_PREFIXW, PHP_WIN32_IOUTIL_UNC_PATH_PREFIX_LENW)) +#define PHP_WIN32_IOUTIL_IS_JUNCTION_PATHW(pathw, path_lenw) (path_lenw >= PHP_WIN32_IOUTIL_JUNCTION_PREFIX_LENW \ + && 0 == wcsncmp((pathw), PHP_WIN32_IOUTIL_JUNCTION_PREFIXW, PHP_WIN32_IOUTIL_JUNCTION_PREFIX_LENW)) #define PHP_WIN32_IOUTIL_IS_ABSOLUTEW(pathw, path_lenw) (PHP_WIN32_IOUTIL_IS_LONG_PATHW(pathw, path_lenw) \ || path_lenw >= 3 && PHP_WIN32_IOUTIL_IS_LETTERW(pathw[0]) && L':' == pathw[1] && IS_SLASHW(pathw[2])) @@ -163,6 +167,8 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz /* Only prefix with long if it's needed. */ if (mb_len > _MAX_PATH) { + size_t new_mb_len; + ret = (wchar_t *) malloc((mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); if (!ret) { free(mb); @@ -174,9 +180,19 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz Partial normalization could still do a better job further. And otherwise, the path might be unchanged which is ok if the path was valid long one. */ - (void)php_win32_ioutil_normalize_path_w(&mb, mb_len, &mb_len); + (void)php_win32_ioutil_normalize_path_w(&mb, mb_len, &new_mb_len); + + if (new_mb_len > mb_len) { + wchar_t *tmp = (wchar_t *) realloc(ret, (new_mb_len + 1) * sizeof(wchar_t)); + if (!tmp) { + free(ret); + return NULL; + } + ret = tmp; + mb_len = new_mb_len; + } - if (PHP_WIN32_IOUTIL_IS_LONG_PATHW(mb, mb_len)) { + if (PHP_WIN32_IOUTIL_IS_LONG_PATHW(mb, mb_len) || PHP_WIN32_IOUTIL_IS_JUNCTION_PATHW(mb, mb_len) || PHP_WIN32_IOUTIL_IS_UNC_PATHW(mb, mb_len)) { memmove(ret, mb, mb_len * sizeof(wchar_t)); ret[mb_len] = L'\0'; } else {