authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-06-30 10:34:14+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-07-01 22:35:19+03:00
log1fc877fd9473c50a51bc616118250a9fc64d3da0
treec6dadf06ac0392e5f1d5b4d133b3e331e21dfa77
parent628f490c59449e38fcc9122968c385997b9e788b

std: Catch and handle overflow in json parser

When a floating-point value with no fractional part is shoved into an integer type we must check whether it fits or not before calling `@floatToInt` as the builtin panics in case of overflow. Catch the error and bubble it up to the caller.

1 files changed, 2 insertions(+), 0 deletions(-)

lib/std/json.zig+2
...@@ -1555,6 +1555,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:...@@ -1555,6 +1555,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:
1555 return try std.fmt.parseInt(T, numberToken.slice(tokens.slice, tokens.i - 1), 10);1555 return try std.fmt.parseInt(T, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1556 const float = try std.fmt.parseFloat(f128, numberToken.slice(tokens.slice, tokens.i - 1));1556 const float = try std.fmt.parseFloat(f128, numberToken.slice(tokens.slice, tokens.i - 1));
1557 if (std.math.round(float) != float) return error.InvalidNumber;1557 if (std.math.round(float) != float) return error.InvalidNumber;
1558 if (float > std.math.maxInt(T) or float < std.math.minInt(T)) return error.Overflow;
1558 return @floatToInt(T, float);1559 return @floatToInt(T, float);
1559 },1560 },
1560 .Optional => |optionalInfo| {1561 .Optional => |optionalInfo| {
...@@ -2617,6 +2618,7 @@ test "parse exponential into int" {...@@ -2617,6 +2618,7 @@ test "parse exponential into int" {
2617 const r = try parse(T, &TokenStream.init("{ \"int\": 4.2e2 }"), ParseOptions{});2618 const r = try parse(T, &TokenStream.init("{ \"int\": 4.2e2 }"), ParseOptions{});
2618 try testing.expectEqual(@as(i64, 420), r.int);2619 try testing.expectEqual(@as(i64, 420), r.int);
2619 try testing.expectError(error.InvalidNumber, parse(T, &TokenStream.init("{ \"int\": 0.042e2 }"), ParseOptions{}));2620 try testing.expectError(error.InvalidNumber, parse(T, &TokenStream.init("{ \"int\": 0.042e2 }"), ParseOptions{}));
2621 try testing.expectError(error.Overflow, parse(T, &TokenStream.init("{ \"int\": 18446744073709551616.0 }"), ParseOptions{}));
2620}2622}
26212623
2622test "escaped characters" {2624test "escaped characters" {