|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2009-02-11 08:12 UTC] php at guggemand dot dk
Description:
------------
glob() cant be used directly in foreach when open_basedir is set.
i found #41655 which is about the change causing this, and a few other closed tickets with "not a bug" as answer.
But that change destroys foreach(glob("nonexistent*") as ... when using open_basedir, and the following comment in dir.c states that should be usable.
/* Some glob implementation simply return no data if no matches
were found, others return the GLOB_NOMATCH error code.
We don't want to treat GLOB_NOMATCH as an error condition
so that PHP glob() behaves the same on both types of
implementations and so that 'foreach (glob() as ...'
can be used for simple glob() calls without further error
checking.
*/
As far as i can tell the right thing to do would be to return an empty array both when using glob("/etc/hosts") and glob("/etc/nonexistent") when open_basedir is used. Or what am i missing?
Ive been using the following patch, and as far as i can tell its not possible to check if a file exists when open_basedir is used, and foreach(glob("nonext*")) works correctly.
http://gugge.dlx.dk/ting/php5-patch-dir.c
Reproduce code:
---------------
set open_basedir /documentroot
open /documentroot/test.php with the following content
<? var_dump(glob("nonexistent*")); ?>
Expected result:
----------------
array(0) {
}
Actual result:
--------------
bool(false)
Patchesopen_basedir_error_fix (last revision 2011-10-09 17:08 UTC by pajoye@php.net)Pull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Oct 29 02:00:01 2025 UTC |
"an empty array if no file matched" is what i see in the manual. but this returns error, and not an empty array() glob("/path/allowd/in/open_basedir/nonexitentfile.*"); I can understand why a system glob call returning no files, and a call returning only nonallowed files has to be treated the same. But im to dumb to see the logic in treating both as errors instead of "no files matched", especially because that breaks existing code. And treating it as "no files matched" doesnt break anything. Please enlighten me if im wrong, and ill put on my pointy hat and sit in the corner for the rest of the day. But now i have link i can give the users telling me my servers doesn't work right. So i guess i can live with that.Hi Pierre! Please merge your patch asap to php. It works as expected and will fix the following inconsistency: $ php -dopen_basedir=/ -r 'var_dump(glob("/does/not/exist"));' bool(false) $ php -r 'var_dump(glob("/does/not/exist"));' array(0) { } Something to consider is updating the docs to mention returning false if open_basedir restriction is in effect.There are some cases with the platform difference windows x64\Debug_TS\php -n -d open_basedir=C:\php-sdk\phpmaster\vc11\x64\php-src -r "var_dump(glob('C:\php-sdk\phpmaster\vc11\x64\php-src\*.none'));" bool(false) x64\Debug_TS\php -n -r "var_dump(glob('C:\php-sdk\phpmaster\vc11\x64\php-src\*.none'));" array(0) { } linux sapi/cli/php -n -d open_basedir=/home/anatol/dws/src/php-master-ts -r 'var_dump(glob("/home/anatol/dws/src/php-master-ts/*.none"));' array(0) { } sapi/cli/php -n -r 'var_dump(glob("/home/anatol/dws/src/php-master-ts/*.none"));' array(0) { } The cause of this platform difference is that here http://lxr.php.net/xref/PHP_TRUNK/ext/standard/dir.c#495 php_check_open_basedir_ex() subsequently calls virtual_file_ex() http://lxr.php.net/xref/PHP_TRUNK/TSRM/tsrm_virtual_cwd.c#1241 and if the pattern contains '*' or '?', php_check_open_basedir_ex() will return -1 on windows. I've discovered while testing this PR https://github.com/php/php-src/pull/398 which had the same issue.Here's a testcase i wrote to ensure it does right across platforms --TEST-- Test glob() function: ensure no platform difference --FILE-- <?php $path = dirname(__FILE__); ini_set('open_basedir', NULL); var_dump(glob("$path/*.none")); ini_set('open_basedir', $path); var_dump(glob("$path/*.none")); ?> ==DONE== --EXPECT-- array(0) { } array(0) { } ==DONE==