]> granicus.if.org Git - php/commitdiff
Fixed bug #73962 bug with symlink related to cyrillic directory
authorAnatol Belski <ab@php.net>
Fri, 20 Jan 2017 22:45:08 +0000 (23:45 +0100)
committerAnatol Belski <ab@php.net>
Fri, 20 Jan 2017 22:45:08 +0000 (23:45 +0100)
NEWS
Zend/zend_virtual_cwd.c
ext/standard/tests/file/windows_links/bug73962.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 65856c647d6c68e5989e5c6f8789daddfe262d32..baed4466b79dc8a48e14e6aa00280e5c331412e9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP                                                                        NEWS
   . Fixed bug #73877 (readlink() returns garbage for UTF-8 paths). (Anatol)
   . Fixed bug #73876 (Crash when exporting **= in expansion of assign op).
     (Sara)
+  . Fixed bug #73962 (bug with symlink related to cyrillic directory). (Anatol)
 
 - DTrace:
   . Fixed bug #73965 (DTrace reported as enabled when disabled). (Remi)
index 53343482db5e16c7a5b21c4595dd4ea1bee35c21..9c2dc2929903a81a933fe1447eeb3149bd3a948e 100644 (file)
@@ -914,7 +914,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
                        wchar_t * reparsetarget;
                        BOOL isVolume = FALSE;
                        char *printname = NULL, *substitutename = NULL;
-                       int substitutename_len;
+                       size_t substitutename_len;
                        int substitutename_off = 0;
 
                        if(++(*ll) > LINK_MAX) {
@@ -959,7 +959,8 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
                                }
 
                                substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
-                               substitutename = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
+                               substitutename = php_win32_cp_conv_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
+                                                                               substitutename_len, &substitutename_len);
                                if (!substitutename) {
                                        free_alloca(pbuffer, use_heap_large);
                                        free_alloca(tmp, use_heap);
@@ -981,7 +982,8 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i
 
 
                                substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
-                               substitutename = php_win32_ioutil_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR));
+                               substitutename = php_win32_cp_conv_w_to_any(reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR),
+                                                                               substitutename_len, &substitutename_len);
                                if (!substitutename) {
                                        free_alloca(pbuffer, use_heap_large);
                                        free_alloca(tmp, use_heap);
diff --git a/ext/standard/tests/file/windows_links/bug73962.phpt b/ext/standard/tests/file/windows_links/bug73962.phpt
new file mode 100644 (file)
index 0000000..6d57838
--- /dev/null
@@ -0,0 +1,77 @@
+--TEST--\r
+Bug #73962 bug with symlink related to cyrillic directory\r
+--SKIPIF--\r
+<?php\r
+if(substr(PHP_OS, 0, 3) != 'WIN' ) {\r
+    die('skip windows only test');\r
+}\r
+include_once __DIR__ . '/common.inc';\r
+$ret = exec('mklink bug48746_tmp.lnk ' . __FILE__ .' 2>&1', $out);\r
+if (strpos($ret, 'privilege')) {\r
+       die('skip. SeCreateSymbolicLinkPrivilege not enable for this user.');\r
+}\r
+unlink('bug48746_tmp.lnk');\r
+?>\r
+--FILE--\r
+<?php\r
+include_once __DIR__ . '/common.inc';\r
+$mountvol = get_mountvol();\r
+$old_dir = __DIR__;\r
+$dirname = '"' . __DIR__ . "\\mnt\\test\\новая папка" . '"';\r
+exec("mkdir " . $dirname, $output, $ret_val);\r
+chdir(__DIR__ . "\\mnt\\test");\r
+$drive = substr(__DIR__, 0, 2);\r
+$pathwithoutdrive = substr(__DIR__, 2);\r
+$ret = exec($mountvol . " " . $drive . " /L", $output, $ret_val);\r
+exec("mklink /d mounted_volume " . $ret, $output, $ret_val);\r
+$fullpath = "mounted_volume" . $pathwithoutdrive;\r
+exec("mklink /d mklink_symlink \"новая папка\"", $output, $ret_val);\r
+file_put_contents("mklink_symlink\\a.php", "<?php echo \"I am included.\n\" ?>");\r
+file_put_contents("$fullpath\\mnt\\test\\новая папка\\b.php", "<?php echo \"I am included.\n\" ?>");\r
+var_dump(scandir("mklink_symlink"));\r
+var_dump(scandir("$fullpath\\mnt\\test\\новая папка"));\r
+var_dump(scandir("$fullpath\\mnt\\test\\mklink_symlink"));\r
+var_dump(is_readable("$fullpath\\mnt\\test\\mklink_symlink\b.php"));\r
+unlink("$fullpath\\mnt\\test\\новая папка\\b.php");\r
+unlink("mklink_symlink\\a.php");\r
+chdir($old_dir);\r
+rmdir(__DIR__ . "\\mnt\\test\\новая папка");\r
+rmdir(__DIR__ . "\\mnt\\test\\mklink_symlink");\r
+rmdir(__DIR__ . "\\mnt\\test\\mounted_volume");\r
+rmdir(__DIR__ . "\\mnt\\test");\r
+rmdir(__DIR__ . "\\mnt");\r
+\r
+?>\r
+--EXPECT--\r
+array(4) {\r
+  [0]=>\r
+  string(1) "."\r
+  [1]=>\r
+  string(2) ".."\r
+  [2]=>\r
+  string(5) "a.php"\r
+  [3]=>\r
+  string(5) "b.php"\r
+}\r
+array(4) {\r
+  [0]=>\r
+  string(1) "."\r
+  [1]=>\r
+  string(2) ".."\r
+  [2]=>\r
+  string(5) "a.php"\r
+  [3]=>\r
+  string(5) "b.php"\r
+}\r
+array(4) {\r
+  [0]=>\r
+  string(1) "."\r
+  [1]=>\r
+  string(2) ".."\r
+  [2]=>\r
+  string(5) "a.php"\r
+  [3]=>\r
+  string(5) "b.php"\r
+}\r
+bool(true)\r
+\r