Skip to content

Commit bb735c9

Browse files
committed
Fix #78296: is_file fails to detect file
If we're constructing extended-length paths (i.e. paths prefixed with `\\?\`), we have to replace all forward slashes with backward slashes, because the former are not supported by Windows for extended-length paths. The more efficient and likely cleaner alternative solution would be to cater to this in `php_win32_ioutil_normalize_path_w()` by always replacing forward slashes, but that might break existing code. It might be sensible to change that for `master`, though.
1 parent 3d81c54 commit bb735c9

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PHP NEWS
77
property). (Nikita)
88
. Fixed bug #78868 (Calling __autoload() with incorrect EG(fake_scope) value).
99
(Antony Dovgal, Dmitry)
10+
. Fixed bug #78296 (is_file fails to detect file). (cmb)
1011

1112
- GD:
1213
. Fixed bug #78849 (GD build broken with -D SIGNED_COMPARE_SLOW). (cmb)

ext/standard/tests/file/bug78296.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Bug #78296 (is_file fails to detect file)
3+
--FILE--
4+
<?php
5+
$dir = str_pad(__DIR__ . '/bug78296', 250, '_');
6+
var_dump(mkdir($dir));
7+
var_dump(is_dir($dir));
8+
?>
9+
--EXPECT--
10+
bool(true)
11+
bool(true)
12+
--CLEAN--
13+
<?php
14+
$dir = str_pad(__DIR__ . '/bug78296', 250, '_');
15+
rmdir($dir);
16+
?>

win32/ioutil.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,13 +320,23 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode)
320320

321321
if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, path_len)) {
322322
wchar_t *_tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
323+
wchar_t *src, *dst;
323324
if (!_tmp) {
324325
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
325326
free(tmp);
326327
return -1;
327328
}
328329
memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
329-
memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, path_len * sizeof(wchar_t));
330+
src = tmp;
331+
dst = _tmp + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
332+
while (src < tmp + path_len) {
333+
if (*src == PHP_WIN32_IOUTIL_FW_SLASHW) {
334+
*dst++ = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
335+
src++;
336+
} else {
337+
*dst++ = *src++;
338+
}
339+
}
330340
path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
331341
_tmp[path_len] = L'\0';
332342
free(tmp);

win32/ioutil.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,16 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz
215215
memmove(ret, mb, mb_len * sizeof(wchar_t));
216216
ret[mb_len] = L'\0';
217217
} else {
218+
wchar_t *src = mb, *dst = ret + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
218219
memmove(ret, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t));
219-
memmove(ret+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, mb, mb_len * sizeof(wchar_t));
220+
while (src < mb + mb_len) {
221+
if (*src == PHP_WIN32_IOUTIL_FW_SLASHW) {
222+
*dst++ = PHP_WIN32_IOUTIL_DEFAULT_SLASHW;
223+
src++;
224+
} else {
225+
*dst++ = *src++;
226+
}
227+
}
220228
ret[mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW] = L'\0';
221229

222230
mb_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;

0 commit comments

Comments
 (0)