Bug #74472 [Fbk->Opn]: readdir strips leading and trailing quotes in a filename
| From: | james at workinout dot com | Date: | Wed, 19 Apr 2017 06:18:25 +0000 |
| Subject: | Bug #74472 [Fbk->Opn]: readdir strips leading and trailing quotes in a filename | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-208655@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74472&edit=1
ID: 74472
User updated by: james at workinout dot com
Reported by: james at workinout dot com
Summary: readdir strips leading and trailing quotes in a
filename
-Status: Feedback
+Status: Open
Type: Bug
Package: Filesystem function related
Operating System: osx 10.12
PHP Version: 7.1.4
Block user comment: N
Private report: N
New Comment:
actually, running it all on fedora 25, sorry about that typo
strange. downloaded from drupal.org as far as i remember.
its weird, I know. cant ever recall seeing a filename with
quotes in it. i know about backslashes. used those with
fortran in 1975.
Entry before: {{ THEME SANITIZED }}.behaviors.js (quotes trimmed by readdir() )
Entry after: \'{{ THEME SANITIZED }}.behaviors.js\' (after using addslashes() )
perhaps echo() and var_dump() use different methods. var_dump using getc/putc ? echo not ?
Previous Comments:
------------------------------------------------------------------------
[2017-04-19 05:37:55] requinix@php.net
Well that's not how the files are bundled. Where did you download it from?
As for the backslashes, those are supposed to be there. That's how escaping works.
https://www.shellscript.sh/escape.html
Besides, I couldn't reproduce what you're describing anyways. And though this is Linux, I
can't imagine it being any different on OSX.
# ls -la
total 4
drwxrwxrwx 2 root root 0 Apr 18 22:33 .
drwxrwxrwx 2 root root 0 Apr 18 22:32 ..
-rw-rw-rw- 1 root root 0 Apr 18 22:32 'foo'
-rw-rw-rw- 1 root root 85 Apr 18 22:33 test.php
# cat test.php
<?php
$h = opendir(".");
while ($f = readdir($h)) {
var_dump($f);
}
closedir($h);
# ~/php/PHP-7.1.4/bin/php test.php
string(1) "."
string(2) ".."
string(5) "'foo'"
string(8) "test.php"
------------------------------------------------------------------------
[2017-04-19 05:28:14] james at workinout dot com
the quotes I AM seeing are when I do ls -al in a bash shell. see below
the filename ON the filesystem has leading and trailing quotes, as I said.
i tried escapeshellarg() but it simply puts in backslashes in front
of the quotes, which of course, creates a filename that does not exist.
drwxr-xr-x 2 james apache 4096 Apr 10 19:21 .
drwxr-xr-x 10 james apache 4096 Apr 10 19:21 ..
-rw-r--r-- 1 james apache 2900 Apr 10 19:21 '{{ THEME SANITIZED }}.behaviors.js'
obviously, the quotes are there...
------------------------------------------------------------------------
[2017-04-19 05:13:38] requinix@php.net
The files don't have quotes.
http://cgit.drupalcode.org/omega/tree/omega/starterkits/default/js?h=7.x-4.x
The filename must be escaped in the shell command, like with escapeshellarg. Not doing so will cause
problems for files that contain spaces or other potentially unsafe characters (such as
'{'). For example,
exec("stat --format=%G " . escapeshellarg($entry));
The fact that the escaped version has quotes is simply because that's the easiest way to make a
string safe.
The quotes you're seeing mentioned somewhere are probably indicative of either PHP code (quotes
form a string) or an actual shell command (author escaped the filename).
------------------------------------------------------------------------
[2017-04-19 04:36:34] james at workinout dot com
Description:
------------
in drupal, some files named with leading and trailing quotes
filename === '{{ THEME SANITIZED }}.behaviors.js'
$entry = readdir() --- > $entry === -> {{ THEME SANITIZED }}.behaviors.js (NO QUOTES)
stat will not work because the stripped quotes are needed: stat
complains like below:
stat --format=%G (command used..)
stat: cannot stat '{{': No such file or directory
stat: cannot stat 'THEME': No such file or directory
stat: cannot stat 'SANITIZED': No such file or directory
stat: cannot stat '}}.behaviors.js': No such file or directory
stat: cannot stat '{{': No such file or directory
stat: cannot stat 'THEME': No such file or directory
stat: cannot stat 'SANITIZED': No such file or directory
stat: cannot stat '}}.behaviors.js': No such file or directory
Test script:
---------------
Solution is to put the quotes back in filename.
$entry = "'" . $entry . "'".
stat works ok then...
if ($handle = opendir($name)) {
while (false !== ($entry = readdir($handle))) {
if (preg_match('/\.$|\..$/', $entry)) {
continue;
}
//special case for filenames with single quotes (they are stripped by readdir() )
// used in omega themes with {{ in the filename..
if(preg_match('/\{/', $entry)) {
$entry = "'" . $entry . "'";
}
<after this, stat will work....
Expected result:
----------------
providing an optional argument in readdir() to not strip leading,trailing quotes would be useful
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74472&edit=1