Skip to content

Commit 088e547

Browse files
committed
Fix FileSystemIterator without SKIP_DOTS
There were two separate bugs here: * The get_iterator implementation did not match the Iterator implementation. In particular, get_iterator did not respect SKIP_DOTS. * The constructor did not honor an explicitly omitted SKIP_DOTS flag. It could still be unset through setFlags() though.
1 parent fbbbb48 commit 088e547

File tree

2 files changed

+40
-11
lines changed

2 files changed

+40
-11
lines changed

ext/spl/spl_directory.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -706,22 +706,16 @@ void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_long cto
706706
spl_filesystem_object *intern;
707707
zend_string *path;
708708
int parsed;
709-
zend_long flags;
709+
zend_long flags = (ctor_flags & ~DIT_CTOR_FLAGS);
710710
zend_error_handling error_handling;
711711

712712
if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_FLAGS)) {
713-
flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO;
713+
flags |= SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO;
714714
parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "P|l", &path, &flags);
715715
} else {
716-
flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
716+
flags |= SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
717717
parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "P", &path);
718718
}
719-
if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) {
720-
flags |= SPL_FILE_DIR_SKIPDOTS;
721-
}
722-
if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_UNIXPATHS)) {
723-
flags |= SPL_FILE_DIR_UNIXPATHS;
724-
}
725719
if (parsed == FAILURE) {
726720
RETURN_THROWS();
727721
}
@@ -1763,11 +1757,12 @@ static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter)
17631757
{
17641758
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
17651759
spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator);
1760+
bool skip_dots = SPL_HAS_FLAG(object->flags, SPL_FILE_DIR_SKIPDOTS);
17661761

17671762
object->u.dir.index++;
17681763
do {
17691764
spl_filesystem_dir_read(object);
1770-
} while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1765+
} while (skip_dots && spl_filesystem_is_dot(object->u.dir.entry.d_name));
17711766
if (object->file_name) {
17721767
zend_string_release(object->file_name);
17731768
object->file_name = NULL;
@@ -1784,14 +1779,15 @@ static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter)
17841779
{
17851780
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
17861781
spl_filesystem_object *object = spl_filesystem_iterator_to_object(iterator);
1782+
bool skip_dots = SPL_HAS_FLAG(object->flags, SPL_FILE_DIR_SKIPDOTS);
17871783

17881784
object->u.dir.index = 0;
17891785
if (object->u.dir.dirp) {
17901786
php_stream_rewinddir(object->u.dir.dirp);
17911787
}
17921788
do {
17931789
spl_filesystem_dir_read(object);
1794-
} while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1790+
} while (skip_dots && spl_filesystem_is_dot(object->u.dir.entry.d_name));
17951791
if (!Z_ISUNDEF(iterator->current)) {
17961792
zval_ptr_dtor(&iterator->current);
17971793
ZVAL_UNDEF(&iterator->current);
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
FileSystemIterator without SKIP_DOTS
3+
--FILE--
4+
<?php
5+
6+
$dir = __DIR__ . '/filesystemiterator_no_skip_dots';
7+
mkdir($dir);
8+
touch($dir . '/file');
9+
10+
$it = new FileSystemIterator($dir, 0);
11+
$files = [];
12+
foreach ($it as $f) {
13+
$files[] = $f->getFileName();
14+
}
15+
sort($files);
16+
var_dump($files);
17+
18+
?>
19+
--CLEAN--
20+
<?php
21+
$dir = __DIR__ . '/filesystemiterator_no_skip_dots';
22+
unlink($dir . '/file');
23+
rmdir($dir);
24+
?>
25+
--EXPECT--
26+
array(3) {
27+
[0]=>
28+
string(1) "."
29+
[1]=>
30+
string(2) ".."
31+
[2]=>
32+
string(4) "file"
33+
}

0 commit comments

Comments
 (0)