From 0879233ed4ab9e2b1ff647707271b50cd48d2f45 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 18 Oct 2022 15:53:39 +0200 Subject: [PATCH 1/2] Fix GH-9674: RecursiveDirectoryIterator regression wrt. junctions If we `lstat()` a junction on Windows, it is not `S_ISLNK()`, but we still must not assume that it is not a link (in the broadest sense). In lack of a proper way to detect that, we use the fact that `.st_mode` is zero in this case. --- ext/spl/spl_directory.c | 2 +- ext/spl/tests/gh9674.phpt | 40 +++++++++++++++++++++++++++++++++++++++ ext/standard/filestat.c | 2 +- 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 ext/spl/tests/gh9674.phpt diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 4edc6361605fb..508fa35430d80 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1480,7 +1480,7 @@ PHP_METHOD(RecursiveDirectoryIterator, hasChildren) php_stat(intern->file_name, FS_LPERMS, return_value); if (Z_TYPE_P(return_value) == IS_FALSE) { return; - } else if (!S_ISLNK(Z_LVAL_P(return_value))) { + } else if (!S_ISLNK(Z_LVAL_P(return_value)) && Z_LVAL_P(return_value) != 0) { RETURN_BOOL(S_ISDIR(Z_LVAL_P(return_value))); } else { if (!allow_links diff --git a/ext/spl/tests/gh9674.phpt b/ext/spl/tests/gh9674.phpt new file mode 100644 index 0000000000000..52f52c072496f --- /dev/null +++ b/ext/spl/tests/gh9674.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug GH-9674 (RecursiveDirectoryIterator regression wrt. junctions) +--SKIPIF-- + +--FILE-- +getFilename()); +} +?> +--CLEAN-- + +--EXPECT-- +string(1) "." +string(2) ".." +string(5) "a.txt" +string(5) "b.txt" +string(1) "." +string(2) ".." +string(5) "c.txt" diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 83fc6837c630c..e28b3a7b9b84d 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -844,7 +844,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) memcpy(&BG(lssb), &ssb, sizeof(php_stream_statbuf)); } if (!(flags & PHP_STREAM_URL_STAT_LINK) - || !S_ISLNK(ssb.sb.st_mode)) { + || !S_ISLNK(ssb.sb.st_mode) && ssb.sb.st_mode != 0) { if (BG(CurrentStatFile)) { zend_string_release(BG(CurrentStatFile)); } From f3d74cdd16b1e9a50250aaf1e5a705457e174699 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 18 Oct 2022 16:10:14 +0200 Subject: [PATCH 2/2] Fix -Werror=parentheses issue --- ext/standard/filestat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index e28b3a7b9b84d..e3961f8a66bd7 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -844,7 +844,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value) memcpy(&BG(lssb), &ssb, sizeof(php_stream_statbuf)); } if (!(flags & PHP_STREAM_URL_STAT_LINK) - || !S_ISLNK(ssb.sb.st_mode) && ssb.sb.st_mode != 0) { + || (!S_ISLNK(ssb.sb.st_mode) && ssb.sb.st_mode != 0)) { if (BG(CurrentStatFile)) { zend_string_release(BG(CurrentStatFile)); }