facebook / facebook/hhvm

DirectoryIterator iterates forever* over stream URL**

Open
#3,690 1 comment 0 reactions 0 assignees View on GitHub
performance php5 incompatibility
Dominant language
C++
Stars
18.7k
Forks
3.1k
Avg merge
1h 47m
Merged PRs (30d)
2

Description

_\* probably not forever_
_*\* the test uses [vfs.php](https://github.com/adlawson/vfs.php) to simulate a file system in memory with stream wrappers_

It seems that `DirectoryIterator` parses stream paths incorrectly.

Iterating over a "directory" implemented over stream wrapper results in a never ending result.
It correctly picks up a single `.` dot directory and a `..` dot directory, but then incorrectly finds a `streamname:` directory and returns a new result for that forever.

``` php
getFileName());
}

// Results...
string(1) "."
string(2) ".."
string(9) "hhvmtest:"
string(9) "hhvmtest:"
string(9) "hhvmtest:"
string(9) "hhvmtest:"
string(9) "hhvmtest:"
string(9) "hhvmtest:"
...
```

I've also checked how it behaves when iterating over a non-root path (not just a schema) and a similar thing happens.

``` php
getFileName());
}

// Results...
string(1) "."
string(2) ".."
string(3) "foo"
string(3) "foo"
string(3) "foo"
string(3) "foo"
string(3) "foo"
string(3) "foo"
...
```

As you can see below, it returns a new object for each erroneous result

``` php

resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(0)
["fileName":"SplFileInfo":private]=>
string(11) "hhvmtest:/."
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
object(DirectoryIterator)#20 (6) {
["dir":"DirectoryIterator":private]=>
resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(1)
["fileName":"SplFileInfo":private]=>
string(12) "hhvmtest:/.."
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
object(DirectoryIterator)#21 (6) {
["dir":"DirectoryIterator":private]=>
resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(2)
["fileName":"SplFileInfo":private]=>
string(9) "hhvmtest:"
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
object(DirectoryIterator)#22 (6) {
["dir":"DirectoryIterator":private]=>
resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(3)
["fileName":"SplFileInfo":private]=>
string(9) "hhvmtest:"
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
object(DirectoryIterator)#23 (6) {
["dir":"DirectoryIterator":private]=>
resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(3)
["fileName":"SplFileInfo":private]=>
string(9) "hhvmtest:"
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
object(DirectoryIterator)#24 (6) {
["dir":"DirectoryIterator":private]=>
resource(28) of type (Directory)
["dirName":"DirectoryIterator":private]=>
string(9) "hhvmtest:"
["index":"DirectoryIterator":private]=>
int(3)
["fileName":"SplFileInfo":private]=>
string(9) "hhvmtest:"
["fileClass":"SplFileInfo":private]=>
string(13) "SplFileObject"
["infoClass":"SplFileInfo":private]=>
NULL
}
...
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.