From 8d54cbb834ab606ecfe23c6514cbac699319f60c Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Sun, 18 Nov 2018 10:14:37 -0800 Subject: [PATCH 1/2] Fix pushToParent to work for arrays of Objects The reference `*array` is a copy of the value on the stack. Instead use a reference to top of stack. This is the same technique used above for `var object` in `Value.String`. Added two simple tests. --- std/json.zig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/std/json.zig b/std/json.zig index 23573b6d72..9eb3a0ea70 100644 --- a/std/json.zig +++ b/std/json.zig @@ -1323,7 +1323,8 @@ pub const Parser = struct { p.state = State.ObjectKey; }, // Array Parent -> [ ..., , value ] - Value.Array => |*array| { + Value.Array => { + var array = &p.stack.items[p.stack.len - 1].Array; try array.append(value); p.state = State.ArrayValue; }, @@ -1364,7 +1365,8 @@ test "json parser dynamic" { \\ "Width": 100 \\ }, \\ "Animated" : false, - \\ "IDs": [116, 943, 234, 38793] + \\ "IDs": [116, 943, 234, 38793], + \\ "ArrayOfObject": [{"n": "m"}] \\ } \\} ; @@ -1387,4 +1389,10 @@ test "json parser dynamic" { const animated = image.Object.get("Animated").?.value; debug.assert(animated.Bool == false); + + const array_of_object = image.Object.get("ArrayOfObject").?.value; + debug.assert(array_of_object.Array.len == 1); + + const obj0 = array_of_object.Array.at(0).Object.get("n").?.value; + debug.assert(mem.eql(u8, obj0.String, "m")); } From a5b79017a32e8ee1c9486b3b3bf2c13fa7db899c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 27 Nov 2018 00:52:32 -0500 Subject: [PATCH 2/2] fix regression from d5648d26 thanks Wink Saville for the test case. --- std/json.zig | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/std/json.zig b/std/json.zig index e18de7ad10..4d07d7b89d 100644 --- a/std/json.zig +++ b/std/json.zig @@ -1188,7 +1188,7 @@ pub const Parser = struct { } var value = p.stack.pop(); - try p.pushToParent(value); + try p.pushToParent(&value); }, Token.Id.String => { try p.stack.append(try p.parseString(allocator, token, input, i)); @@ -1251,7 +1251,7 @@ pub const Parser = struct { } var value = p.stack.pop(); - try p.pushToParent(value); + try p.pushToParent(&value); }, Token.Id.ObjectBegin => { try p.stack.append(Value{ .Object = ObjectMap.init(allocator) }); @@ -1312,20 +1312,19 @@ pub const Parser = struct { } } - fn pushToParent(p: *Parser, value: Value) !void { - switch (p.stack.at(p.stack.len - 1)) { + fn pushToParent(p: *Parser, value: *const Value) !void { + switch (p.stack.toSlice()[p.stack.len - 1]) { // Object Parent -> [ ..., object, , value ] Value.String => |key| { _ = p.stack.pop(); var object = &p.stack.items[p.stack.len - 1].Object; - _ = try object.put(key, value); + _ = try object.put(key, value.*); p.state = State.ObjectKey; }, // Array Parent -> [ ..., , value ] - Value.Array => { - var array = &p.stack.items[p.stack.len - 1].Array; - try array.append(value); + Value.Array => |*array| { + try array.append(value.*); p.state = State.ArrayValue; }, else => {