diff --git a/src/string.cpp b/src/string.cpp index 59785cfe90..191d9924ad 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -368,6 +368,20 @@ bool StrEqualsIgnoreCase(const std::string_view str1, const std::string_view str return StrCompareIgnoreCase(str1, str2) == 0; } +/** + * Checks if a string is contained in another string, while ignoring the case of the characters. + * + * @param str The string to search in. + * @param value The string to search for. + * @return True if a match was found. + */ +bool StrContainsIgnoreCase(const std::string_view str, const std::string_view value) +{ + CaseInsensitiveStringView ci_str{ str.data(), str.size() }; + CaseInsensitiveStringView ci_value{ value.data(), value.size() }; + return ci_str.find(ci_value) != ci_str.npos; +} + /** * Get the length of an UTF-8 encoded string in number of characters * and thus not the number of bytes that the encoded string contains. diff --git a/src/string_func.h b/src/string_func.h index 25cc86489e..68fd80b45f 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -36,6 +36,7 @@ std::string_view StrTrimView(std::string_view str); [[nodiscard]] int StrCompareIgnoreCase(const std::string_view str1, const std::string_view str2); [[nodiscard]] bool StrEqualsIgnoreCase(const std::string_view str1, const std::string_view str2); +[[nodiscard]] bool StrContainsIgnoreCase(const std::string_view str, const std::string_view value); [[nodiscard]] int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front = false); [[nodiscard]] bool StrNaturalContains(const std::string_view str, const std::string_view value); [[nodiscard]] bool StrNaturalContainsIgnoreCase(const std::string_view str, const std::string_view value); diff --git a/src/stringfilter.cpp b/src/stringfilter.cpp index 539a95fca4..3a3221509b 100644 --- a/src/stringfilter.cpp +++ b/src/stringfilter.cpp @@ -102,10 +102,8 @@ void StringFilter::ResetState() * * @param str Another line from the item. */ -void StringFilter::AddLine(const char *str) +void StringFilter::AddLine(std::string_view str) { - if (str == nullptr) return; - bool match_case = this->case_sensitive != nullptr && *this->case_sensitive; for (WordState &ws : this->word_index) { if (!ws.match) { @@ -115,7 +113,7 @@ void StringFilter::AddLine(const char *str) this->word_matches++; } } else { - if ((match_case ? strstr(str, ws.word.c_str()) : strcasestr(str, ws.word.c_str())) != nullptr) { + if (match_case ? str.find(ws.word) != str.npos : StrContainsIgnoreCase(str, ws.word)) { ws.match = true; this->word_matches++; } diff --git a/src/stringfilter_type.h b/src/stringfilter_type.h index a4f6c8c03a..f060c3ca4c 100644 --- a/src/stringfilter_type.h +++ b/src/stringfilter_type.h @@ -57,8 +57,8 @@ public: bool IsEmpty() const { return this->word_index.empty(); } void ResetState(); - void AddLine(const char *str); - void AddLine(const std::string &str) { this->AddLine(str.c_str()); } + void AddLine(const char *) = delete; // prevent implicit construction of string_view from potential nullptr + void AddLine(std::string_view str); /** * Get the matching state of the current item.