mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 04:17:34 +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:
parent
afabfc1964
commit
be9cbd428e
1 changed files with 8 additions and 2 deletions
|
@ -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)
|
static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const String& string, StringView reserved_set)
|
||||||
{
|
{
|
||||||
StringBuilder decoded_builder;
|
StringBuilder decoded_builder;
|
||||||
|
auto code_point_start_offset = 0u;
|
||||||
auto expected_continuation_bytes = 0;
|
auto expected_continuation_bytes = 0;
|
||||||
for (size_t k = 0; k < string.length(); k++) {
|
for (size_t k = 0; k < string.length(); k++) {
|
||||||
auto code_unit = string[k];
|
auto code_unit = string[k];
|
||||||
|
@ -488,11 +489,13 @@ static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const S
|
||||||
if (second_digit >= 16)
|
if (second_digit >= 16)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
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;
|
k += 2;
|
||||||
if (expected_continuation_bytes > 0) {
|
if (expected_continuation_bytes > 0) {
|
||||||
decoded_builder.append(decoded_code_unit);
|
decoded_builder.append(decoded_code_unit);
|
||||||
expected_continuation_bytes--;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,13 +507,16 @@ static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const S
|
||||||
continue;
|
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)
|
if (leading_ones == 1 || leading_ones > 4)
|
||||||
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);
|
||||||
|
|
||||||
|
code_point_start_offset = decoded_builder.length();
|
||||||
decoded_builder.append(decoded_code_unit);
|
decoded_builder.append(decoded_code_unit);
|
||||||
expected_continuation_bytes = leading_ones - 1;
|
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();
|
return decoded_builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue