From 1037433f3d9334a26142a6d3f7c08a802d68b092 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Wed, 3 Jun 2015 19:08:32 +0300 Subject: [PATCH] dbms: finally fix out-of-bounds access in SSE lower/upper UTF8[#METR-14764] --- dbms/include/DB/Functions/FunctionsString.h | 31 ++++++++------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/dbms/include/DB/Functions/FunctionsString.h b/dbms/include/DB/Functions/FunctionsString.h index a3c530217a9..52f9f73f98d 100644 --- a/dbms/include/DB/Functions/FunctionsString.h +++ b/dbms/include/DB/Functions/FunctionsString.h @@ -342,7 +342,6 @@ private: const auto v_zero = _mm_setzero_si128(); const auto v_not_case_lower_bound = _mm_set1_epi8(not_case_lower_bound - 1); const auto v_not_case_upper_bound = _mm_set1_epi8(not_case_upper_bound + 1); -// const auto v_not_case_range = _mm_set1_epi16((not_case_upper_bound << 8) | not_case_lower_bound); const auto v_flip_case_mask = _mm_set1_epi8(flip_case_mask); while (src < src_end_sse) @@ -360,10 +359,6 @@ private: _mm_cmplt_epi8(chars, v_not_case_upper_bound)); const auto mask_is_not_case = _mm_movemask_epi8(is_not_case); - /// check for case - // const auto is_case_result = _mm_cmpestra(v_not_case_range, 2, chars, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES); - // if (is_case_result == 0) - /// everything in correct case ASCII if (mask_is_not_case == 0) _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), chars); @@ -385,9 +380,9 @@ private: else { /// UTF-8 - const auto end = src + bytes_sse; + const auto expected_end = src + bytes_sse; - while (src < end) + while (src < expected_end) { if (src[0] <= ascii_upper_bound) { @@ -434,22 +429,20 @@ private: // res_pos += 3; // } else - { if (const auto chars = utf8.convert(to_case(utf8.convert(src)), dst, src_end - src)) - { - src += chars; - dst += chars; - } + src += chars, dst += chars; else - { - ++src; - ++dst; - } - } + ++src, ++dst; } - const auto diff = src - end; - src_end_sse += diff; + const auto diff = src - expected_end; + if (diff != 0) + { + if (src_end_sse + diff < src_end) + src_end_sse += diff; + else + src_end_sse -= bytes_sse - diff; + } } }