diff options
Diffstat (limited to 'win32/codepage.c')
-rw-r--r-- | win32/codepage.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/win32/codepage.c b/win32/codepage.c index b84909c10c..0543a057a5 100644 --- a/win32/codepage.c +++ b/win32/codepage.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2018 The PHP Group | + | Copyright (c) The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -22,6 +22,8 @@ #include "SAPI.h" #include <emmintrin.h> +#include "win32/console.h" + ZEND_TLS const struct php_win32_cp *cur_cp = NULL; ZEND_TLS const struct php_win32_cp *orig_cp = NULL; ZEND_TLS const struct php_win32_cp *cur_out_cp = NULL; @@ -103,10 +105,12 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size {/*{{{*/ wchar_t *ret, *ret_idx; const char *idx = in, *end; + char ch_err = 0; + #if PHP_DEBUG size_t save_in_len = in_len; #endif - + assert(in && in_len ? in[in_len] == '\0' : 1); if (!in) { @@ -124,29 +128,33 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size /* Process unaligned chunk. */ while (idx < aidx) { - if (!__isascii(*idx) && '\0' != *idx) { - ASCII_FAIL_RETURN() - } + ch_err |= *idx; idx++; } + if (ch_err & 0x80) { + ASCII_FAIL_RETURN() + } /* Process aligned chunk. */ + __m128i vec_err = _mm_setzero_si128(); while (end - idx > 15) { const __m128i block = _mm_load_si128((__m128i *)idx); - if (_mm_movemask_epi8(block)) { - ASCII_FAIL_RETURN() - } + vec_err = _mm_or_si128(vec_err, block); idx += 16; } + if (_mm_movemask_epi8(vec_err)) { + ASCII_FAIL_RETURN() + } } /* Process the trailing part, or otherwise process string < 16 bytes. */ while (idx < end) { - if (!__isascii(*idx) && '\0' != *idx) { - ASCII_FAIL_RETURN() - } + ch_err |= *idx; idx++; } + if (ch_err & 0x80) { + ASCII_FAIL_RETURN() + } ret = malloc((in_len+1)*sizeof(wchar_t)); if (!ret) { @@ -157,9 +165,6 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size ret_idx = ret; idx = in; - /* Check and conversion could be merged. This however would - be more expencive, if a non ASCII string was passed. - TODO check whether the impact is acceptable. */ if (in_len > 15) { const char *aidx = (const char *)ZEND_SLIDE_TO_ALIGNED16(in); @@ -292,11 +297,6 @@ __forceinline static char *php_win32_cp_get_enc(void) return enc; }/*}}}*/ -__forceinline static BOOL php_win32_cp_is_cli_sapi() -{/*{{{*/ - return strlen(sapi_module.name) >= sizeof("cli") - 1 && !strncmp(sapi_module.name, "cli", sizeof("cli") - 1); -}/*}}}*/ - PW32CP const struct php_win32_cp *php_win32_cp_get_current(void) {/*{{{*/ return cur_cp; @@ -476,7 +476,7 @@ PW32CP const struct php_win32_cp *php_win32_cp_do_setup(const char *enc) if (!orig_cp) { orig_cp = php_win32_cp_get_by_id(GetACP()); } - if (php_win32_cp_is_cli_sapi()) { + if (php_win32_console_is_cli_sapi()) { if (!orig_in_cp) { orig_in_cp = php_win32_cp_get_by_id(GetConsoleCP()); if (!orig_in_cp) { @@ -502,7 +502,7 @@ PW32CP const struct php_win32_cp *php_win32_cp_do_update(const char *enc) } cur_cp = php_win32_cp_get_by_enc(enc); - if (php_win32_cp_is_cli_sapi()) { + if (php_win32_console_is_cli_sapi()) { php_win32_cp_cli_do_setup(cur_cp->id); } @@ -577,7 +577,7 @@ PHP_FUNCTION(sapi_windows_cp_set) RETURN_FALSE; } - if (php_win32_cp_is_cli_sapi()) { + if (php_win32_console_is_cli_sapi()) { cp = php_win32_cp_cli_do_setup((DWORD)id); } else { cp = php_win32_cp_set_by_id((DWORD)id); @@ -657,7 +657,9 @@ PHP_FUNCTION(sapi_windows_cp_conv) RETURN_NULL(); } } else { - convert_to_string(z_in_cp); + if (!try_convert_to_string(z_in_cp)) { + return; + } in_cp = php_win32_cp_get_by_enc(Z_STRVAL_P(z_in_cp)); if (!in_cp) { @@ -678,7 +680,9 @@ PHP_FUNCTION(sapi_windows_cp_conv) RETURN_NULL(); } } else { - convert_to_string(z_out_cp); + if (!try_convert_to_string(z_out_cp)) { + return; + } out_cp = php_win32_cp_get_by_enc(Z_STRVAL_P(z_out_cp)); if (!out_cp) { @@ -708,11 +712,3 @@ PHP_FUNCTION(sapi_windows_cp_conv) /* }}} */ /* }}} */ -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ |