Skip to content

SPL: Fix for bug 66405 RecursiveDirectoryIterator w/ CURRENT_AS_PATHNAME - #665

Closed
paulyg wants to merge 1 commit into
php:PHP-5.4from
paulyg:issue-66405
Closed

paulyg wants to merge 1 commit into
php:PHP-5.4from
paulyg:issue-66405

Conversation

@paulyg

@paulyg paulyg commented May 7, 2014

Copy link
Copy Markdown
Contributor

Commit bc75208 introduced a change to make
RecursiveDirectoryIterator::getChildren() return the current directory name
when the FilesystemIterator::CURRENT_AS_PATHNAME flag is used. However, per the
RecursiveIterator interface getChildren() is supposed to return an Iterator
(or subclass of). So when you use RecursiveDirectoryIterator with
FilesystemIterator::CURRENT_AS_PATHNAME and wrap it in a
RecursiveIteratorIterator and try to foreach: RecursiveIteratorIterator throws
an UnexpectedValueException with message 'Objects returned by
RecursiveIterator::getChildren() must implement RecursiveIterator' becuase it
got a string when it should have gotten an Iterator object.

This commit removed the change introduced by commit bc75208 so that
RecursiveDirectoryIterator::getChildren() always returns a new instance of
itself.

This fix is against the PHP-5.4 branch
(as per https://wiki.php.net/vcs/gitworkflow applied to lowest stable branch).
I believe it should get ported up to 5.5, 5.6, and master. A test case
(bug66405.phpt) is includes. All tests in ext/spl/tests pass.

…HNAME

Commit bc75208 introduced a change to make
RecursiveDirectoryIterator::getChildren() return the current directory name
when the FilesystemIterator::CURRENT_AS_PATHNAME flag is used. However, per the
RecursiveIterator interface getChildren() is supposed to return an Iterator
(or subclass of). So when you use RecursiveDirectoryIterator with
FilesystemIterator::CURRENT_AS_PATHNAME and wrap it in a
RecursiveIteratorIterator and try to foreach: RecursiveIteratorIterator throws
an UnexpectedValueException with message 'Objects returned by
RecursiveIterator::getChildren() must implement RecursiveIterator' becuase it
got a string when it should have gotten an Iterator object.

This commit removed the change introduced by commit bc75208 so that
RecursiveDirectoryIterator::getChildren() always returns a new instance of
itself.

This fix is against the PHP-5.4 branch
(as per https://wiki.php.net/vcs/gitworkflow applied to lowest stable branch).
I believe it should get ported up to 5.5, 5.6, and master. A test case
(bug66405.phpt) is includes. All tests in ext/spl/tests pass.
@smalyshev

Copy link
Copy Markdown
Contributor

I'm not sure why it is necessary. If you tell FilesystemIterator to return pathname, it would return pathname, what's wrong with that?
Also, pulls should be always targeted against master, unless there are specific circumstances (like bug that is present only in specific version).

@paulyg

paulyg commented Jun 9, 2014

Copy link
Copy Markdown
Contributor Author

Yes FilesystemIterator and RecursiveDirectoryIterator should return the pathname if you ask for in in current(). This patch does not change that. What it does change is the return value of getChildren(), which MUST return another RecursiveIterator according to that interface. If you run code right now using the CURRENT_AS_PATHNAME option you will get an uncaught exception. Run the .phpt provided in this patch for proof.

@paulyg

paulyg commented Jun 9, 2014

Copy link
Copy Markdown
Contributor Author

I do apologize for not doing push against the correct branch. Instructions on wiki.PHP.net say to do PR against lowest branch. Maybe somebody should update that.

@smalyshev

Copy link
Copy Markdown
Contributor

@paulyg the instructions on the wiki are for developers (people doing actual commit/merge), not pull authors. I'll review this patch soon but I wonder since we've had it there since 5.3.0 and looks like the only point of bc75208 was to do this, maybe it makes sense to reach out to @colder (colder at php.net) and ask him what was the idea there.

@paulyg

paulyg commented Jun 9, 2014

Copy link
Copy Markdown
Contributor Author

@smalyshev OK. If you need me to rebase the PR on a different branch let me know.

@colder

colder commented Jun 10, 2014

Copy link
Copy Markdown
Contributor

I have to say I don't agree with my commit back then. It makes very little sense, getChildren should always return an iterator, but this iterator should be customized to return the pathname when calling current(). I will need a bit more time to take a careful look at this fix here.

@smalyshev

Copy link
Copy Markdown
Contributor

@colder ok, thanks, please update when you have reviewed it.

@colder

colder commented Jun 23, 2014

Copy link
Copy Markdown
Contributor

The patch looks good to me.

The only small worry I have is the, in essence, new $this($path, $flags) which means that each subclass of RecursiveDirectoryIterator needs to provide such a constructor and there is no easy way of extending this. Since this is not supposed to be a re-design of RecursiveIterator I think this is a reasonable constraint to keep, and it is much better than returning an instance of the base class.

@paulyg paulyg closed this Nov 22, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants