diff --git a/src/cmph.zig b/src/cmph.zig index eaefc75..a1e966e 100644 --- a/src/cmph.zig +++ b/src/cmph.zig @@ -28,6 +28,7 @@ pub fn pack(allocator: Allocator, input: [][*:0]const u8) Error![]const u8 { const size = c.cmph_packed_size(hash); var buf = try allocator.alloc(u8, size); + errdefer allocator.free(buf); c.cmph_pack(hash, &buf[0]); c.cmph_destroy(hash); return buf[4..]; diff --git a/src/group.zig b/src/group.zig index b2d3fd3..ea59b3c 100644 --- a/src/group.zig +++ b/src/group.zig @@ -139,6 +139,7 @@ pub fn someMembers( members: []const []const u8, ) Allocator.Error!BufSet { var bufset = BufSet.init(allocator); + errdefer bufset.deinit(); for (members) |member| { try bufset.insert(member); } diff --git a/src/sections.zig b/src/sections.zig index 93ee1da..d913956 100644 --- a/src/sections.zig +++ b/src/sections.zig @@ -53,6 +53,7 @@ const Corpus = struct { ) initErr!Corpus { var arena = std.heap.ArenaAllocator.init(baseAllocator); var allocator = arena.allocator(); + errdefer arena.deinit(); var users = try allocator.alloc(User, usersConst.len); var groups = try allocator.alloc(Group, groupsConst.len); @@ -108,6 +109,7 @@ const Corpus = struct { var username2groups = StringHashMap( ArrayListUnmanaged(*const Group), ).init(baseAllocator); + defer username2groups.deinit(); for (groups) |*group| { var members = try allocator.alloc(*const User, group.members.count()); @@ -150,7 +152,6 @@ const Corpus = struct { const usergroups = elem.value_ptr.*.toOwnedSlice(allocator); try username2groups_final.put(username, usergroups); } - username2groups.deinit(); return Corpus{ .arena = arena, @@ -243,11 +244,13 @@ pub const UserGids = struct { const userGidsErr = Allocator.Error || error{Overflow}; pub fn userGids(allocator: Allocator, corpus: *const Corpus) userGidsErr!UserGids { - var arena = std.heap.ArenaAllocator.init(allocator); - defer arena.deinit(); var blob = ArrayList(u8).init(allocator); - + errdefer blob.deinit(); var name2offset = StringHashMap(u32).init(allocator); + errdefer name2offset.deinit(); + + var scratch = try allocator.alloc(u32, 256); + defer allocator.free(scratch); for (corpus.users) |user| { const usergroups_maybe = corpus.username2groups.get(user.name); if (usergroups_maybe == null) @@ -255,19 +258,16 @@ pub fn userGids(allocator: Allocator, corpus: *const Corpus) userGidsErr!UserGid const usergroups = usergroups_maybe.?; try name2offset.putNoClobber(user.name, try math.cast(u32, blob.items.len)); - var deltaCompressedGids = try arena.allocator().alloc(u32, usergroups.len); - - deltaCompressedGids.len = usergroups.len; - for (usergroups) |group, i| { - deltaCompressedGids[i] = group.gid; - } - compress.deltaCompress(u32, deltaCompressedGids) catch |err| switch (err) { + scratch = try allocator.realloc(scratch, usergroups.len); + scratch.len = usergroups.len; + for (usergroups) |group, i| + scratch[i] = group.gid; + compress.deltaCompress(u32, scratch) catch |err| switch (err) { error.NotSorted => unreachable, }; try compress.appendUvarint(&blob, usergroups.len); - for (deltaCompressedGids) |gid| { + for (scratch) |gid| try compress.appendUvarint(&blob, gid); - } } return UserGids{