authorgravatar for emil@lerch.orgEmil Lerch <emil@lerch.org> 2021-06-24 17:07:58-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-26 10:10:36+03:00
log2ac769eab9b7dba4cd38e5de01dfa6400f7ebd5b
treee6f6bf4b763c9a22c5b6dcf69ec5ac52efb51d19
parentdacc5e624eb28570fe517b1f00ddc6287e2c5249

allow json scientific notation to coerce to integers as long as they actually resolve to int type


1 files changed, 14 insertions(+), 4 deletions(-)

lib/std/json.zig+14-4
......@@ -1551,8 +1551,11 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options:
15511551 .Number => |n| n,
15521552 else => return error.UnexpectedToken,
15531553 };
1554 if (!numberToken.is_integer) return error.UnexpectedToken;
1555 return try std.fmt.parseInt(T, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1554 if (numberToken.is_integer)
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));
1557 if (std.math.round(float) != float) return error.InvalidNumber;
1558 return @floatToInt(T, float);
15561559 },
15571560 .Optional => |optionalInfo| {
15581561 if (token == .Null) {
......@@ -2122,8 +2125,8 @@ test "parse into struct with duplicate field" {
21222125
21232126 const T1 = struct { a: *u64 };
21242127 // both .UseFirst and .UseLast should fail because second "a" value isn't a u64
2125 try testing.expectError(error.UnexpectedToken, parse(T1, &TokenStream.init(str), options_first));
2126 try testing.expectError(error.UnexpectedToken, parse(T1, &TokenStream.init(str), options_last));
2128 try testing.expectError(error.InvalidNumber, parse(T1, &TokenStream.init(str), options_first));
2129 try testing.expectError(error.InvalidNumber, parse(T1, &TokenStream.init(str), options_last));
21272130
21282131 const T2 = struct { a: f64 };
21292132 try testing.expectEqual(T2{ .a = 1.0 }, try parse(T2, &TokenStream.init(str), options_first));
......@@ -2609,6 +2612,13 @@ test "integer after float has proper type" {
26092612 try std.testing.expect(json.Object.get("ints").?.Array.items[0] == .Integer);
26102613}
26112614
2615test "parse exponential into int" {
2616 const T = struct { int: i64 };
2617 const r = try parse(T, &TokenStream.init("{ \"int\": 4.2e2 }"), ParseOptions{});
2618 try testing.expectEqual(@as(i64, 420), r.int);
2619 try testing.expectError(error.InvalidNumber, parse(T, &TokenStream.init("{ \"int\": 0.042e2 }"), ParseOptions{}));
2620}
2621
26122622test "escaped characters" {
26132623 var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
26142624 defer arena_allocator.deinit();