Skip to content

Commit beb9295

Browse files
committed
Merge branch 'PHP-7.2'
* PHP-7.2: Fixed bug #75063
2 parents 9221bd7 + 0a2a136 commit beb9295

File tree

6 files changed

+195
-2
lines changed

6 files changed

+195
-2
lines changed

Zend/zend.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
717717
extern zend_php_scanner_globals language_scanner_globals;
718718
#endif
719719

720+
#ifdef ZEND_WIN32
721+
php_win32_cp_set_by_id(65001);
722+
#endif
723+
720724
start_memory_manager();
721725

722726
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */

Zend/zend_virtual_cwd.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,16 +389,21 @@ static void cwd_globals_dtor(virtual_cwd_globals *cwd_g) /* {{{ */
389389
}
390390
/* }}} */
391391

392-
CWD_API void virtual_cwd_startup(void) /* {{{ */
392+
void virtual_cwd_main_cwd_init(uint8_t reinit) /* {{{ */
393393
{
394394
char cwd[MAXPATHLEN];
395395
char *result;
396396

397+
if (reinit) {
398+
free(main_cwd_state.cwd);
399+
}
397400

398401
#ifdef ZEND_WIN32
399402
ZeroMemory(&cwd, sizeof(cwd));
400-
#endif
403+
result = php_win32_ioutil_getcwd(cwd, sizeof(cwd));
404+
#else
401405
result = getcwd(cwd, sizeof(cwd));
406+
#endif
402407

403408
if (!result) {
404409
cwd[0] = '\0';
@@ -411,7 +416,12 @@ CWD_API void virtual_cwd_startup(void) /* {{{ */
411416
}
412417
#endif
413418
main_cwd_state.cwd = strdup(cwd);
419+
}
420+
/* }}} */
414421

