summaryrefslogtreecommitdiff
path: root/AK/StringView.cpp
diff options
context:
space:
mode:
authorBen Wiederhake <BenWiederhake.GitHub@gmx.de>2022-09-12 16:31:16 +0200
committerAndrew Kaster <andrewdkaster@gmail.com>2022-10-09 10:37:20 -0600
commit3aeb57ed095d6174f1561a82afa8164923e2849d (patch)
treea80709825d5a274aa4f12efdc14140d8eb7e31e2 /AK/StringView.cpp
parentf07e0180d63a522c1de4ac1c616b78a5ccaa3d37 (diff)
downloadserenity-3aeb57ed095d6174f1561a82afa8164923e2849d.zip
AK+Everywhere: Fix data corruption due to code-point-to-char conversion
In particular, StringView::contains(char) is often used with a u32 code point. When this is done, the compiler will for some reason allow data corruption to occur silently. In fact, this is one of two reasons for the following OSS Fuzz issue: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=49184 This is probably a very old bug. In the particular case of URLParser, AK::is_url_code_point got confused: return /* ... */ || "!$&'()*+,-./:;=?@_~"sv.contains(code_point); If code_point is a large code point that happens to have the correct lower bytes, AK::is_url_code_point is then convinced that the given code point is okay, even if it is actually problematic. This commit fixes *only* the silent data corruption due to the erroneous conversion, and does not fully resolve OSS-Fuzz#49184.
Diffstat (limited to 'AK/StringView.cpp')
-rw-r--r--AK/StringView.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/AK/StringView.cpp b/AK/StringView.cpp
index c9b1cbc703..a987696a08 100644
--- a/AK/StringView.cpp
+++ b/AK/StringView.cpp
@@ -9,6 +9,7 @@
#include <AK/Find.h>
#include <AK/Function.h>
#include <AK/Memory.h>
+#include <AK/StringBuilder.h>
#include <AK/StringView.h>
#include <AK/Vector.h>
@@ -137,6 +138,20 @@ bool StringView::contains(char needle) const
return false;
}
+bool StringView::contains(u32 needle) const
+{
+ // A code point should be at most four UTF-8 bytes, which easily fits into StringBuilder's inline-buffer.
+ // Therefore, this will not allocate.
+ StringBuilder needle_builder;
+ auto result = needle_builder.try_append_code_point(needle);
+ if (result.is_error()) {
+ // The needle is invalid, therefore the string does not contain it.
+ return false;
+ }
+
+ return contains(needle_builder.string_view());
+}
+
bool StringView::contains(StringView needle, CaseSensitivity case_sensitivity) const
{
return StringUtils::contains(*this, needle, case_sensitivity);