From bce5e3ddceddfcca929f33b3d7e66d46d6627f53 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Mon, 21 Sep 2026 13:54:47 +1000 Subject: [PATCH] StringUtil: Fix buffer overflow in BytePatternSearch() Also fixes searching at the final valid offset and underflow when the pattern length exceeds the input length. --- src/common-tests/string_tests.cpp | 9 +++++++++ src/common/string_util.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/common-tests/string_tests.cpp b/src/common-tests/string_tests.cpp index f9f85e8db..91f5052a8 100644 --- a/src/common-tests/string_tests.cpp +++ b/src/common-tests/string_tests.cpp @@ -1030,6 +1030,15 @@ TEST(StringUtil, BytePatternSearch) result = StringUtil::BytePatternSearch(std::span(data), "01 ?? 03"); ASSERT_TRUE(result.has_value()); ASSERT_EQ(result.value(), 0u); + + // Test a match at the final valid offset. + result = StringUtil::BytePatternSearch(std::span(data), "06 07 08"); + ASSERT_TRUE(result.has_value()); + ASSERT_EQ(result.value(), 5u); + + // Test a pattern longer than the input. + result = StringUtil::BytePatternSearch(std::span(data), "01 02 03 04 05 06 07 08 09"); + ASSERT_FALSE(result.has_value()); } TEST(StringUtil, StrideMemCpy) diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 372599612..4f953d2f2 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -1100,6 +1100,8 @@ std::optional StringUtil::BytePatternSearch(const std::span by } if (pattern_length == 0) return std::nullopt; + if (pattern_length > bytes.size()) + return std::nullopt; const bool allocate_on_heap = (pattern_length >= 512); u8* match_bytes = allocate_on_heap ? new u8[pattern_length * 2] : static_cast(alloca(pattern_length * 2)); @@ -1143,7 +1145,7 @@ std::optional StringUtil::BytePatternSearch(const std::span by std::optional ret; const size_t max_search_offset = bytes.size() - pattern_length; - for (size_t offset = 0; offset < max_search_offset; offset++) + for (size_t offset = 0; offset <= max_search_offset; offset++) { const u8* start = bytes.data() + offset; for (size_t match_offset = 0;;) @@ -1154,8 +1156,8 @@ std::optional StringUtil::BytePatternSearch(const std::span by match_offset++; if (match_offset == pattern_length) { - // found it! ret = offset; + break; } } }