diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2022-09-12 16:31:16 +0200 |
---|---|---|
committer | Andrew Kaster <andrewdkaster@gmail.com> | 2022-10-09 10:37:20 -0600 |
commit | 3aeb57ed095d6174f1561a82afa8164923e2849d (patch) | |
tree | a80709825d5a274aa4f12efdc14140d8eb7e31e2 /AK/StringView.cpp | |
parent | f07e0180d63a522c1de4ac1c616b78a5ccaa3d37 (diff) | |
download | serenity-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.cpp | 15 |
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); |