php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51068 DirectoryIterator glob:// don't support current path relative queries
Submitted: 2010-02-17 14:39 UTC Modified: 2017-10-24 07:42 UTC
Votes:7
Avg. Score:3.6 ± 1.4
Reproduced:5 of 5 (100.0%)
Same Version:5 (100.0%)
Same OS:4 (80.0%)
From: pedro dot laguna at pentura dot com Assigned:
Status: Closed Package: SPL related
PHP Version: 7.1.9 OS: Linux
Private report: No CVE-ID: None
 [2010-02-17 14:39 UTC] pedro dot laguna at pentura dot com
Description:
------------
glob:// wrapper doesn't support current queries like glob://*

Reproduce code:
---------------
<?php
$it = new DirectoryIterator("glob://*");
foreach($it as $f) {
	printf("%s: %.1FK<br />", $f->getFilename(), $f->getSize()/1024);
}
?>

Expected result:
----------------
tree.php: 1.0K
findregex.php: 0.6K
findfile.php: 0.7K
dba_dump.php: 0.9K
nocvsdir.php: 1.1K
phar_from_dir.php: 1.0K
ini_groups.php: 0.9K
directorytree.php: 0.9K
dba_array.php: 1.1K
class_tree.php: 1.8K

Actual result:
--------------
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'SplFileInfo::getSize(): stat failed for /tree.php' in /home/pedro/public_html/glob.php:7
Stack trace:
#0 /home/pedro/public_html/glob.php(7): SplFileInfo->getSize()
#1 {main}
  thrown in /home/pedro/public_html/glob.php on line 7

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-02-17 15:57 UTC] jani@php.net
Use something that is actually supported:

   http://php.net/globiterator


 [2010-02-17 16:11 UTC] pedro dot laguna at pentura dot com
I know that I have many ways to do it, but I'm exposing that the current glob:// wrapper is not working properly.

If it supports relative paths should support the current path when you don't specify a full or relative path.
 [2010-02-17 16:15 UTC] aharvey@php.net
Hold up a sec, Jani. That's pretty much the example in the manual for the glob:// wrapper, just without a relative path, and it should work.

I suspect this is going to end up with Marcus, since he implemented glob:// in the first place, but in the meantime, OP, can you try the following script and confirm that it doesn't throw an exception (and prints the file names in the current directory)? Thanks.

<?php
$it = new DirectoryIterator("glob://*");
foreach($it as $f) {
	printf("%s<br />", $f->getFilename());
}
?>

 [2010-02-17 16:28 UTC] pedro dot laguna at pentura dot com
Without the size object reference it works as expected.
 [2010-02-17 16:47 UTC] pajoye@php.net
Which SAPI do you use? (or with which web server)
 [2010-02-17 16:57 UTC] pedro dot laguna at pentura dot com
pedro@pedro:~$ php --version
PHP 5.3.1-0.dotdeb.1 with Suhosin-Patch (cli) (built: Dec  5 2009 20:08:29) 
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies
pedro@pedro:~$ apache2 -v
Server version: Apache/2.2.12 (Ubuntu)
Server built:   Nov 12 2009 22:49:46
 [2010-02-17 16:58 UTC] colder@php.net
I'll look into it. 

Looks like glob://* makes DirectoryIterator generate paths like /file, 
which is wrong.
 [2010-02-17 17:10 UTC] aharvey@php.net
I kept looking into this after my initial post; I wasn't quite expecting this to be assigned quite so fast!

A quick and dirty patch against PHP_5_3 that appears to fix this is at http://www.adamharvey.name/patches/bug-51068-spl_directory.patch -- I can cook up a .phpt to go with it pretty rapidly if desired. This also doesn't look terribly difficult to port to trunk.
 [2010-02-17 18:29 UTC] aharvey@php.net
OK, strike my last patch, since it was only half of the solution.

This is really two bugs for the price of one. The first problem is that globs without a path (such as glob://*) always had a / prepended to their file name within spl_filesystem_object_get_file_name(), which caused the problem in this bug: that a relative foo.txt was resulting in a call to stat("/foo.txt"), which was obviously wrong.

The second problem is in the glob wrapper itself. php_glob_stream_path_split() had an off-by-one error that meant that glob patterns within the root directory resulted in an empty path string, just the same as a relative glob. This was being partially masked by the first problem, since the automatic prepending meant that globbing the root directory worked more or less by accident.

I've added a phpt file for the reported issue. I'm unsure of the best way to attack testing iterating over the root directory in a platform-independent manner; this may be worth someone with more familiarity writing a test for this case (ie creating a DirectoryIterator with glob:///* on platforms where it makes sense and seeing if the results look vaguely sensible).

So, the patches, (hopefully) ready for review and application:

Against PHP_5_3:
http://www.adamharvey.name/patches/bug-51068-5.3.patch

Against trunk:
http://www.adamharvey.name/patches/bug-51068-trunk.patch
 [2010-11-24 14:04 UTC] jani@php.net
-Package: Feature/Change Request +Package: SPL related
 [2017-10-24 07:25 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: colder +Assigned To:
 [2017-10-24 07:42 UTC] requinix@php.net
-Status: Open +Status: Analyzed -Type: Feature/Change Request +Type: Bug -PHP Version: 5.3.1 +PHP Version: 7.1.9
 [2019-01-28 02:43 UTC] mail at ahmed dot nu
Hi 

I was trying to find small thing I can contribute with, submitted MR as for fix for this, the same idea of aharvey patches, hopefully it is okay

https://github.com/php/php-src/pull/3767
 [2019-02-11 14:51 UTC] nikic@php.net
Automatic comment on behalf of email@ahmed.ro
Revision: http://git.php.net/?p=php-src.git;a=commit;h=ec28d4c247ef3c7ab9af41ff6e26b802694492b2
Log: Fix bug #51068 (glob:// do not support current path relative)
 [2019-02-11 14:51 UTC] nikic@php.net
-Status: Analyzed +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC