Merge branch 'PHP-7.2'

* PHP-7.2:
  Fix mkdir() special case for path length < 260 and > 248
This commit is contained in:
Anatol Belski 2017-09-28 13:20:09 +02:00
commit eca3bc59b2
2 changed files with 88 additions and 1 deletions

View File

@ -0,0 +1,60 @@
--TEST--
Mkdir with path length < 260 and > 248 has be a long path
--SKIPIF--
<?php
include dirname(__FILE__) . DIRECTORY_SEPARATOR . "util.inc";
skip_if_not_win();
$start = realpath(dirname(__FILE__));
if (strlen($start) > 260 || strlen($start) > 248) {
die("skip the starting path length is unsuitable for this test");
}
?>
--FILE--
<?php
$p = "";
$s = str_repeat('a', 50);
$how_many = 32;
for ($i = 0; $i < $how_many; $i++) {
$p .= "$s\\";
}
$start = realpath(dirname(__FILE__));
if (strlen($start) <= 248) {
// create the exact length
$start = $start . "\\" . str_repeat('a', 251 - strlen($start) - 1);
}
var_dump($start);
$p = $start . "\\" . $p;
var_dump($p);
var_dump(mkdir($p, 0777, true));
var_dump(file_exists($p));
$p7 = $p . "hello.txt";
var_dump(file_put_contents($p7, "hello"));
var_dump(file_get_contents($p7));
// cleanup
unlink($p7);
for ($i = 0; $i < $how_many; $i++) {
$p0 = substr($p, 0, strlen($p) - $i*51);
rmdir($p0);
}
?>
===DONE===
--EXPECTF--
string(251) "%s"
string(1884) "%s"
bool(true)
bool(true)
int(5)
string(5) "hello"
===DONE===

View File

@ -306,10 +306,37 @@ PW32IO int php_win32_ioutil_mkdir_w(const wchar_t *path, mode_t mode)
PW32IO int php_win32_ioutil_mkdir(const char *path, mode_t mode)
{/*{{{*/
wchar_t *pathw = php_win32_ioutil_any_to_w(path);
size_t pathw_len = 0;
wchar_t *pathw = php_win32_ioutil_conv_any_to_w(path, 0, &pathw_len);
int ret = 0;
DWORD err = 0;
if (pathw_len < _MAX_PATH && pathw_len > _MAX_PATH - 12) {
/* Special case here. From the doc:
"When using an API to create a directory, the specified path cannot be
so long that you cannot append an 8.3 file name ..."
Thus, if the directory name length happens to be in this range, it
already needs to be a long path. The given path is already normalized
and prepared, need only to prefix it.
*/
wchar_t *tmp = (wchar_t *) malloc((pathw_len + PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW + 1) * sizeof(wchar_t));
if (!tmp) {
free(pathw);
SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
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, pathw, pathw_len * sizeof(wchar_t));
pathw_len += PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW;
tmp[pathw_len] = L'\0';
free(pathw);
pathw = tmp;
}
/* TODO extend with mode usage */
if (!pathw) {
SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER);