]> granicus.if.org Git - php/commitdiff
Fixed bug #74923 Crash when crawling through network share
authorAnatol Belski <ab@php.net>
Fri, 14 Jul 2017 11:23:24 +0000 (13:23 +0200)
committerAnatol Belski <ab@php.net>
Fri, 14 Jul 2017 11:23:24 +0000 (13:23 +0200)
win32/ioutil.h

index f0c1f53c76a88b39c7615250164428a3fe0383a0..9aac1c435a9b4788d00f1218825e0182cf546f50 100644 (file)
@@ -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 {