Merge branch 'PHP-7.2'

* PHP-7.2:
  Fixed bug #75574 putenv does not work properly if parameter contains non-ASCII unicode character
This commit is contained in:
Anatol Belski 2017-11-27 18:52:45 +01:00
commit edc77d5d00
3 changed files with 153 additions and 9 deletions

View File

@ -4079,14 +4079,20 @@ PHP_FUNCTION(getenv)
}
#ifdef PHP_WIN32
{
char dummybuf;
int size;
wchar_t dummybuf;
DWORD size;
wchar_t *keyw, *valw;
keyw = php_win32_cp_conv_any_to_w(str, str_len, PHP_WIN32_CP_IGNORE_LEN_P);
if (!keyw) {
RETURN_FALSE;
}
SetLastError(0);
/*If the given bugger is not large enough to hold the data, the return value is
the buffer size, in characters, required to hold the string and its terminating
null character. We use this return value to alloc the final buffer. */
size = GetEnvironmentVariableA(str, &dummybuf, 0);
size = GetEnvironmentVariableW(keyw, &dummybuf, 0);
if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
/* The environment variable doesn't exist. */
RETURN_FALSE;
@ -4097,15 +4103,19 @@ PHP_FUNCTION(getenv)
RETURN_EMPTY_STRING();
}
ptr = emalloc(size);
size = GetEnvironmentVariableA(str, ptr, size);
valw = emalloc(size);
size = GetEnvironmentVariableW(keyw, valw, size);
if (size == 0) {
/* has been removed between the two calls */
efree(ptr);
free(keyw);
efree(valw);
RETURN_EMPTY_STRING();
} else {
ptr = php_win32_cp_w_to_any(valw);
RETVAL_STRING(ptr);
efree(ptr);
free(ptr);
free(keyw);
efree(valw);
return;
}
}
@ -4190,7 +4200,22 @@ PHP_FUNCTION(putenv)
# ifndef PHP_WIN32
if (putenv(pe.putenv_string) == 0) { /* success */
# else
error_code = SetEnvironmentVariable(pe.key, value);
wchar_t *keyw, *valw = NULL;
keyw = php_win32_cp_any_to_w(pe.key);
if (value) {
valw = php_win32_cp_any_to_w(value);
}
/* valw may be NULL, but the failed conversion still needs to be checked. */
if (!keyw || !valw && value) {
efree(pe.putenv_string);
efree(pe.key);
free(keyw);
free(valw);
RETURN_FALSE;
}
error_code = SetEnvironmentVariableW(keyw, valw);
if (error_code != 0
# ifndef ZTS
@ -4199,7 +4224,7 @@ PHP_FUNCTION(putenv)
Obviously the CRT version will be useful more often. But
generally, doing both brings us on the safe track at least
in NTS build. */
&& _putenv_s(pe.key, value ? value : "") == 0
&& _wputenv_s(keyw, valw ? valw : L"") == 0
# endif
) { /* success */
# endif
@ -4209,11 +4234,19 @@ PHP_FUNCTION(putenv)
if (!strncmp(pe.key, "TZ", pe.key_len)) {
tzset();
}
#endif
#if defined(PHP_WIN32)
free(keyw);
free(valw);
#endif
RETURN_TRUE;
} else {
efree(pe.putenv_string);
efree(pe.key);
#if defined(PHP_WIN32)
free(keyw);
free(valw);
#endif
RETURN_FALSE;
}
}

View File

@ -0,0 +1,61 @@
--TEST--
Bug #75574 putenv does not work properly if parameter contains non-ASCII unicode character, cp936 Windows
--SKIPIF--
<?php
if (substr(PHP_OS, 0, 3) != 'WIN') {
die("skip Valid only on Windows");
}
if (!sapi_windows_cp_set(936)) {
die("skip Required CP 936 or compatible");
}
?>
--INI--
internal_encoding=cp936
--FILE--
<?php
/*
#vim: set fileencoding=cp936
#vim: set encoding=cp936
*/
var_dump(putenv('FOO=가'), getenv("FOO"));
var_dump(putenv('FOO=가가'), getenv("FOO"));
var_dump(putenv('FOO=가가가'), getenv("FOO"));
var_dump(putenv('FOO=가가가가'), getenv("FOO"));
var_dump(putenv('FOO=가a'), getenv("FOO"));
var_dump(putenv('FOO=가a가'), getenv("FOO"));
var_dump(putenv('FOO=가a가a'), getenv("FOO"));
var_dump(putenv('FOO=가a가a가'), getenv("FOO"));
var_dump(putenv('FOO=가a가가'), getenv("FOO"));
var_dump(putenv('FOO=가a가가가'), getenv("FOO"));
var_dump(putenv('FOO=가a가가가가'), getenv("FOO"));
?>
===DONE===
--EXPECTF--
bool(true)
string(2) "가"
bool(true)
string(4) "가가"
bool(true)
string(6) "가가가"
bool(true)
string(8) "가가가가"
bool(true)
string(3) "가a"
bool(true)
string(5) "가a가"
bool(true)
string(6) "가a가a"
bool(true)
string(8) "가a가a가"
bool(true)
string(7) "가a가가"
bool(true)
string(9) "가a가가가"
bool(true)
string(11) "가a가가가가"
===DONE===

View File

@ -0,0 +1,50 @@
--TEST--
Bug #75574 putenv does not work properly if parameter contains non-ASCII unicode character, UTF-8
--INI--
internal_encoding=utf-8
--FILE--
<?php
/*
#vim: set fileencoding=utf-8
#vim: set encoding=utf-8
*/
var_dump(putenv('FOO=啊'), getenv("FOO"));
var_dump(putenv('FOO=啊啊'), getenv("FOO"));
var_dump(putenv('FOO=啊啊啊'), getenv("FOO"));
var_dump(putenv('FOO=啊啊啊啊'), getenv("FOO"));
var_dump(putenv('FOO=啊a'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊a'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊a啊'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊啊'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊啊啊'), getenv("FOO"));
var_dump(putenv('FOO=啊a啊啊啊啊'), getenv("FOO"));
?>
===DONE===
--EXPECTF--
bool(true)
string(3) "啊"
bool(true)
string(6) "啊啊"
bool(true)
string(9) "啊啊啊"
bool(true)
string(12) "啊啊啊啊"
bool(true)
string(4) "啊a"
bool(true)
string(7) "啊a啊"
bool(true)
string(8) "啊a啊a"
bool(true)
string(11) "啊a啊a啊"
bool(true)
string(10) "啊a啊啊"
bool(true)
string(13) "啊a啊啊啊"
bool(true)
string(16) "啊a啊啊啊啊"
===DONE===