mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 08:11:13 +00:00
AK: Do not coerce i64 and u64 values to i32 and u32
First, this isn't actually helpful, as we no longer store 32-bit values in JsonValue. They are stored as 64-bit values anyways. But more imporatantly, there was a bug here when trying to coerce an i64 to an i32. All negative values were cast to an i32, without checking if the value is below NumericLimits<i32>::min.
This commit is contained in:
parent
749cf2d1b5
commit
7b3b608caf
Notes:
github-actions[bot]
2024-09-27 08:48:15 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/7b3b608cafb Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1546 Reviewed-by: https://github.com/tcl3 ✅
|
@ -271,19 +271,10 @@ ErrorOr<JsonValue> JsonParser::parse_number()
|
||||||
|
|
||||||
StringView number_string(number_buffer.data(), number_buffer.size());
|
StringView number_string(number_buffer.data(), number_buffer.size());
|
||||||
|
|
||||||
auto to_unsigned_result = number_string.to_number<u64>();
|
if (auto number = number_string.to_number<u64>(); number.has_value())
|
||||||
if (to_unsigned_result.has_value()) {
|
return JsonValue(*number);
|
||||||
if (*to_unsigned_result <= NumericLimits<u32>::max())
|
if (auto number = number_string.to_number<i64>(); number.has_value())
|
||||||
return JsonValue((u32)*to_unsigned_result);
|
return JsonValue(*number);
|
||||||
|
|
||||||
return JsonValue(*to_unsigned_result);
|
|
||||||
} else if (auto signed_number = number_string.to_number<i64>(); signed_number.has_value()) {
|
|
||||||
|
|
||||||
if (*signed_number <= NumericLimits<i32>::max())
|
|
||||||
return JsonValue((i32)*signed_number);
|
|
||||||
|
|
||||||
return JsonValue(*signed_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's possible the unsigned value is bigger than u64 max
|
// It's possible the unsigned value is bigger than u64 max
|
||||||
return fallback_to_double_parse();
|
return fallback_to_double_parse();
|
||||||
|
|
|
@ -128,6 +128,34 @@ TEST_CASE(json_64_bit_value)
|
||||||
EXPECT(big_json_value.equals(big_json_value_copy));
|
EXPECT(big_json_value.equals(big_json_value_copy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(json_64_bit_value_coerced_to_32_bit)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
auto min = NumericLimits<i64>::min();
|
||||||
|
auto max = NumericLimits<i64>::max();
|
||||||
|
|
||||||
|
auto json = TRY_OR_FAIL(JsonValue::from_string(MUST(String::number(min))));
|
||||||
|
EXPECT_EQ(json.get_integer<i64>(), min);
|
||||||
|
EXPECT(!json.is_integer<i32>());
|
||||||
|
|
||||||
|
json = TRY_OR_FAIL(JsonValue::from_string(MUST(String::number(max))));
|
||||||
|
EXPECT_EQ(json.get_integer<i64>(), max);
|
||||||
|
EXPECT(!json.is_integer<i32>());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto min = NumericLimits<u64>::min();
|
||||||
|
auto max = NumericLimits<u64>::max();
|
||||||
|
|
||||||
|
auto json = TRY_OR_FAIL(JsonValue::from_string(MUST(String::number(min))));
|
||||||
|
EXPECT_EQ(json.get_integer<u64>(), min);
|
||||||
|
EXPECT_EQ(json.get_integer<u32>(), min);
|
||||||
|
|
||||||
|
json = TRY_OR_FAIL(JsonValue::from_string(MUST(String::number(max))));
|
||||||
|
EXPECT_EQ(json.get_integer<u64>(), max);
|
||||||
|
EXPECT(!json.is_integer<u32>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(json_duplicate_keys)
|
TEST_CASE(json_duplicate_keys)
|
||||||
{
|
{
|
||||||
JsonObject json;
|
JsonObject json;
|
||||||
|
|
Loading…
Reference in a new issue