authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-06-08 17:43:13+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-06-08 17:43:13+12:00
logffb089a9f5fa95fd559a7c88081310d0be73f206
tree60dbb1ed07fc878205778d2bd20617b24eabbf87
parentf0b6dac1f2d37ea9eff0116bec34e9b2be9f3ce7

Fix json parser comma after empty object case


2 files changed, 23 insertions(+), 5 deletions(-)

std/json.zig+13-5
...@@ -324,7 +324,9 @@ pub const StreamingParser = struct {...@@ -324,7 +324,9 @@ pub const StreamingParser = struct {
324 p.complete = true;324 p.complete = true;
325 p.state = State.TopLevelEnd;325 p.state = State.TopLevelEnd;
326 },326 },
327 else => {},327 else => {
328 p.state = State.ValueEnd;
329 },
328 }330 }
329331
330 token.* = Token.initMarker(Token.Id.ObjectEnd);332 token.* = Token.initMarker(Token.Id.ObjectEnd);
...@@ -348,7 +350,9 @@ pub const StreamingParser = struct {...@@ -348,7 +350,9 @@ pub const StreamingParser = struct {
348 p.complete = true;350 p.complete = true;
349 p.state = State.TopLevelEnd;351 p.state = State.TopLevelEnd;
350 },352 },
351 else => {},353 else => {
354 p.state = State.ValueEnd;
355 },
352 }356 }
353357
354 token.* = Token.initMarker(Token.Id.ArrayEnd);358 token.* = Token.initMarker(Token.Id.ArrayEnd);
...@@ -970,7 +974,7 @@ pub fn validate(s: []const u8) bool {...@@ -970,7 +974,7 @@ pub fn validate(s: []const u8) bool {
970 var token1: ?Token = undefined;974 var token1: ?Token = undefined;
971 var token2: ?Token = undefined;975 var token2: ?Token = undefined;
972976
973 p.feed(c, *token1, *token2) catch |err| {977 p.feed(c, &token1, &token2) catch |err| {
974 return false;978 return false;
975 };979 };
976 }980 }
...@@ -978,6 +982,10 @@ pub fn validate(s: []const u8) bool {...@@ -978,6 +982,10 @@ pub fn validate(s: []const u8) bool {
978 return p.complete;982 return p.complete;
979}983}
980984
985test "json validate" {
986 debug.assert(validate("{}"));
987}
988
981const Allocator = std.mem.Allocator;989const Allocator = std.mem.Allocator;
982const ArenaAllocator = std.heap.ArenaAllocator;990const ArenaAllocator = std.heap.ArenaAllocator;
983const ArrayList = std.ArrayList;991const ArrayList = std.ArrayList;
...@@ -1230,7 +1238,7 @@ pub const Parser = struct {...@@ -1230,7 +1238,7 @@ pub const Parser = struct {
1230 _ = p.stack.pop();1238 _ = p.stack.pop();
1231 p.state = State.ObjectKey;1239 p.state = State.ObjectKey;
1232 },1240 },
1233 else => {1241 Token.Id.ObjectEnd, Token.Id.ArrayEnd => {
1234 unreachable;1242 unreachable;
1235 },1243 },
1236 }1244 }
...@@ -1270,7 +1278,7 @@ pub const Parser = struct {...@@ -1270,7 +1278,7 @@ pub const Parser = struct {
1270 Token.Id.Null => {1278 Token.Id.Null => {
1271 try array.append(Value.Null);1279 try array.append(Value.Null);
1272 },1280 },
1273 else => {1281 Token.Id.ObjectEnd => {
1274 unreachable;1282 unreachable;
1275 },1283 },
1276 }1284 }
std/json_test.zig+10
...@@ -17,6 +17,16 @@ fn any(comptime s: []const u8) void {...@@ -17,6 +17,16 @@ fn any(comptime s: []const u8) void {
17 std.debug.assert(true);17 std.debug.assert(true);
18}18}
1919
20////////////////////////////////////////////////////////////////////////////////////////////////////
21//
22// Additional tests not part of test JSONTestSuite.
23
24test "y_trailing_comma_after_empty" {
25 ok(
26 \\{"1":[],"2":{},"3":"4"}
27 );
28}
29
20////////////////////////////////////////////////////////////////////////////////////////////////////30////////////////////////////////////////////////////////////////////////////////////////////////////
2131
22test "y_array_arraysWithSpaces" {32test "y_array_arraysWithSpaces" {