1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 06:27:45 +00:00

LibJS: Check validity of encoded unicode code points in the Decode AO

As required by the specification:
7. If Octets does not contain a valid UTF-8 encoding of a Unicode code
point, throw a URIError exception.
This commit is contained in:
Idan Horowitz 2022-01-16 19:04:34 +02:00 committed by Linus Groh
parent afabfc1964
commit be9cbd428e

View file

@ -466,6 +466,7 @@ static ThrowCompletionOr<String> encode([[maybe_unused]] JS::GlobalObject& globa
static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const String& string, StringView reserved_set)
{
StringBuilder decoded_builder;
auto code_point_start_offset = 0u;
auto expected_continuation_bytes = 0;
for (size_t k = 0; k < string.length(); k++) {
auto code_unit = string[k];
@ -488,11 +489,13 @@ static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const S
if (second_digit >= 16)
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
char decoded_code_unit = (first_digit << 4) | second_digit;
u8 decoded_code_unit = (first_digit << 4) | second_digit;
k += 2;
if (expected_continuation_bytes > 0) {
decoded_builder.append(decoded_code_unit);
expected_continuation_bytes--;
if (expected_continuation_bytes == 0 && !Utf8View(decoded_builder.string_view().substring_view(code_point_start_offset)).validate())
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
continue;
}
@ -504,13 +507,16 @@ static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const S
continue;
}
auto leading_ones = count_trailing_zeroes_safe(static_cast<u32>(~decoded_code_unit)) - 24;
auto leading_ones = count_leading_zeroes_safe(static_cast<u8>(~decoded_code_unit));
if (leading_ones == 1 || leading_ones > 4)
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
code_point_start_offset = decoded_builder.length();
decoded_builder.append(decoded_code_unit);
expected_continuation_bytes = leading_ones - 1;
}
if (expected_continuation_bytes > 0)
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
return decoded_builder.build();
}