php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61315 stat() fails with specific DBCS characters
Submitted: 2012-03-07 09:23 UTC Modified: 2012-03-08 07:46 UTC
From: ku at digitaldolphins dot jp Assigned:
Status: Duplicate Package: Filesystem function related
PHP Version: 5.4SVN-2012-03-07 (SVN) OS: Windows Server 2008 R2 Foundatio
Private report: No CVE-ID:
 [2012-03-07 09:23 UTC] ku at digitaldolphins dot jp
Description:
------------
[not a #61309 report. this is another bug fix.]
[this is FYI patch. if you want to fix the problem on latest php5.4.]

stat() fails on all of following conditions:
- using DBCS enabled Windows env.
- a DBCS character contains backslash (\x5C) at second byte.

for example: /tmp/ソフト

(ソフト means "soft" in katakana, reading so-fu-to)

character -> to CP932(Shift_JIS) byte array -> to ascii

ソ -> 83 5C -> .\
フ -> 83 74 -> .t
ト -> 83 67 -> .g

I'll attach a patch for fixing this problem.

About my fix method:
- define IS_SLASH_PI(pointer, index). replace IS_SLASH(path[i-1]) with IS_SLASH_PI(path, i-1).
- use IS_SLASH_PI instead of IS_SLASH_P and IS_SLASH.
- IS_SLASH can catch backslash in second byte of DBCS character. it is problem.
- IS_SLASH_P of Win32 impl is dangerous because it decreases the pointer. check this: #define IS_SLASH_PI(c,i) ... IsDBCSLeadByte((c)[i-1])

IS_SLASH_PI defines as follows:

#define IS_SLASH_PI(c,i)	((c)[i] == '/' || \
        ((c)[i] == '\\' && ((i) == 0 || !IsDBCSLeadByte((c)[i-1]))))


Test script:
---------------
<?php

mkdir("/tmp"); // ok
mkdir("/tmp/ソフト"); // ok
touch("/tmp/ソフト/test.txt"); // ok, with warning.
echo count(stat("/tmp/ソフト/test.txt")); // FAIL

?>

Expected result:
----------------
C:\php-sdk\php54dev\vc9\x86\php5.4-201203070030>Release_TS\php.exe \php5\test3.php
PHP Warning:  mkdir(): File exists in C:\php5\test3.php on line 3
26


run once, it creates "/tmp/ソフト/test.txt".
run one more, it won't create any more file/folder.


Actual result:
--------------
C:\php5>php.exe test3.php
PHP Warning:  mkdir(): File exists in C:\php5\test3.php on line 3
PHP Warning:  touch(): Utime failed: No such file or directory in C:\php5\test3.php on line 5
PHP Warning:  stat(): stat failed for /tmp/ソフト/test.txt in C:\php5\test3.php on line 6
1


run once, it creates "/tmp/ソフト/test.txt".
run one more, it creates "/tmp/ソソフト/test.txt".


Patches

php54_dbcs_win_is_slash_2 (last revision 2012-03-08 07:38 UTC) by ku at digitaldolphins dot jp)
php54_dbcs_win_is_slash_1 (last revision 2012-03-07 09:24 UTC) by ku at digitaldolphins dot jp)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-07 09:24 UTC] pajoye@php.net
-Status: Open +Status: Duplicate
 [2012-03-07 09:24 UTC] pajoye@php.net
Same as before, a feature request is being worked on.

please do not report one bug for every single file function about the same 
problem.
 [2012-03-08 07:46 UTC] ku at digitaldolphins dot jp
Thanks for your advice. I'll keep in mind.

I posted a new patch is_slash_2.

IMO, IS_SLASH needs sequential scan from the beginning of string.
it will cost a little bit more time.

Test script:
--------------

<?php

print_r(scandir("C:\\A\\test\\≒\\")); // (81 E0 5C) fail -> ok
print_r(scandir("C:\\A\\test\\÷\\")); // (81 80 5C) ok
print_r(scandir("\\\\DD5\\test\\≒\\")); // (81 E0 5C) fail -> ok
print_r(scandir("\\\\DD5\\test\\÷\\")); // (81 80 5C) ok

?>
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Tue Aug 29 15:01:52 2017 UTC