diff options
| author | daurnimator <quae@daurnimator.com> | 2020-11-10 10:29:02 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-09 18:29:02 -0500 |
| commit | 73f3f0167079aaa47117175c31960963dc5af9ee (patch) | |
| tree | 3d83d834675ab341b6575f1910d7860040450add /lib/std/json.zig | |
| parent | 15dbab9a0c1016348fee388ba620cd933ac621a8 (diff) | |
| download | zig-73f3f0167079aaa47117175c31960963dc5af9ee.tar.gz zig-73f3f0167079aaa47117175c31960963dc5af9ee.zip | |
Fix json parser close tracking (#6865)
* std: fix json parsing with unmatched closing tokens
* std: fix swapped json parsing errors
Diffstat (limited to 'lib/std/json.zig')
| -rw-r--r-- | lib/std/json.zig | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/lib/std/json.zig b/lib/std/json.zig index 8ea91d8753..f6644fef9c 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -375,7 +375,7 @@ pub const StreamingParser = struct { '}' => { // unlikely if (p.stack & 1 != object_bit) { - return error.UnexpectedClosingBracket; + return error.UnexpectedClosingBrace; } if (p.stack_used == 0) { return error.TooManyClosingItems; @@ -401,7 +401,7 @@ pub const StreamingParser = struct { }, ']' => { if (p.stack & 1 != array_bit) { - return error.UnexpectedClosingBrace; + return error.UnexpectedClosingBracket; } if (p.stack_used == 0) { return error.TooManyClosingItems; @@ -571,8 +571,11 @@ pub const StreamingParser = struct { p.state = .ValueBeginNoClosing; }, ']' => { + if (p.stack & 1 != array_bit) { + return error.UnexpectedClosingBracket; + } if (p.stack_used == 0) { - return error.UnbalancedBrackets; + return error.TooManyClosingItems; } p.state = .ValueEnd; @@ -589,8 +592,12 @@ pub const StreamingParser = struct { token.* = Token.ArrayEnd; }, '}' => { + // unlikely + if (p.stack & 1 != object_bit) { + return error.UnexpectedClosingBrace; + } if (p.stack_used == 0) { - return error.UnbalancedBraces; + return error.TooManyClosingItems; } p.state = .ValueEnd; @@ -1189,6 +1196,15 @@ test "json.token" { testing.expect((try p.next()) == null); } +test "json.token mismatched close" { + var p = TokenStream.init("[102, 111, 111 }"); + checkNext(&p, .ArrayBegin); + checkNext(&p, .Number); + checkNext(&p, .Number); + checkNext(&p, .Number); + testing.expectError(error.UnexpectedClosingBrace, p.next()); +} + /// Validate a JSON string. This does not limit number precision so a decoder may not necessarily /// be able to decode the string even if this returns true. pub fn validate(s: []const u8) bool { @@ -1207,7 +1223,12 @@ pub fn validate(s: []const u8) bool { } test "json.validate" { - testing.expect(validate("{}")); + testing.expectEqual(true, validate("{}")); + testing.expectEqual(true, validate("[]")); + testing.expectEqual(true, validate("[{[[[[{}]]]]}]")); + testing.expectEqual(false, validate("{]")); + testing.expectEqual(false, validate("[}")); + testing.expectEqual(false, validate("{{{{[]}}}]")); } const Allocator = std.mem.Allocator; |
