authorgravatar for quae@daurnimator.comdaurnimator <quae@daurnimator.com> 2020-11-10 10:29:02+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-09 16:29:22-07:00
log904c513a1e6fee98f4c431fe8213f7f32e18be6a
treece2299af88c202f302d0069ded53733e87317fd7
parent0e2eb6eb651112e27ae996cfdb67a878ddb61f81

Fix json parser close tracking (#6865)

* std: fix json parsing with unmatched closing tokens * std: fix swapped json parsing errors

1 files changed, 26 insertions(+), 5 deletions(-)

lib/std/json.zig+26-5
......@@ -375,7 +375,7 @@ pub const StreamingParser = struct {
375375 '}' => {
376376 // unlikely
377377 if (p.stack & 1 != object_bit) {
378 return error.UnexpectedClosingBracket;
378 return error.UnexpectedClosingBrace;
379379 }
380380 if (p.stack_used == 0) {
381381 return error.TooManyClosingItems;
......@@ -401,7 +401,7 @@ pub const StreamingParser = struct {
401401 },
402402 ']' => {
403403 if (p.stack & 1 != array_bit) {
404 return error.UnexpectedClosingBrace;
404 return error.UnexpectedClosingBracket;
405405 }
406406 if (p.stack_used == 0) {
407407 return error.TooManyClosingItems;
......@@ -571,8 +571,11 @@ pub const StreamingParser = struct {
571571 p.state = .ValueBeginNoClosing;
572572 },
573573 ']' => {
574 if (p.stack & 1 != array_bit) {
575 return error.UnexpectedClosingBracket;
576 }
574577 if (p.stack_used == 0) {
575 return error.UnbalancedBrackets;
578 return error.TooManyClosingItems;
576579 }
577580
578581 p.state = .ValueEnd;
......@@ -589,8 +592,12 @@ pub const StreamingParser = struct {
589592 token.* = Token.ArrayEnd;
590593 },
591594 '}' => {
595 // unlikely
596 if (p.stack & 1 != object_bit) {
597 return error.UnexpectedClosingBrace;
598 }
592599 if (p.stack_used == 0) {
593 return error.UnbalancedBraces;
600 return error.TooManyClosingItems;
594601 }
595602
596603 p.state = .ValueEnd;
......@@ -1189,6 +1196,15 @@ test "json.token" {
11891196 testing.expect((try p.next()) == null);
11901197}
11911198
1199test "json.token mismatched close" {
1200 var p = TokenStream.init("[102, 111, 111 }");
1201 checkNext(&p, .ArrayBegin);
1202 checkNext(&p, .Number);
1203 checkNext(&p, .Number);
1204 checkNext(&p, .Number);
1205 testing.expectError(error.UnexpectedClosingBrace, p.next());
1206}
1207
11921208/// Validate a JSON string. This does not limit number precision so a decoder may not necessarily
11931209/// be able to decode the string even if this returns true.
11941210pub fn validate(s: []const u8) bool {
......@@ -1207,7 +1223,12 @@ pub fn validate(s: []const u8) bool {
12071223}
12081224
12091225test "json.validate" {
1210 testing.expect(validate("{}"));
1226 testing.expectEqual(true, validate("{}"));
1227 testing.expectEqual(true, validate("[]"));
1228 testing.expectEqual(true, validate("[{[[[[{}]]]]}]"));
1229 testing.expectEqual(false, validate("{]"));
1230 testing.expectEqual(false, validate("[}"));
1231 testing.expectEqual(false, validate("{{{{[]}}}]"));
12111232}
12121233
12131234const Allocator = std.mem.Allocator;