Edit report at https://bugs.php.net/bug.php?id=61315&edit=1
ID: 61315
User updated by: ku at digitaldolphins dot jp
Reported by: ku at digitaldolphins dot jp
Summary: stat() fails with specific DBCS characters
Status: Duplicate
Type: Bug
Package: Filesystem function related
Operating System: Windows Server 2008 R2 Foundatio
PHP Version: 5.4SVN-2012-03-07 (SVN)
Block user comment: N
Private report: N
New Comment:
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
?>
Previous Comments:
------------------------------------------------------------------------
[2012-03-07 09:24:44] [email protected]
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-07 09:23:25] 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".
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=61315&edit=1