std.json: avoid dangling pointers in ValueTree

Closes https://github.com/ziglang/zig/issues/5229.
This commit is contained in:
John Schmidt 2023-02-04 18:44:57 +01:00
parent 73c857415e
commit b42caff2a2
2 changed files with 25 additions and 2 deletions

View File

@ -1163,11 +1163,12 @@ const ArrayList = std.ArrayList;
const StringArrayHashMap = std.StringArrayHashMap;
pub const ValueTree = struct {
arena: ArenaAllocator,
arena: *ArenaAllocator,
root: Value,
pub fn deinit(self: *ValueTree) void {
self.arena.deinit();
self.arena.child_allocator.destroy(self.arena);
}
};
@ -1809,8 +1810,12 @@ pub const Parser = struct {
pub fn parse(p: *Parser, input: []const u8) !ValueTree {
var s = TokenStream.init(input);
var arena = ArenaAllocator.init(p.allocator);
var arena = try p.allocator.create(ArenaAllocator);
errdefer p.allocator.destroy(arena);
arena.* = ArenaAllocator.init(p.allocator);
errdefer arena.deinit();
const allocator = arena.allocator();
while (try s.next()) |token| {

View File

@ -2589,6 +2589,24 @@ test "parsing empty string gives appropriate error" {
try testing.expectError(error.UnexpectedEndOfJson, testParse(arena_allocator.allocator(), ""));
}
test "parse tree should not contain dangling pointers" {
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena_allocator.deinit();
var p = json.Parser.init(arena_allocator.allocator(), false);
defer p.deinit();
var tree = try p.parse("[]");
defer tree.deinit();
// Allocation should succeed
var i: usize = 0;
while (i < 100) : (i += 1) {
try tree.root.Array.append(std.json.Value{ .Integer = 100 });
}
try testing.expectEqual(tree.root.Array.items.len, 100);
}
test "integer after float has proper type" {
var arena_allocator = std.heap.ArenaAllocator.init(std.testing.allocator);
defer arena_allocator.deinit();