From: Christoph M. Becker Date: Thu, 9 May 2019 14:55:35 +0000 (+0200) Subject: Merge branch 'PHP-7.2' into PHP-7.3 X-Git-Tag: php-7.3.6RC1~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fd1ffa4692dd91af08ea019fc2db0d8b3835dfe9;p=php Merge branch 'PHP-7.2' into PHP-7.3 * PHP-7.2: Fix erroneous assertions --- fd1ffa4692dd91af08ea019fc2db0d8b3835dfe9 diff --cc win32/codepage.c index 73645bc22b,86b7179c3e..b84909c10c --- a/win32/codepage.c +++ b/win32/codepage.c @@@ -94,16 -93,14 +94,19 @@@ PW32CP wchar_t *php_win32_cp_conv_to_w( return php_win32_cp_to_w_int(in, in_len, out_len, cp, flags); }/*}}}*/ +#define ASCII_FAIL_RETURN() \ + if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { \ + *out_len = 0; \ + } \ + return NULL; PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size_t *out_len) {/*{{{*/ - wchar_t *ret = NULL; + wchar_t *ret, *ret_idx; const char *idx = in, *end; - + #if PHP_DEBUG + size_t save_in_len = in_len; + #endif + assert(in && in_len ? in[in_len] == '\0' : 1); if (!in) { @@@ -145,60 -124,48 +148,60 @@@ idx++; } - if (idx == end) { - size_t i = 0; - int k = 0; - wchar_t *ret_idx; + ret = malloc((in_len+1)*sizeof(wchar_t)); + if (!ret) { + SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); + return NULL; + } + + ret_idx = ret; + idx = in; - ret = malloc((in_len+1)*sizeof(wchar_t)); - if (!ret) { - SET_ERRNO_FROM_WIN32_CODE(ERROR_OUTOFMEMORY); - return NULL; + /* 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); + + /* Process unaligned chunk. */ + while (idx < aidx) { + *ret_idx++ = (wchar_t)*idx++; } - ret_idx = ret; - do { - k = _snwprintf(ret_idx, in_len - i, L"%.*hs", (int)(in_len - i), in); + /* Process aligned chunk. */ + if (end - idx > 15) { + const __m128i mask = _mm_set1_epi32(0); + while (end - idx > 15) { + const __m128i block = _mm_load_si128((__m128i *)idx); - if (-1 == k) { - free(ret); - SET_ERRNO_FROM_WIN32_CODE(ERROR_INVALID_PARAMETER); - return NULL; - } + { + const __m128i lo = _mm_unpacklo_epi8(block, mask); + _mm_storeu_si128((__m128i *)ret_idx, lo); + } - i += k + 1; + ret_idx += 8; + { + const __m128i hi = _mm_unpackhi_epi8(block, mask); + _mm_storeu_si128((__m128i *)ret_idx, hi); + } - if (i < in_len) { - /* Advance as this seems to be a string with \0 in it. */ - in += k + 1; - ret_idx += k + 1; + idx += 16; + ret_idx += 8; } + } + } + /* Process the trailing part, or otherwise process string < 16 bytes. */ + while (idx < end) { + *ret_idx++ = (wchar_t)*idx++; + } - } while (i < in_len); - ret[in_len] = L'\0'; + ret[in_len] = L'\0'; - assert(ret ? wcslen(ret) == in_len : 1); - assert(ret && !save_in_len ? wcslen(ret) == in_len : 1); ++ assert(ret && !save_in_len ? wcslen(ret) == in_len : 1); - if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { - *out_len = in_len; - } - } else { - if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { - *out_len = 0; - } + if (PHP_WIN32_CP_IGNORE_LEN_P != out_len) { + *out_len = in_len; } return ret;