diff options
Diffstat (limited to 'ext/standard')
-rw-r--r-- | ext/standard/link_win32.c | 27 | ||||
-rw-r--r-- | ext/standard/tests/file/windows_links/bug76335.phpt | 52 |
2 files changed, 77 insertions, 2 deletions
diff --git a/ext/standard/link_win32.c b/ext/standard/link_win32.c index 35ea1cd1ef..898928b2af 100644 --- a/ext/standard/link_win32.c +++ b/ext/standard/link_win32.c @@ -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 index 0000000000..866057fe02 --- /dev/null +++ b/ext/standard/tests/file/windows_links/bug76335.phpt @@ -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) + |