422+
CWD_API void virtual_cwd_startup(void) /* {{{ */
423+
{
424+
virtual_cwd_main_cwd_init(0);
415425
#ifdef ZTS
416426
ts_allocate_id(&cwd_globals_id, sizeof(virtual_cwd_globals), (ts_allocate_ctor) cwd_globals_ctor, (ts_allocate_dtor) cwd_globals_dtor);
417427
#else

Zend/zend_virtual_cwd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ CWD_API zend_long realpath_cache_size(void);
238238
CWD_API zend_long realpath_cache_max_buckets(void);
239239
CWD_API realpath_cache_bucket** realpath_cache_get_buckets(void);
240240

241+
#ifdef CWD_EXPORTS
242+
extern void virtual_cwd_main_cwd_init(uint8_t);
243+
#endif
244+
241245
/* The actual macros to be used in programs using TSRM
242246
* If the program defines VIRTUAL_DIR it will use the
243247
* virtual_* functions
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
--TEST--
2+
Bug #75063 Many filesystem-related functions do not work with multibyte file names, cp1251
3+
--SKIPIF--
4+
<?php
5+
include dirname(__FILE__) . DIRECTORY_SEPARATOR . "util.inc";
6+
7+
skip_if_not_win();
8+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
9+
skip_if_no_required_exts();
10+
11+
?>
12+
--INI--
13+
default_charset=cp1251
14+
--FILE--
15+
<?php
16+
17+
/* This file is in cp1251. */
18+
19+
include dirname(__FILE__) . DIRECTORY_SEPARATOR . "util.inc";
20+
21+
$dir_basename = "ňĺńň";
22+
$prefix = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug75063-cp1251";
23+
$d0 = $prefix . DIRECTORY_SEPARATOR . $dir_basename;
24+
25+
mkdir($prefix);
26+
create_verify_dir($prefix, $dir_basename, 1251);
27+
28+
var_dump(get_basename_with_cp($d0, 1251, false));
29+
30+
$old_cwd = getcwd();
31+
var_dump(chdir($d0));
32+
33+
$code = <<<CODE
34+
<?php
35+
36+
foreach(["test", "ňŕńň"] as \$fn) {
37+
file_put_contents("\$fn.txt", "");
38+
}
39+
40+
var_dump(getcwd());
41+
if (\$dh = opendir(getcwd())) {
42+
while ((\$file = readdir(\$dh)) !== false) {
43+
if ("." == \$file || ".." == \$file) continue;
44+
var_dump(\$file);
45+
}
46+
closedir(\$dh);
47+
}
48+
CODE;
49+
$code_fn = "code.php";
50+
file_put_contents($code_fn, $code);
51+
52+
print(shell_exec(getenv('TEST_PHP_EXECUTABLE') . " -n -d default_charset=cp1251 -f code.php"));
53+
54+
chdir($old_cwd);
55+
56+
/* --CLEAN-- section were the right place, but it won't accept default_charset ATM, it seems. */
57+
$dir_basename = "ňĺńň";
58+
$prefix = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug75063-cp1251";
59+
$d0 = $prefix . DIRECTORY_SEPARATOR . $dir_basename;
60+
61+
$obj = scandir($d0);
62+
foreach ($obj as $file) {
63+
if ("." == $file || ".." == $file) continue;
64+
unlink($d0 . DIRECTORY_SEPARATOR . $file);
65+
}
66+
67+
rmdir($d0);
68+
rmdir($prefix);
69+
?>
70+
===DONE===
71+
72+
--EXPECTF--
73+
string(4) "ňĺńň"
74+
bool(true)
75+
string(%d) "%sbug75063-cp1251%eňĺńň"
76+
string(8) "code.php"
77+
string(8) "test.txt"
78+
string(8) "ňŕńň.txt"
79+
===DONE===
80+
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
--TEST--
2+
Bug #75063 Many filesystem-related functions do not work with multibyte file names, UTF-8
3+
--SKIPIF--
4+
<?php
5+
include dirname(__FILE__) . DIRECTORY_SEPARATOR . "util.inc";
6+
7+
skip_if_not_win();
8+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
9+
skip_if_no_required_exts();
10+
11+
?>
12+
--FILE--
13+
<?php
14+
15+
/* This file is in UTF-8. */
16+
17+
include dirname(__FILE__) . DIRECTORY_SEPARATOR . "util.inc";
18+
19+
$dir_basename = "тест";
20+
$prefix = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug75063-utf8";
21+
$d0 = $prefix . DIRECTORY_SEPARATOR . $dir_basename;
22+
23+
mkdir($prefix);
24+
create_verify_dir($prefix, $dir_basename);
25+
26+
var_dump(get_basename_with_cp($d0, 65001, false));
27+
28+
$old_cwd = getcwd();
29+
var_dump(chdir($d0));
30+
31+
$code = <<<CODE
32+
<?php
33+
34+
foreach(["test", "таст"] as \$fn) {
35+
file_put_contents("\$fn.txt", "");
36+
}
37+
38+
var_dump(getcwd());
39+
if (\$dh = opendir(getcwd())) {
40+
while ((\$file = readdir(\$dh)) !== false) {
41+
if ("." == \$file || ".." == \$file) continue;
42+
var_dump(\$file);
43+
}
44+
closedir(\$dh);
45+
}
46+
CODE;
47+
$code_fn = "code.php";
48+
file_put_contents($code_fn, $code);
49+
50+
print(shell_exec(getenv('TEST_PHP_EXECUTABLE') . " -nf code.php"));
51+
52+
chdir($old_cwd);
53+
54+
?>
55+
===DONE===
56+
--CLEAN--
57+
<?php
58+
$dir_basename = "тест";
59+
$prefix = dirname(__FILE__) . DIRECTORY_SEPARATOR . "bug75063-utf8";
60+
$d0 = $prefix . DIRECTORY_SEPARATOR . $dir_basename;
61+
62+
$obj = scandir($d0);
63+
foreach ($obj as $file) {
64+
if ("." == $file || ".." == $file) continue;
65+
unlink($d0 . DIRECTORY_SEPARATOR . $file);
66+
}
67+
68+
rmdir($d0);
69+
rmdir($prefix);
70+
71+
?>
72+
73+
--EXPECTF--
74+
string(8) "тест"
75+
bool(true)
76+
string(%d) "%sbug75063-utf8%eтест"
77+
string(8) "code.php"
78+
string(8) "test.txt"
79+
string(12) "таст.txt"
80+
===DONE===
81+

main/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,6 +2231,20 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
22312231
/* Register Zend ini entries */
22322232
zend_register_standard_ini_entries();
22332233

2234+
#ifdef ZEND_WIN32
2235+
/* Until the current ini values was setup, the current cp is 65001.
2236+
If the actual ini vaues are different, some stuff needs to be updated.
2237+
It concerns at least main_cwd_state and there might be more. As we're
2238+
still in the startup phase, lets use the chance and reinit the relevant
2239+
item according to the current codepage. Still, if ini_set() is used
2240+
later on, a more intelligent way to update such stuff is needed.
2241+
Startup/shutdown routines could involve touching globals and thus
2242+
can't always be used on demand. */
2243+
if (!php_win32_cp_use_unicode()) {
2244+
virtual_cwd_main_cwd_init(1);
2245+
}
2246+
#endif
2247+
22342248
/* Disable realpath cache if an open_basedir is set */
22352249
if (PG(open_basedir) && *PG(open_basedir)) {
22362250
CWDG(realpath_cache_size_limit) = 0;

0 commit comments

Comments
 (0)