authorgravatar for motiejus@jakstys.ltMotiejus Jakštys <motiejus@jakstys.lt> 2022-03-01 14:55:15+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-01 13:28:47-05:00
log543bee0adf2d3b036654fa0983c16ff7023f504c
treef5aaeb93432acd7f8bff670dc3229c99ff7dbb71
parent52205a3c162d5adaf98be1dbf96bf86afd658182

std.BufSet.clone: fix key ownership

This was introduced in d1a46548349a902c30057b3ba66ebad9bc25bdd2: when a BufSet clones the keys, it used to assign the new pointers to the old struct. Fix that by assigning the pointers to the correct, i.e. the new, struct. This caused double-free when using arena allocator for the new struct, also in the test case.

1 files changed, 14 insertions(+), 1 deletions(-)

lib/std/buf_set.zig+14-1
...@@ -78,7 +78,7 @@ pub const BufSet = struct {...@@ -78,7 +78,7 @@ pub const BufSet = struct {
78 ) Allocator.Error!BufSet {78 ) Allocator.Error!BufSet {
79 var cloned_hashmap = try self.hash_map.cloneWithAllocator(new_allocator);79 var cloned_hashmap = try self.hash_map.cloneWithAllocator(new_allocator);
80 var cloned = BufSet{ .hash_map = cloned_hashmap };80 var cloned = BufSet{ .hash_map = cloned_hashmap };
81 var it = self.hash_map.keyIterator();81 var it = cloned.hash_map.keyIterator();
82 while (it.next()) |key_ptr| {82 while (it.next()) |key_ptr| {
83 key_ptr.* = try cloned.copy(key_ptr.*);83 key_ptr.* = try cloned.copy(key_ptr.*);
84 }84 }
...@@ -132,3 +132,16 @@ test "BufSet clone" {...@@ -132,3 +132,16 @@ test "BufSet clone" {
132 original.cloneWithAllocator(testing.failing_allocator),132 original.cloneWithAllocator(testing.failing_allocator),
133 );133 );
134}134}
135
136test "BufSet.clone with arena" {
137 var allocator = std.testing.allocator;
138 var arena = std.heap.ArenaAllocator.init(allocator);
139 defer arena.deinit();
140
141 var buf = BufSet.init(allocator);
142 defer buf.deinit();
143 try buf.insert("member1");
144 try buf.insert("member2");
145
146 _ = try buf.cloneWithAllocator(arena.allocator());
147}