Fix json parser close tracking (#6865)

* std: fix json parsing with unmatched closing tokens

* std: fix swapped json parsing errors
master
daurnimator 2020-11-10 10:29:02 +11:00 committed by GitHub
parent 15dbab9a0c
commit 73f3f01670
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 5 deletions

View File

@ -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;