diff options
-rw-r--r-- | main/SAPI.c | 6 | ||||
-rw-r--r-- | sapi/cgi/cgi_main.c | 42 | ||||
-rw-r--r-- | sapi/cgi/tests/bug75574_utf8_win.phpt | 35 |
3 files changed, 83 insertions, 0 deletions
diff --git a/main/SAPI.c b/main/SAPI.c index c841c6e789..aec4e30d31 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -1027,6 +1027,12 @@ SAPI_API char *sapi_getenv(char *name, size_t name_len) char *value, *tmp = sapi_module.getenv(name, name_len); if (tmp) { value = estrdup(tmp); +#ifdef PHP_WIN32 + if (strlen(sapi_module.name) == sizeof("cgi-fcgi") - 1 && !strcmp(sapi_module.name, "cgi-fcgi")) { + /* XXX more modules to go, if needed. */ + free(tmp); + } +#endif } else { return NULL; } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 8639027dbc..a5627da311 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -534,9 +534,47 @@ static size_t sapi_fcgi_read_post(char *buffer, size_t count_bytes) return read_bytes; } +#ifdef PHP_WIN32 +/* The result needs to be freed! See sapi_getenv(). */ +static char *cgi_getenv_win32(const char *name, size_t name_len) +{ + char *ret = NULL; + wchar_t *keyw, *valw; + size_t size; + int rc; + + keyw = php_win32_cp_conv_any_to_w(name, name_len, PHP_WIN32_CP_IGNORE_LEN_P); + if (!keyw) { + return NULL; + } + + rc = _wgetenv_s(&size, NULL, 0, keyw); + if (rc || 0 == size) { + free(keyw); + return NULL; + } + + valw = emalloc((size + 1) * sizeof(wchar_t)); + + rc = _wgetenv_s(&size, valw, size, keyw); + if (!rc) { + ret = php_win32_cp_w_to_any(valw); + } + + free(keyw); + efree(valw); + + return ret; +} +#endif + static char *sapi_cgi_getenv(char *name, size_t name_len) { +#ifndef PHP_WIN32 return getenv(name); +#else + return cgi_getenv_win32(name, name_len); +#endif } static char *sapi_fcgi_getenv(char *name, size_t name_len) @@ -551,7 +589,11 @@ static char *sapi_fcgi_getenv(char *name, size_t name_len) if (ret) return ret; /* if cgi, or fastcgi and not found in fcgi env check the regular environment */ +#ifndef PHP_WIN32 return getenv(name); +#else + return cgi_getenv_win32(name, name_len); +#endif } static char *_sapi_cgi_putenv(char *name, size_t name_len, char *value) diff --git a/sapi/cgi/tests/bug75574_utf8_win.phpt b/sapi/cgi/tests/bug75574_utf8_win.phpt new file mode 100644 index 0000000000..f674168e03 --- /dev/null +++ b/sapi/cgi/tests/bug75574_utf8_win.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #75574 putenv does not work properly if parameter contains non-ASCII unicode character, UTF-8 +--SKIPIF-- +<?php + +if (substr(PHP_OS, 0, 3) != 'WIN') { + die("skip Valid only on Windows"); +} +include "skipif.inc"; +?> +--FILE-- +<?php +/* +#vim: set fileencoding=utf-8 +#vim: set encoding=utf-8 +*/ + +include "include.inc"; + +$php = get_cgi_path(); +reset_env_vars(); + +$fn = dirname(__FILE__) . DIRECTORY_SEPARATOR . md5(uniqid()); +file_put_contents($fn, "<?php\nvar_dump(putenv('FOO=啊'));\n//var_dump(`echo %FOO%`);\nvar_dump(getenv('FOO'));"); + +echo shell_exec("$php -n -f $fn"); + +unlink($fn); + +?> +===DONE=== +--EXPECTF-- +bool(true) +string(3) "啊" +===DONE=== |