diff --git a/win32/ioutil.c b/win32/ioutil.c index 7eeddfbb70d..4f3e2d0bd67 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -538,6 +538,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]; @@ -545,6 +546,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; } @@ -554,6 +556,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); @@ -562,6 +566,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; diff --git a/win32/ioutil.h b/win32/ioutil.h index 120d69213dd..a22ca3eb143 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -177,17 +177,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;