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 {
7878 ) Allocator.Error!BufSet {
7979 var cloned_hashmap = try self.hash_map.cloneWithAllocator(new_allocator);
8080 var cloned = BufSet{ .hash_map = cloned_hashmap };
81 var it = self.hash_map.keyIterator();
81 var it = cloned.hash_map.keyIterator();
8282 while (it.next()) |key_ptr| {
8383 key_ptr.* = try cloned.copy(key_ptr.*);
8484 }
......@@ -132,3 +132,16 @@ test "BufSet clone" {
132132 original.cloneWithAllocator(testing.failing_allocator),
133133 );
134134}
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}