mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 17:24:48 -05:00
LibWeb: Add parse_integer_digits
methods
The rules for parsing integers don't specify an upper bound on the value that can be returned, so the `parse_integer_digits` method can be used to check whether the given arbitrarily-large StringView is valid according to these rules. The `parse_integer` and `parse_non_negative_integer` methods would fail for values larger than 2147483647 when they shouldn't have.
This commit is contained in:
parent
7097152ebc
commit
d02b763cd6
Notes:
github-actions[bot]
2024-12-02 09:26:43 +00:00
Author: https://github.com/tcl3 Commit: https://github.com/LadybirdBrowser/ladybird/commit/d02b763cd6d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2685
2 changed files with 38 additions and 13 deletions
|
@ -12,7 +12,7 @@
|
|||
namespace Web::HTML {
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-integers
|
||||
Optional<i32> parse_integer(StringView string)
|
||||
Optional<StringView> parse_integer_digits(StringView string)
|
||||
{
|
||||
// 1. Let input be the string being parsed.
|
||||
// 2. Let position be a pointer into input, initially pointing at the start of the string.
|
||||
|
@ -26,7 +26,7 @@ Optional<i32> parse_integer(StringView string)
|
|||
|
||||
// 5. If position is past the end of input, return an error.
|
||||
if (lexer.is_eof()) {
|
||||
return {};
|
||||
return OptionalNone {};
|
||||
}
|
||||
|
||||
// 6. If the character indicated by position (the first character) is a U+002D HYPHEN-MINUS character (-):
|
||||
|
@ -40,23 +40,33 @@ Optional<i32> parse_integer(StringView string)
|
|||
|
||||
// 7. If the character indicated by position is not an ASCII digit, then return an error.
|
||||
if (!lexer.next_is(is_ascii_digit)) {
|
||||
return {};
|
||||
return OptionalNone {};
|
||||
}
|
||||
|
||||
// 8. Collect a sequence of code points that are ASCII digits from input given position, and interpret the resulting sequence as a base-ten integer. Let value be that integer.
|
||||
// NOTE: Integer conversion is performed by the caller.
|
||||
lexer.consume_while(is_ascii_digit);
|
||||
size_t end_index = lexer.tell();
|
||||
auto digits = lexer.input().substring_view(start_index, end_index - start_index);
|
||||
auto optional_value = AK::StringUtils::convert_to_int<i32>(digits);
|
||||
|
||||
// 9. If sign is "positive", return value, otherwise return the result of subtracting value from zero.
|
||||
// NOTE: Skipped, see comment on step 6.
|
||||
|
||||
return optional_value;
|
||||
return digits;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-integers
|
||||
Optional<i32> parse_integer(StringView string)
|
||||
{
|
||||
auto optional_digits = parse_integer_digits(string);
|
||||
if (!optional_digits.has_value())
|
||||
return {};
|
||||
|
||||
return optional_digits->to_number<i32>(TrimWhitespace::No);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-non-negative-integers
|
||||
Optional<u32> parse_non_negative_integer(StringView string)
|
||||
Optional<StringView> parse_non_negative_integer_digits(StringView string)
|
||||
{
|
||||
// 1. Let input be the string being parsed.
|
||||
// 2. Let value be the result of parsing input using the rules for parsing integers.
|
||||
|
@ -64,19 +74,32 @@ Optional<u32> parse_non_negative_integer(StringView string)
|
|||
// NOTE: Because we call `parse_integer`, we parse all integers as signed. If we need the extra
|
||||
// size that an unsigned integer offers, then this would need to be improved. That said,
|
||||
// I don't think we need to support such large integers at the moment.
|
||||
auto optional_value = parse_integer(string);
|
||||
|
||||
auto optional_integer_digits = parse_integer_digits(string);
|
||||
// 3. If value is an error, return an error.
|
||||
if (!optional_value.has_value()) {
|
||||
return {};
|
||||
}
|
||||
if (!optional_integer_digits.has_value())
|
||||
return OptionalNone {};
|
||||
|
||||
// 4. If value is less than zero, return an error.
|
||||
if (optional_value.value() < 0) {
|
||||
return {};
|
||||
}
|
||||
if (optional_integer_digits->length() > 1 && optional_integer_digits->starts_with('-') && optional_integer_digits->bytes().at(1) != '0')
|
||||
return OptionalNone {};
|
||||
|
||||
// 5. Return value.
|
||||
// NOTE: Integer conversion is performed by the caller.
|
||||
return optional_integer_digits;
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-non-negative-integers
|
||||
Optional<u32> parse_non_negative_integer(StringView string)
|
||||
{
|
||||
auto optional_digits = parse_non_negative_integer_digits(string);
|
||||
if (!optional_digits.has_value())
|
||||
return {};
|
||||
|
||||
auto optional_value = optional_digits->to_number<i64>(TrimWhitespace::No);
|
||||
if (!optional_value.has_value() || *optional_value > NumericLimits<u32>::max())
|
||||
return {};
|
||||
|
||||
return static_cast<u32>(optional_value.value());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
namespace Web::HTML {
|
||||
|
||||
Optional<i32> parse_integer(StringView string);
|
||||
Optional<StringView> parse_integer_digits(StringView string);
|
||||
|
||||
Optional<u32> parse_non_negative_integer(StringView string);
|
||||
Optional<StringView> parse_non_negative_integer_digits(StringView string);
|
||||
|
||||
Optional<double> parse_floating_point_number(StringView string);
|
||||
|
||||
|
|
Loading…
Reference in a new issue