| 698 | } |
| 699 | |
| 700 | void StringFunctions::TrimContext::Reset(const StringVal& chars_to_trim) { |
| 701 | single_byte_chars_.reset(); |
| 702 | double_byte_chars_.clear(); |
| 703 | triple_byte_chars_.clear(); |
| 704 | quadruple_byte_chars_.clear(); |
| 705 | |
| 706 | if (!utf8_mode_) { |
| 707 | for (size_t i = 0; i < chars_to_trim.len; ++i) { |
| 708 | single_byte_chars_.set(chars_to_trim.ptr[i], true); |
| 709 | } |
| 710 | return; |
| 711 | } |
| 712 | |
| 713 | for (size_t i = 0, char_size = 0; i < chars_to_trim.len; i += char_size) { |
| 714 | char_size = BitUtil::NumBytesInUtf8Encoding(chars_to_trim.ptr[i]); |
| 715 | |
| 716 | // If the remaining number of bytes does not match the number of bytes specified by |
| 717 | // the UTF-8 character, we may have encountered an illegal UTF-8 character. |
| 718 | // In order to prevent subsequent data access from going out of bounds, restrictions |
| 719 | // are placed here to ensure that accessing pointers to multi-byte characters is |
| 720 | // always safe. |
| 721 | if (UNLIKELY(i + char_size > chars_to_trim.len)) { |
| 722 | char_size = chars_to_trim.len - i; |
| 723 | } |
| 724 | |
| 725 | switch (char_size) { |
| 726 | case 1: single_byte_chars_.set(chars_to_trim.ptr[i], true); break; |
| 727 | case 2: double_byte_chars_.push_back(&chars_to_trim.ptr[i]); break; |
| 728 | case 3: triple_byte_chars_.push_back(&chars_to_trim.ptr[i]); break; |
| 729 | case 4: quadruple_byte_chars_.push_back(&chars_to_trim.ptr[i]); break; |
| 730 | default: DCHECK(false); break; |
| 731 | } |
| 732 | } |
| 733 | } |
| 734 | |
| 735 | bool StringFunctions::TrimContext::Contains(const uint8_t* utf8_char, int len) const { |
| 736 | auto eq = [&](const uint8_t* c){ return memcmp(c, utf8_char, len) == 0; }; |
no test coverage detected