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: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ku at digitaldolphins dot jp
New email:
PHP Version: OS:

 

 [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)

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 10:01:28 2024 UTC