]> granicus.if.org Git - php/commitdiff
Fix #78296: is_file fails to detect file
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 25 Nov 2019 11:16:54 +0000 (12:16 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Mon, 2 Dec 2019 10:29:10 +0000 (11:29 +0100)
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.

NEWS
ext/standard/tests/file/bug78296.phpt [new file with mode: 0644]
win32/ioutil.c
win32/ioutil.h

diff --git a/NEWS b/NEWS
index 1786ba2b1527e7ab7a91fe78b0ac607d4029f2c1..186968758537b5dea8a3767a7f75f986ceb24f73 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP                                                                        NEWS
     property). (Nikita)
   . Fixed bug #78868 (Calling __autoload() with incorrect EG(fake_scope) value).
     (Antony Dovgal, Dmitry)
+  . Fixed bug #78296 (is_file fails to detect file). (cmb)
 
 - GD:
   . Fixed bug #78849 (GD build broken with -D SIGNED_COMPARE_SLOW). (cmb)
diff --git a/ext/standard/tests/file/bug78296.phpt b/ext/standard/tests/file/bug78296.phpt
new file mode 100644 (file)
index 0000000..e7388d5
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #78296 (is_file fails to detect file)
+--FILE--
+<?php
+$dir = str_pad(__DIR__ . '/bug78296', 250, '_');
+var_dump(mkdir($dir));
+var_dump(is_dir($dir));
+?>
+--EXPECT--
+bool(true)
+bool(true)
+--CLEAN--
+<?php
+$dir = str_pad(__DIR__ . '/bug78296', 250, '_');
+rmdir($dir);
+?>
index c3c307a2a8e58d418be569d539e1a9d835171620..6fbfdb52e420da784626acf131ee592fae6e474f 100644 (file)
@@ -320,13 +320,23 @@ 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);
                                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) {
+                               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);
index 0578584fe0311ef1f09ac62f12fde33ab829711e..82ed6b4e63176af878f3330c3b1286a5838fc15b 100644 (file)
@@ -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;