Skip to content

Commit d5b59b4

Browse files
committed
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.
1 parent 6f18d7e commit d5b59b4

File tree

3 files changed

+13
-8
lines changed

3 files changed

+13
-8
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PHP NEWS
55
- Core:
66
. Fixed bug #79884 (PHP_CONFIG_FILE_PATH is meaningless). (cmb)
77
. Fixed bug #77932 (File extensions are case-sensitive). (cmb)
8+
. Fixed bug #79806 (realpath() erroneously resolves link to link). (cmb)
89

910
?? ??? ????, PHP 7.3.21
1011

Zend/zend_virtual_cwd.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
845845
}
846846

847847
#ifdef ZEND_WIN32
848+
retry_reparse_point:
848849
if (save) {
849850
pathw = php_win32_ioutil_any_to_w(path);
850851
if (!pathw) {
@@ -867,7 +868,7 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
867868
tmp = do_alloca(len+1, use_heap);
868869
memcpy(tmp, path, len+1);
869870

870-
retry:
871+
retry_reparse_tag_cloud:
871872
if(save &&
872873
!(IS_UNC_PATH(path, len) && len >= 3 && path[2] != '?') &&
873874
(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
928929
dataw.dwFileAttributes = fileInformation.dwFileAttributes;
929930
CloseHandle(hLink);
930931
(*ll)--;
931-
goto retry;
932+
goto retry_reparse_tag_cloud;
932933
}
933934
free_alloca(tmp, use_heap);
934935
CloseHandle(hLink);
@@ -1075,6 +1076,15 @@ static size_t tsrm_realpath_r(char *path, size_t start, size_t len, int *ll, tim
10751076
free_alloca(pbuffer, use_heap_large);
10761077
free(substitutename);
10771078

1079+
{
1080+
DWORD attrs = GetFileAttributesA(path);
1081+
if (!isVolume && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) {
1082+
free_alloca(tmp, use_heap);
1083+
FREE_PATHW()
1084+
goto retry_reparse_point;
1085+
}
1086+
}
1087+
10781088
if(isabsolute == 1) {
10791089
if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) {
10801090
/* use_realpath is 0 in the call below coz path is absolute*/

ext/standard/tests/file/realpath_basic4.phpt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
--TEST--
22
Test realpath() with relative paths
3-
--SKIPIF--
4-
<?php
5-
if (substr(PHP_OS, 0, 3) == 'WIN') {
6-
die('skip no symlinks on Windows');
7-
}
8-
?>
93
--FILE--
104
<?php
115
$file_path = dirname(__FILE__);

0 commit comments

Comments
 (0)