Bug #78296 [PATCH]: is_file fails to detect file
| From: | cmb@php.net | Date: | Mon, 25 Nov 2019 11:29:00 +0000 |
| Subject: | Bug #78296 [PATCH]: is_file fails to detect file | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-223879@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78296&edit=1
ID: 78296
Patch added by: cmb@php.net
Reported by: v-altruo at microsoft dot com
Summary: is_file fails to detect file
Status: Analyzed
Type: Bug
Package: Scripting Engine problem
Operating System: Windows
PHP Version: 7.2Git-2019-07-16 (Git)
Assigned To: cmb
Block user comment: N
Private report: N
New Comment:
The following pull request has been associated:
Patch Name: Fix #78296: is_file fails to detect file
On GitHub: https://github.com/php/php-src/pull/4943
Patch: https://github.com/php/php-src/pull/4943.patch
Previous Comments:
------------------------------------------------------------------------
[2019-11-25 11:07:29] cmb@php.net
My assessment so far was not quite right. Actually, the problem
is that[1]:
| File I/O functions in the Windows API convert "/" to "\" as part
| of converting the name to an NT-style name, except when using the
| "\\?\" prefix as detailed in the following sections.
This is already correctly handled on systems supporting
PathCchCanonicalizeEx(), which have the registry setting
LongPathsEnabled disabled, but not for other systems.
Also, mkdir() is affected by this issue if the path is between 248
and 259 characters long.
[1] <https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file>
------------------------------------------------------------------------
[2019-07-16 13:05:05] cmb@php.net
The following pull request has been associated:
Patch Name: Fix #78296: is_file fails to detect file
On GitHub: https://github.com/php/php-src/pull/4421
Patch: https://github.com/php/php-src/pull/4421.patch
------------------------------------------------------------------------
[2019-07-16 12:26:08] cmb@php.net
> It seems that the file and directory management functions (such
> as CreateFileW()) don't accept long paths prefixed by \\?\.
Wrong conclusion. Actually we're not properly normalizing the
path, if the canonicalized path has the same length as before.
------------------------------------------------------------------------
[2019-07-16 10:52:48] cmb@php.net
Thanks for reporting! This is a rather interesting
issue.
At first I have not been able to reproduce the test
failure. Then I checked the registry key LongPathsEnabled[1]
and found that it was disabled. After enabling it, the test
failed for me as well. It seems that the file and directory
management functions (such as CreateFileW()) don't accept
long paths prefixed by \\?\. The following patch makes the test
pass for LongPathsEnabled set to true:
win32/ioutil.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/win32/ioutil.h b/win32/ioutil.h
index 34104a3f45..7937718766 100644
--- a/win32/ioutil.h
+++ b/win32/ioutil.h
@@ -190,7 +190,7 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz
}
/* Only prefix with long if it's needed. */
- if (mb_len >= _MAX_PATH) {
+ if (0) {
size_t new_mb_len;
ret = (wchar_t *) malloc((mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) *
sizeof(wchar_t));
[1] <https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#enable-long-paths-in-windows-10-version-1607-and-later>
------------------------------------------------------------------------
[2019-07-15 22:53:41] v-altruo at microsoft dot com
Description:
------------
Test fails across all builds regardless of opcache on/off. Looked a bit into it, the
"is_file($file)" is the part that fails.
Failed Test Location: ext\standard\tests\file\bug75679.phpt
Test script:
---------------
<?php
$d = __DIR__;
$Files2Report =
[
str_pad ($d . '/' . str_repeat (str_pad ('bug75679_path_259_characters_long_',
100, '_') . '/', 1), 259, '_') => [],
str_pad ($d . '/' . str_repeat (str_pad ('bug75679_path_260_characters_long_',
100, '_') . '/', 1), 260, '_') => [],
str_pad ($d . '/' . str_repeat (str_pad ('bug75679_path_261_characters_long_',
100, '_') . '/', 1), 261, '_') => [],
];
foreach ($Files2Report as $file => &$Report)
{
$Report = ['strlen' => strlen ($file), 'result' => 'nok'];
if (! is_dir (dirname ($file))) mkdir (dirname ($file), 0777, true);
if (copy (__FILE__, $file) && is_file ($file))
{
$Report['result'] = 'ok';
}
print_r ($Report);
}
?>
Expected result:
----------------
Array
(
[strlen] => 259
[result] => ok
)
Array
(
[strlen] => 260
[result] => ok
)
Array
(
[strlen] => 261
[result] => ok
)
==DONE==
Actual result:
--------------
Array
(
[strlen] => 259
[result] => ok
)
Array
(
[strlen] => 260
[result] => nok
)
Array
(
[strlen] => 261
[result] => nok
)
==DONE==
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78296&edit=1