]> granicus.if.org Git - php/commitdiff
Fix normalized path length calculation and error handling
authorAnatol Belski <ab@php.net>
Mon, 27 Nov 2017 11:32:19 +0000 (12:32 +0100)
committerAnatol Belski <ab@php.net>
Mon, 27 Nov 2017 11:32:19 +0000 (12:32 +0100)
win32/ioutil.c
win32/ioutil.h

index 0beea2bfefd6412fc757a206e16ccaef8b891ef9..958bef8f9fbbfbacb6e7e62fd610c6d9d3733d5c 100644 (file)
@@ -539,6 +539,7 @@ PW32IO size_t php_win32_ioutil_dirname(char *path, size_t len)
        return ret_len;
 }/*}}}*/
 
+/* Partial normalization can still be acceptable, explicit fail has to be caught. */
 PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
 {/*{{{*/
        wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN];
@@ -546,6 +547,7 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w
 
        if (len >= MAXPATHLEN) {
                SET_ERRNO_FROM_WIN32_CODE(ERROR_BAD_LENGTH);
+               *new_len = 0;
                return PHP_WIN32_IOUTIL_NORM_FAIL;
        }
 
@@ -555,6 +557,8 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w
        }
 
        if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) {
+               /* Length unchanged. */
+               *new_len = len;
                return PHP_WIN32_IOUTIL_NORM_PARTIAL;
        }
        ret_len = wcslen(canonicalw);
@@ -563,6 +567,8 @@ PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(w
                        wchar_t *tmp = realloc(*buf, (ret_len + 1) * sizeof(wchar_t));
                        if (!tmp) {
                                SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
+                               /* Length unchanged. */
+                               *new_len = len;
                                return PHP_WIN32_IOUTIL_NORM_PARTIAL;
                        }
                        *buf = tmp;
index 9aac1c435a9b4788d00f1218825e0182cf546f50..394932d78edefdecdff63a010121f029b6417f67 100644 (file)
@@ -175,17 +175,17 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz
                        return NULL;
                }
 
-               /* The return can be ignored here, as the normalization can fail for
-                  various reasons not directly related to the operation itself.
-                  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, &new_mb_len);
+               if (PHP_WIN32_IOUTIL_NORM_FAIL == php_win32_ioutil_normalize_path_w(&mb, mb_len, &new_mb_len)) {
+                               free(ret);
+                               free(mb);
+                               return NULL;
+               }
 
                if (new_mb_len > mb_len) {
                        wchar_t *tmp = (wchar_t *) realloc(ret, (new_mb_len + 1) * sizeof(wchar_t));
                        if (!tmp) {
                                free(ret);
+                               free(mb);
                                return NULL;
                        }
                        ret = tmp;