From f75da63b47dcf53b233316974a501d0fd29c5170 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 25 Nov 2019 12:09:09 +0100 Subject: [PATCH 1/2] 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. --- ext/standard/tests/file/bug78296.phpt | 16 ++++++++++++++++ win32/ioutil.c | 11 +++++++++++ win32/ioutil.h | 10 +++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 ext/standard/tests/file/bug78296.phpt diff --git a/ext/standard/tests/file/bug78296.phpt b/ext/standard/tests/file/bug78296.phpt new file mode 100644 index 0000000000000..e7388d51b7448 --- /dev/null +++ b/ext/standard/tests/file/bug78296.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #78296 (is_file fails to detect file) +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +--CLEAN-- + diff --git a/win32/ioutil.c b/win32/ioutil.c index c3c307a2a8e58..c163eb47bfd3b 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -320,6 +320,7 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode) if (!PHP_WIN32_IOUTIL_IS_LONG_PATHW(tmp, path_len)) { wchar_t *_tmp = (wchar_t *) malloc((path_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t)); + wchar_t *src, *dst; if (!_tmp) { SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY); free(tmp); @@ -327,6 +328,16 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode) } memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, path_len * sizeof(wchar_t)); + src = tmp; + dst = _tmp + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; + while (src < tmp + path_len) { + if (*src == PHP_WIN32_IOUTIL_FW_SLASHW) { + *dst++ = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; + src++; + } else { + *dst++ = *src++; + } + } path_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; _tmp[path_len] = L'\0'; free(tmp); diff --git a/win32/ioutil.h b/win32/ioutil.h index 0578584fe0311..82ed6b4e63176 100644 --- a/win32/ioutil.h +++ b/win32/ioutil.h @@ -215,8 +215,16 @@ __forceinline static wchar_t *php_win32_ioutil_conv_any_to_w(const char* in, siz memmove(ret, mb, mb_len * sizeof(wchar_t)); ret[mb_len] = L'\0'; } else { + wchar_t *src = mb, *dst = ret + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; memmove(ret, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); - memmove(ret+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, mb, mb_len * sizeof(wchar_t)); + while (src < mb + mb_len) { + if (*src == PHP_WIN32_IOUTIL_FW_SLASHW) { + *dst++ = PHP_WIN32_IOUTIL_DEFAULT_SLASHW; + src++; + } else { + *dst++ = *src++; + } + } ret[mb_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW] = L'\0'; mb_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; From 93c1c2855808c14713b94b71e7d8e2e238cecd37 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 25 Nov 2019 12:16:54 +0100 Subject: [PATCH 2/2] Remove superfluous memmove() --- win32/ioutil.c | 1 - 1 file changed, 1 deletion(-) diff --git a/win32/ioutil.c b/win32/ioutil.c index c163eb47bfd3b..6fbfdb52e420d 100644 --- a/win32/ioutil.c +++ b/win32/ioutil.c @@ -327,7 +327,6 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode) return -1; } memmove(_tmp, PHP_WIN32_IOUTIL_LONG_PATH_PREFIXW, PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW * sizeof(wchar_t)); - memmove(_tmp+PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW, tmp, path_len * sizeof(wchar_t)); src = tmp; dst = _tmp + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW; while (src < tmp + path_len) {