diff options
| author | Sterling-Augustine <saugustine@google.com> | 2025-11-06 06:48:14 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-06 06:48:14 -0800 |
| commit | 7ff8a5175428361e90c7bd7fd765192bec42be42 (patch) | |
| tree | d765a7fbeb6568fa3fe46f4e8b26a105b15c3598 /libc/src/string | |
| parent | 277bd096890f04979e44c09ffa020e35bf35e06a (diff) | |
[libc] Fix stale char_ptr for find_first_character_wide read (#166594)
On exit from the loop, char_ptr had not been updated to match block_ptr,
resulting in erroneous results. Moving all updates out of the loop fixes
that.
Adjust derefences to always be inside bounds checks.
Diffstat (limited to 'libc/src/string')
| -rw-r--r-- | libc/src/string/string_utils.h | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/libc/src/string/string_utils.h b/libc/src/string/string_utils.h index 7feef56fb367..cbce62ead032 100644 --- a/libc/src/string/string_utils.h +++ b/libc/src/string/string_utils.h @@ -127,8 +127,8 @@ find_first_character_wide_read(const unsigned char *src, unsigned char ch, size_t cur = 0; // Step 1: read 1 byte at a time to align to block size - for (; reinterpret_cast<uintptr_t>(char_ptr) % sizeof(Word) != 0 && cur < n; - ++char_ptr, ++cur) { + for (; cur < n && reinterpret_cast<uintptr_t>(char_ptr) % sizeof(Word) != 0; + ++cur, ++char_ptr) { if (*char_ptr == ch) return const_cast<unsigned char *>(char_ptr); } @@ -136,18 +136,18 @@ find_first_character_wide_read(const unsigned char *src, unsigned char ch, const Word ch_mask = repeat_byte<Word>(ch); // Step 2: read blocks - for (const Word *block_ptr = reinterpret_cast<const Word *>(char_ptr); - !has_zeroes<Word>((*block_ptr) ^ ch_mask) && cur < n; - ++block_ptr, cur += sizeof(Word)) { - char_ptr = reinterpret_cast<const unsigned char *>(block_ptr); - } + const Word *block_ptr = reinterpret_cast<const Word *>(char_ptr); + for (; cur < n && !has_zeroes<Word>((*block_ptr) ^ ch_mask); + cur += sizeof(Word), ++block_ptr) + ; + char_ptr = reinterpret_cast<const unsigned char *>(block_ptr); // Step 3: find the match in the block - for (; *char_ptr != ch && cur < n; ++char_ptr, ++cur) { + for (; cur < n && *char_ptr != ch; ++cur, ++char_ptr) { ; } - if (*char_ptr != ch || cur >= n) + if (cur >= n || *char_ptr != ch) return static_cast<void *>(nullptr); return const_cast<unsigned char *>(char_ptr); |
