]> granicus.if.org Git - php/commitdiff
Fixed bug #80724
authorCameron Porter <camporter1@gmail.com>
Mon, 15 Feb 2021 04:55:25 +0000 (22:55 -0600)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 23 Feb 2021 08:50:36 +0000 (09:50 +0100)
FilesystemIterator::FOLLOW_SYMLINKS is currently treated as a directory
key mode flag, even though it does not change the way that the key
during iteration is set. To address this, FOLLOW_SYMLINKS has been
converted into an OTHER flag.

Closes GH-6695.

NEWS
ext/spl/spl_directory.h
ext/spl/tests/RecursiveDirectoryIterator_hasChildren.phpt [new file with mode: 0644]
ext/spl/tests/bug80724.phpt [new file with mode: 0644]
ext/spl/tests/filesystemiterator_flags.phpt

diff --git a/NEWS b/NEWS
index 02e3c77cf92891c6eacf2689807de20662975b25..3caf269956def3c2c994bf8e44076618b000ebd3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -44,4 +44,8 @@ PHP                                                                        NEWS
   . Convert resource<pspell> to object \PSpell. (Sara)
   . Convert resource<pspell config> to object \PSpellConfig. (Sara)
 
+- SPL:
+  . Fixed bug #80724 (FilesystemIterator::FOLLOW_SYMLINKS remove KEY_AS_FILE
+    from bitmask). (Cameron Porter)
+
 <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
index 88fbd0f05260191b95a068f8853f5ce5b4c4a7ad..e3deb81aebff3a4f7f6a764c2f84ed33572b01fd 100644 (file)
@@ -136,12 +136,12 @@ static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_files
 
 #define SPL_FILE_DIR_KEY_AS_PATHNAME       0x00000000 /* make RecursiveDirectoryTree::key() return getPathname() */
 #define SPL_FILE_DIR_KEY_AS_FILENAME       0x00000100 /* make RecursiveDirectoryTree::key() return getFilename() */
-#define SPL_FILE_DIR_FOLLOW_SYMLINKS       0x00000200 /* make RecursiveDirectoryTree::hasChildren() follow symlinks */
 #define SPL_FILE_DIR_KEY_MODE_MASK         0x00000F00 /* mask RecursiveDirectoryTree::key() */
 #define SPL_FILE_DIR_KEY(intern,mode)      ((intern->flags&SPL_FILE_DIR_KEY_MODE_MASK)==mode)
 
 #define SPL_FILE_DIR_SKIPDOTS              0x00001000 /* Tells whether it should skip dots or not */
 #define SPL_FILE_DIR_UNIXPATHS             0x00002000 /* Whether to unixify path separators */
-#define SPL_FILE_DIR_OTHERS_MASK           0x00003000 /* mask used for get/setFlags */
+#define SPL_FILE_DIR_FOLLOW_SYMLINKS       0x00004000 /* make RecursiveDirectoryTree::hasChildren() follow symlinks */
+#define SPL_FILE_DIR_OTHERS_MASK           0x00007000 /* mask used for get/setFlags */
 
 #endif /* SPL_DIRECTORY_H */
diff --git a/ext/spl/tests/RecursiveDirectoryIterator_hasChildren.phpt b/ext/spl/tests/RecursiveDirectoryIterator_hasChildren.phpt
new file mode 100644 (file)
index 0000000..a4bad9b
--- /dev/null
@@ -0,0 +1,35 @@
+--TEST--
+SPL: RecursiveDirectoryIterator::hasChildren() follow symlinks test
+--FILE--
+<?php
+
+$dir = __DIR__ . DIRECTORY_SEPARATOR . 'symlinktest';
+
+if (!mkdir($dir)) {
+    die('Failed to create temporary directory for testing');
+} elseif (!symlink(__DIR__, $dir . DIRECTORY_SEPARATOR . 'symlink')) {
+    die('Failed to create symbolic link');
+}
+
+$it = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::KEY_AS_FILENAME);
+
+var_dump($it->key());
+var_dump($it->hasChildren());
+
+$it->setFlags(FilesystemIterator::SKIP_DOTS | FilesystemIterator::KEY_AS_FILENAME);
+
+var_dump($it->key());
+var_dump($it->hasChildren());
+
+?>
+--EXPECT--
+string(7) "symlink"
+bool(true)
+string(7) "symlink"
+bool(false)
+--CLEAN--
+<?php
+$dir = __DIR__ . DIRECTORY_SEPARATOR . 'symlinktest';
+unlink($dir . DIRECTORY_SEPARATOR . 'symlink');
+rmdir($dir);
+?>
diff --git a/ext/spl/tests/bug80724.phpt b/ext/spl/tests/bug80724.phpt
new file mode 100644 (file)
index 0000000..7ff118e
--- /dev/null
@@ -0,0 +1,46 @@
+--TEST--
+Bug #80724 (FOLLOW_SYMLINKS interfering with FilesystemIterator key flags)
+--FILE--
+<?php
+$iterator = new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME);
+foreach ($iterator as $key => $value) {
+    echo var_dump(hasSeparator($key));
+    break;
+}
+$iterator->rewind();
+echo var_dump(hasSeparator($iterator->key()));
+
+$iterator->setFlags(0);
+echo var_dump(hasSeparator($iterator->key()));
+
+$iterator->setFlags(FilesystemIterator::KEY_AS_FILENAME);
+echo var_dump(hasSeparator($iterator->key()));
+
+$iterator2 = new FilesystemIterator(__DIR__, FilesystemIterator::FOLLOW_SYMLINKS | FilesystemIterator::KEY_AS_FILENAME);
+foreach ($iterator2 as $key => $value) {
+    echo var_dump(hasSeparator($key));
+    break;
+}
+$iterator2->rewind();
+echo var_dump(hasSeparator($iterator2->key()));
+
+$iterator2->setFlags(0);
+echo var_dump(hasSeparator($iterator2->key()));
+
+$iterator2->setFlags(FilesystemIterator::KEY_AS_FILENAME);
+echo var_dump(hasSeparator($iterator2->key()));
+
+function hasSeparator($key) {
+    return str_contains($key, __DIR__ . DIRECTORY_SEPARATOR);
+}
+
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
index 1a8cce034e33c5e23b5c86ec60bcc5e2896ea25f..b4e582b77ae12971def8140b31210fdfeba45524 100644 (file)
@@ -34,7 +34,7 @@ function printflags($it) {
 00000010
 00000100
 00003000
-00003FF0
+00007FF0
 000000F0
 00000F00
-00003000
+00007000