AK+Tests: Fix StringUtils::contains() being confused by repeating text

Previously, case-insensitively searching the haystack "Go Go Back" for
the needle "Go Back" would return false:

1. Match the first three characters. "Go ".
2. Notice that 'G' and 'B' don't match.
3. Skip ahead 3 characters, plus 1 for the outer for-loop.
4. Now, the haystack is effectively "o Back", so the match fails.

Reducing the skip by 1 fixes this issue. I'm not 100% convinced this
fixes all cases, but I haven't been able to find any cases where it
doesn't work now. :^)
This commit is contained in:
Sam Atkins 2022-03-18 18:02:07 +00:00 committed by Linus Groh
parent 00eca26085
commit 7e98c8eaf6
Notes: sideshowbarker 2024-07-17 17:09:22 +09:00
2 changed files with 6 additions and 1 deletions

View File

@ -305,7 +305,8 @@ bool contains(StringView str, StringView needle, CaseSensitivity case_sensitivit
continue;
for (size_t ni = 0; si + ni < str.length(); ni++) {
if (to_ascii_lowercase(str_chars[si + ni]) != to_ascii_lowercase(needle_chars[ni])) {
si += ni;
if (ni > 0)
si += ni - 1;
break;
}
if (ni + 1 == needle.length())

View File

@ -321,6 +321,10 @@ TEST_CASE(contains)
EXPECT(!AK::StringUtils::contains("", test_string, CaseSensitivity::CaseInsensitive));
EXPECT(!AK::StringUtils::contains(test_string, "L", CaseSensitivity::CaseSensitive));
EXPECT(!AK::StringUtils::contains(test_string, "L", CaseSensitivity::CaseInsensitive));
String command_palette_bug_string = "Go Go Back";
EXPECT(AK::StringUtils::contains(command_palette_bug_string, "Go Back", AK::CaseSensitivity::CaseSensitive));
EXPECT(AK::StringUtils::contains(command_palette_bug_string, "gO bAcK", AK::CaseSensitivity::CaseInsensitive));
}
TEST_CASE(is_whitespace)