diff options
author | Anatol Belski <ab@php.net> | 2019-04-01 02:17:40 +0200 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2019-04-01 02:17:40 +0200 |
commit | d8628e941fdf7a18168d59ef2eec586d92df1d0f (patch) | |
tree | c02be760e897dca5fbfde8f99117150b804b536a /win32/codepage.c | |
parent | bf78142295a2ecb5c639b7e61a7a3e7d63c8005c (diff) | |
parent | 1686c3fa47155d9c3884726b2ade4dede2eeb99f (diff) | |
download | php-git-d8628e941fdf7a18168d59ef2eec586d92df1d0f.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
Improve ascii check
Diffstat (limited to 'win32/codepage.c')
-rw-r--r-- | win32/codepage.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/win32/codepage.c b/win32/codepage.c index b8bb0bd88b..cdec68b8a7 100644 --- a/win32/codepage.c +++ b/win32/codepage.c @@ -105,6 +105,7 @@ 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; assert(in && in_len ? in[in_len] == '\0' : 1); @@ -123,29 +124,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) { @@ -156,9 +161,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); |