From b56b0ba689638ee3a0c905f5df28bfa7a7fa2739 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Mon, 27 Sep 2021 20:17:56 +0300 Subject: [PATCH] AK: Eliminate avoidable strlen call in String::matches We already know the length of these substrings, so there's no need to check their lengths using strlen in the StringView(char*) constructor. This patch also removes an accidental 1-byte OOB read that was left over from when this method received null-terminated char pointers instead of string views, as well removes the unnecessary lambda call (two of the checks were impossible, and this was only called in one place, so we can just inline it) --- AK/StringUtils.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/AK/StringUtils.cpp b/AK/StringUtils.cpp index 887620c663..9ad58da156 100644 --- a/AK/StringUtils.cpp +++ b/AK/StringUtils.cpp @@ -29,7 +29,7 @@ bool matches(const StringView& str, const StringView& mask, CaseSensitivity case if (str.is_null() || mask.is_null()) return str.is_null() && mask.is_null(); - if (mask == "*") { + if (mask == "*"sv) { record_span(0, str.length()); return true; } @@ -40,24 +40,15 @@ bool matches(const StringView& str, const StringView& mask, CaseSensitivity case const char* mask_ptr = mask.characters_without_null_termination(); const char* mask_end = mask_ptr + mask.length(); - auto matches_one = [](char ch, char p, CaseSensitivity case_sensitivity) { - if (p == '?') - return true; - if (ch == 0) - return false; - if (case_sensitivity == CaseSensitivity::CaseSensitive) - return p == ch; - return to_ascii_lowercase(p) == to_ascii_lowercase(ch); - }; while (string_ptr < string_end && mask_ptr < mask_end) { auto string_start_ptr = string_ptr; switch (*mask_ptr) { case '*': - if (mask_ptr[1] == 0) { + if (mask_ptr == mask_end - 1) { record_span(string_ptr - string_start, string_end - string_ptr); return true; } - while (string_ptr < string_end && !matches(string_ptr, mask_ptr + 1, case_sensitivity)) + while (string_ptr < string_end && !matches({ string_ptr, static_cast(string_end - string_ptr) }, { mask_ptr + 1, static_cast(mask_end - mask_ptr - 1) }, case_sensitivity)) ++string_ptr; record_span(string_start_ptr - string_start, string_ptr - string_start_ptr); --string_ptr; @@ -66,7 +57,9 @@ bool matches(const StringView& str, const StringView& mask, CaseSensitivity case record_span(string_ptr - string_start, 1); break; default: - if (!matches_one(*string_ptr, *mask_ptr, case_sensitivity)) + auto p = *mask_ptr; + auto ch = *string_ptr; + if (case_sensitivity == CaseSensitivity::CaseSensitive ? p != ch : to_ascii_lowercase(p) != to_ascii_lowercase(ch)) return false; break; }