Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

paulyg
Copy link
Contributor

@paulyg paulyg commented May 7, 2014

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
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
Copy link
Contributor Author

paulyg commented Jun 9, 2014

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
Copy link
Contributor Author

paulyg commented Jun 9, 2014

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
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
Copy link
Contributor Author

paulyg commented Jun 9, 2014

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

@colder
Copy link
Contributor

colder commented Jun 10, 2014

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
Contributor

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

@colder
Copy link
Contributor

colder commented Jun 23, 2014

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