]> granicus.if.org Git - php/commitdiff
Fixed bug #76335 "link(): Bad file descriptor" with non-ASCII path
authorAnatol Belski <ab@php.net>
Mon, 14 May 2018 08:43:11 +0000 (10:43 +0200)
committerAnatol Belski <ab@php.net>
Mon, 14 May 2018 08:43:11 +0000 (10:43 +0200)
ext/standard/link_win32.c
ext/standard/tests/file/windows_links/bug76335.phpt [new file with mode: 0644]

index 35ea1cd1efc63d925c13f72e0c4e592c31111ffe..898928b2af9e0408fc41790122280d4c0d68516a 100644 (file)
@@ -196,6 +196,7 @@ PHP_FUNCTION(link)
        int ret;
        char source_p[MAXPATHLEN];
        char dest_p[MAXPATHLEN];
+       wchar_t *dstw, *srcw;
 
        /*First argument to link function is the target and hence should go to frompath
          Second argument to link function is the link itself and hence should go to topath */
@@ -224,16 +225,38 @@ PHP_FUNCTION(link)
        }
 
 #ifndef ZTS
-       ret = CreateHardLinkA(topath, frompath, NULL);
+# define _TO_PATH topath
+# define _FROM_PATH frompath
 #else
-       ret = CreateHardLinkA(dest_p, source_p, NULL);
+# define _TO_PATH dest_p
+# define _FROM_PATH source_p
 #endif
+       dstw = php_win32_ioutil_any_to_w(_TO_PATH);
+       if (!dstw) {
+               php_error_docref(NULL, E_WARNING, "UTF-16 conversion failed (error %d)", GetLastError());
+               RETURN_FALSE;
+       }
+       srcw = php_win32_ioutil_any_to_w(_FROM_PATH);
+       if (!srcw) {
+               free(dstw);
+               php_error_docref(NULL, E_WARNING, "UTF-16 conversion failed (error %d)", GetLastError());
+               RETURN_FALSE;
+       }
+#undef _TO_PATH
+#undef _FROM_PATH
+
+       ret = CreateHardLinkW(dstw, srcw, NULL);
 
        if (ret == 0) {
+               free(dstw);
+               free(srcw);
                php_error_docref(NULL, E_WARNING, "%s", strerror(errno));
                RETURN_FALSE;
        }
 
+       free(dstw);
+       free(srcw);
+
        RETURN_TRUE;
 }
 /* }}} */
diff --git a/ext/standard/tests/file/windows_links/bug76335.phpt b/ext/standard/tests/file/windows_links/bug76335.phpt
new file mode 100644 (file)
index 0000000..866057f
--- /dev/null
@@ -0,0 +1,52 @@
+--TEST--
+Bug #76335 "link(): Bad file descriptor" with non-ASCII path
+--SKIPIF--
+<?php
+if(substr(PHP_OS, 0, 3) != 'WIN' ) {
+    die('skip windows only test');
+}
+?>
+--FILE--
+<?php
+
+$d0 = dirname(__FILE__) . DIRECTORY_SEPARATOR . "á";
+$d1 = dirname(__FILE__) . DIRECTORY_SEPARATOR . "a";
+
+$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . "file";
+
+$l0 = $d0 . DIRECTORY_SEPARATOR . "b";
+$l1 = $d1 . DIRECTORY_SEPARATOR . "b";
+
+mkdir($d0);
+mkdir($d1);
+
+file_put_contents($fn, "");
+
+chdir($d0);
+var_dump(link($d0 . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "file", $l0));
+
+chdir($d1);
+var_dump(link($d1 . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "file", $l1));
+
+?>
+--CLEAN--
+<?php
+
+$d0 = dirname(__FILE__) . DIRECTORY_SEPARATOR . "á";
+$d1 = dirname(__FILE__) . DIRECTORY_SEPARATOR . "a";
+
+$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . "file";
+
+$l0 = $d0 . DIRECTORY_SEPARATOR . "b";
+$l1 = $d1 . DIRECTORY_SEPARATOR . "b";
+
+unlink($l0);
+unlink($l1);
+unlink($fn);
+rmdir($d0);
+rmdir($d1);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+