mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-12-04 05:20:30 +00:00
AK: Allow exponents in JSON double values
This is required for ECMA-404 compliance, but probably not for serenity itself.
This commit is contained in:
parent
68c6161f25
commit
75ebcf6b4a
Notes:
sideshowbarker
2024-07-17 07:34:45 +09:00
Author: https://github.com/davidot Commit: https://github.com/SerenityOS/serenity/commit/75ebcf6b4a Pull-request: https://github.com/SerenityOS/serenity/pull/15100 Reviewed-by: https://github.com/linusg
2 changed files with 55 additions and 8 deletions
|
@ -190,6 +190,7 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
|||
JsonValue value;
|
||||
Vector<char, 128> number_buffer;
|
||||
Vector<char, 128> fraction_buffer;
|
||||
Vector<char, 128> exponent_buffer;
|
||||
|
||||
bool is_double = false;
|
||||
bool all_zero = true;
|
||||
|
@ -231,6 +232,30 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
|||
break;
|
||||
}
|
||||
|
||||
#ifndef KERNEL
|
||||
if (peek() == 'e' || peek() == 'E') {
|
||||
// Force it to be a double
|
||||
is_double = true;
|
||||
++m_index;
|
||||
|
||||
for (;;) {
|
||||
char ch = peek();
|
||||
if (ch == '.')
|
||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
if (ch == '-' || ch == '+' || (ch >= '0' && ch <= '9')) {
|
||||
exponent_buffer.append(ch);
|
||||
|
||||
++m_index;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (exponent_buffer.is_empty())
|
||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
}
|
||||
#endif
|
||||
|
||||
StringView number_string(number_buffer.data(), number_buffer.size());
|
||||
|
||||
#ifndef KERNEL
|
||||
|
@ -250,16 +275,29 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
|||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
whole = number.value();
|
||||
}
|
||||
double number_value = whole;
|
||||
|
||||
StringView fraction_string(fraction_buffer.data(), fraction_buffer.size());
|
||||
auto fraction_string_uint = fraction_string.to_uint<u64>();
|
||||
if (!fraction_string_uint.has_value())
|
||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
auto fraction = static_cast<double>(fraction_string_uint.value());
|
||||
double sign = (whole < 0) ? -1 : 1;
|
||||
if (!fraction_buffer.is_empty()) {
|
||||
StringView fraction_string(fraction_buffer.data(), fraction_buffer.size());
|
||||
auto fraction_string_uint = fraction_string.to_uint<u64>();
|
||||
if (!fraction_string_uint.has_value())
|
||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
auto fraction = static_cast<double>(fraction_string_uint.value());
|
||||
double sign = (whole < 0) ? -1 : 1;
|
||||
auto divider = pow(10.0, static_cast<double>(fraction_buffer.size()));
|
||||
number_value += sign * (fraction / divider);
|
||||
}
|
||||
|
||||
auto divider = pow(10.0, static_cast<double>(fraction_buffer.size()));
|
||||
value = JsonValue((double)whole + sign * (fraction / divider));
|
||||
if (exponent_buffer.size() > 0) {
|
||||
StringView exponent_string(exponent_buffer.data(), exponent_buffer.size());
|
||||
auto exponent_string_uint = exponent_string.to_int();
|
||||
if (!exponent_string_uint.has_value())
|
||||
return Error::from_string_literal("JsonParser: Error while parsing number");
|
||||
double exponent = pow(10.0, static_cast<double>(exponent_string_uint.value()));
|
||||
number_value *= exponent;
|
||||
}
|
||||
|
||||
value = JsonValue(number_value);
|
||||
} else {
|
||||
#endif
|
||||
auto to_unsigned_result = number_string.to_uint<u64>();
|
||||
|
|
|
@ -134,3 +134,12 @@ TEST_CASE(json_parse_long_decimals)
|
|||
auto value = JsonValue::from_string("1644452550.6489999294281"sv);
|
||||
EXPECT_EQ(value.value().as_double(), 1644452550.6489999294281);
|
||||
}
|
||||
|
||||
TEST_CASE(json_parse_number_with_exponent)
|
||||
{
|
||||
auto value_without_fraction = JsonValue::from_string("10e5"sv);
|
||||
EXPECT_EQ(value_without_fraction.value().as_double(), 1000000.0);
|
||||
|
||||
auto value_with_fraction = JsonValue::from_string("10.5e5"sv);
|
||||
EXPECT_EQ(value_with_fraction.value().as_double(), 1050000.0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue