From 2d50237627c2ebfd5300b931e489460587f0ba15 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 15 Jul 2020 18:37:27 +0200 Subject: [PATCH 1/2] Fix #79806: realpath() erroneously resolves link to link After resolving reparse points, the path still may be a reparse point; in that case we have to resolve that reparse point as well. --- Zend/zend_virtual_cwd.c | 14 ++++++++++++-- ext/standard/tests/file/realpath_basic4.phpt | 6 ------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 253ed8c420262..3b90074683b28 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -845,6 +845,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim } #ifdef ZEND_WIN32 +retry_reparse_point: if (save) { pathw = php_win32_ioutil_any_to_w(path); if (!pathw) { @@ -867,7 +868,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim tmp = do_alloca(len+1, use_heap); memcpy(tmp, path, len+1); -retry: +retry_reparse_tag_cloud: if(save && !(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') && (dataw.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) @@ -928,7 +929,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim dataw.dwFileAttributes = fileInformation.dwFileAttributes; CloseHandle(hLink); (*ll)--; - goto retry; + goto retry_reparse_tag_cloud; } free_alloca(tmp, use_heap); CloseHandle(hLink); @@ -1075,6 +1076,15 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim free_alloca(pbuffer, use_heap_large); free(substitutename); + { + DWORD attrs = GetFileAttributesA(path); + if (!isVolume && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { + free_alloca(tmp, use_heap); + FREE_PATHW() + goto retry_reparse_point; + } + } + if(isabsolute == 1) { if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { /* use_realpath is 0 in the call below coz path is absolute*/ diff --git a/ext/standard/tests/file/realpath_basic4.phpt b/ext/standard/tests/file/realpath_basic4.phpt index d782b6d618fa9..5f18dd9841656 100644 --- a/ext/standard/tests/file/realpath_basic4.phpt +++ b/ext/standard/tests/file/realpath_basic4.phpt @@ -1,11 +1,5 @@ --TEST-- Test realpath() with relative paths ---SKIPIF-- - --FILE-- Date: Tue, 28 Jul 2020 11:22:57 +0200 Subject: [PATCH 2/2] Properly support Unicode paths We also make sure that we don't retry on GetFileAttributes() failures. --- Zend/zend_virtual_cwd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 3b90074683b28..7c5ac825c55c8 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -1077,8 +1077,15 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim free(substitutename); { - DWORD attrs = GetFileAttributesA(path); - if (!isVolume && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { + DWORD attrs; + + FREE_PATHW() + pathw = php_win32_ioutil_any_to_w(path); + if (!pathw) { + return (size_t)-1; + } + attrs = GetFileAttributesW(pathw); + if (!isVolume && attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) { free_alloca(tmp, use_heap); FREE_PATHW() goto retry_reparse_point;