Skip to content

Commit c756f82

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 efe6d96 commit c756f82

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-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
- LDAP:
1011
. Fixed memory leaks. (ptomulik)

Zend/zend_virtual_cwd.c

Lines changed: 19 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,22 @@ 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;
1081+
1082+
FREE_PATHW()
1083+
pathw = php_win32_ioutil_any_to_w(path);
1084+
if (!pathw) {
1085+
return (size_t)-1;
1086+
}
1087+
attrs = GetFileAttributesW(pathw);
1088+
if (!isVolume && attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_REPARSE_POINT)) {
1089+
free_alloca(tmp, use_heap);
1090+
FREE_PATHW()
1091+
goto retry_reparse_point;
1092+
}
1093+
}
1094+
10781095
if(isabsolute == 1) {
10791096
if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) {
10801097
/* 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)