From d3ee3fc68a67403940c22ad7ce20a9fb514e603f Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 12 Nov 2020 23:44:32 +0000 Subject: [PATCH] AK: Fix StringUtils::contains() case insensitive search It would incorrectly return false if needle was at the end the string. --- AK/StringUtils.cpp | 15 +++++++-------- AK/Tests/TestStringUtils.cpp | 2 ++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index eb17b558b6..531b1ff505 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -247,18 +247,17 @@ bool contains(const StringView& str, const StringView& needle, CaseSensitivity c return memmem(str_chars, str.length(), needle_chars, needle.length()) != nullptr; auto needle_first = to_lowercase(needle_chars[0]); - size_t slen = str.length() - needle.length(); - for (size_t si = 0; si < slen; si++) { + for (size_t si = 0; si < str.length(); si++) { if (to_lowercase(str_chars[si]) != needle_first) continue; - size_t ni = 1; - while (ni < needle.length()) { - if (to_lowercase(str_chars[si + ni]) != to_lowercase(needle_chars[ni])) + for (size_t ni = 0; si + ni < str.length(); ni++) { + if (to_lowercase(str_chars[si + ni]) != to_lowercase(needle_chars[ni])) { + si += ni; break; - ni++; + } + if (ni + 1 == needle.length()) + return true; } - if (ni == needle.length()) - return true; } return false; } diff --git a/AK/Tests/TestStringUtils.cpp b/AK/Tests/TestStringUtils.cpp index 55b4ab5fc7..6b608859ca 100644 --- a/AK/Tests/TestStringUtils.cpp +++ b/AK/Tests/TestStringUtils.cpp @@ -203,6 +203,8 @@ TEST_CASE(contains) EXPECT(AK::StringUtils::contains(test_string, "BCX", CaseSensitivity::CaseSensitive)); EXPECT(AK::StringUtils::contains(test_string, "BCX", CaseSensitivity::CaseInsensitive)); EXPECT(AK::StringUtils::contains(test_string, "BcX", CaseSensitivity::CaseInsensitive)); + EXPECT(!AK::StringUtils::contains(test_string, "xyz", CaseSensitivity::CaseSensitive)); + EXPECT(AK::StringUtils::contains(test_string, "xyz", CaseSensitivity::CaseInsensitive)); EXPECT(!AK::StringUtils::contains(test_string, "EFG", CaseSensitivity::CaseSensitive)); EXPECT(!AK::StringUtils::contains(test_string, "EfG", CaseSensitivity::CaseInsensitive)); EXPECT(AK::StringUtils::contains(test_string, "", CaseSensitivity::CaseSensitive));