StringUtil: Return first match in BytePatternSearch()

Also validate byte pattern syntax and improve unit test coverage.
wip3-rebase
Stenzek 2 days ago
parent fc8675c95d
commit 60a798cdce
No known key found for this signature in database

@ -1008,6 +1008,12 @@ TEST(StringUtil, BytePatternSearch)
ASSERT_TRUE(result.has_value());
ASSERT_EQ(result.value(), 2u);
// Test that the first match is returned.
const std::vector<u8> duplicate_data = {0x01, 0x02, 0x01, 0x02};
result = StringUtil::BytePatternSearch(std::span<const u8>(duplicate_data), "01 02");
ASSERT_TRUE(result.has_value());
ASSERT_EQ(result.value(), 0u);
// Test with wildcards
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 ?? 03");
ASSERT_TRUE(result.has_value());
@ -1021,6 +1027,12 @@ TEST(StringUtil, BytePatternSearch)
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "");
ASSERT_FALSE(result.has_value());
// Test malformed patterns.
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 2");
ASSERT_FALSE(result.has_value());
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 GG");
ASSERT_FALSE(result.has_value());
// Test lowercase hex
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 02 03");
ASSERT_TRUE(result.has_value());
@ -1036,6 +1048,16 @@ TEST(StringUtil, BytePatternSearch)
ASSERT_TRUE(result.has_value());
ASSERT_EQ(result.value(), 5u);
// Test a wildcard match at the final valid offset.
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "06 ?? 08");
ASSERT_TRUE(result.has_value());
ASSERT_EQ(result.value(), 5u);
// Test a pattern exactly the size of the input.
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 02 03 04 05 06 07 08");
ASSERT_TRUE(result.has_value());
ASSERT_EQ(result.value(), 0u);
// Test a pattern longer than the input.
result = StringUtil::BytePatternSearch(std::span<const u8>(data), "01 02 03 04 05 06 07 08 09");
ASSERT_FALSE(result.has_value());

@ -1095,10 +1095,10 @@ std::optional<size_t> StringUtil::BytePatternSearch(const std::span<const u8> by
}
else
{
break;
return std::nullopt;
}
}
if (pattern_length == 0)
if (pattern_length == 0 || !hinibble)
return std::nullopt;
if (pattern_length > bytes.size())
return std::nullopt;
@ -1145,7 +1145,7 @@ std::optional<size_t> StringUtil::BytePatternSearch(const std::span<const u8> by
std::optional<size_t> 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 && !ret.has_value(); offset++)
{
const u8* start = bytes.data() + offset;
for (size_t match_offset = 0;;)

Loading…
Cancel
Save