mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.json: avoid dangling pointers in ValueTree
Closes https://github.com/ziglang/zig/issues/5229.
This commit is contained in:
parent
73c857415e
commit
b42caff2a2
@ -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| {
|
||||
|
||||
@ -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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user