diff --git a/src/DB.zig b/src/DB.zig index 7163a00..055f572 100644 --- a/src/DB.zig +++ b/src/DB.zig @@ -279,7 +279,7 @@ pub fn fromBytes(buf: []align(8) const u8) InvalidHeader!DB { return result; } -pub fn packCGroupNoMembers(group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup { +pub fn packCGroupNoMembers(group: *const PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup { // first word in buf will be a pointer to null. that probably can be // simplified by writing (0)**word_size to the buffer, but let's pretend // type safety for a moment. @@ -301,48 +301,53 @@ pub fn packCGroupNoMembers(group: PackedGroup, buf: []u8) error{BufferTooSmall}! }; } -const GroupMembersIter = struct { - it: compress.DeltaDecompressionIterator, -}; - -pub fn groupMembersIter(vit: *compress.VarintSliceIterator) GroupMembersIter { - return GroupMembersIter{ - .it = compress.deltaDecompressionIterator(vit), - }; -} - +// The pointer to `arr` gets changed on second iteration, and I don't know why. +// Leaving this for better times. +//const GroupMembersIter = struct { +// vit: compress.VarintSliceIterator, +// it: compress.DeltaDecompressionIterator, +// total: usize, +// arr: []const u8, +// +// pub fn nextMust(self: *GroupMembersIter) ?u64 { +// return self.it.nextMust(); +// } +//}; +// //pub fn groupMembersIter(members_slice: []const u8) GroupMembersIter { +// std.debug.print("members_slice.ptr={*}\n", .{members_slice.ptr}); // var vit = compress.varintSliceIteratorMust(members_slice); +// var it = compress.deltaDecompressionIterator(&vit); // return GroupMembersIter{ -// .it = compress.deltaDecompressionIterator(&vit), +// .arr = members_slice, +// .vit = vit, +// .it = it, +// .total = vit.remaining, // }; //} // dumps PackedGroup to []u8 and returns a CGroup. -pub fn packCGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup { +pub fn packCGroup(self: *const DB, group: *const PackedGroup, buf: []u8) error{BufferTooSmall}!CGroup { const members_slice = self.groupmembers[group.members_offset..]; var vit = compress.varintSliceIteratorMust(members_slice); const num_members = vit.remaining; const ptr_end = @sizeOf(?[*:0]const u8) * (num_members + 1); - if (ptr_end > buf.len) return error.BufferTooSmall; + if (ptr_end > buf.len) + return error.BufferTooSmall; var member_ptrs = mem.bytesAsSlice(?[*:0]const u8, buf[0..ptr_end]); member_ptrs[member_ptrs.len - 1] = null; var buf_offset: usize = ptr_end; var it = compress.deltaDecompressionIterator(&vit); - var members = groupMembersIter(&vit); - _ = members; - _ = it; var i: usize = 0; - std.debug.print("\n", .{}); while (it.nextMust()) |member_offset| : (i += 1) { - std.debug.print("got offset: {d}\n", .{member_offset}); const entry = PackedUser.fromBytes(self.users[member_offset << 3 ..]); const start = buf_offset; const name = entry.user.name(); - if (buf_offset + name.len + 1 > buf.len) return error.BufferTooSmall; + if (buf_offset + name.len + 1 > buf.len) + return error.BufferTooSmall; mem.copy(u8, buf[buf_offset..], name); buf_offset += name.len; buf[buf_offset] = 0; @@ -394,9 +399,9 @@ pub fn getgrnam( ) error{BufferTooSmall}!?CGroup { const group = self.getGroupByName(name) orelse return null; if (omit_members) - return try packCGroupNoMembers(group, buf) + return try packCGroupNoMembers(&group, buf) else - return try self.packCGroup(group, buf); + return try self.packCGroup(&group, buf); } // get a CGroup entry by it's gid. @@ -408,9 +413,9 @@ pub fn getgrgid( ) error{BufferTooSmall}!?CGroup { const group = self.getGroupByGid(gid) orelse return null; if (omit_members) - return try packCGroupNoMembers(group, buf) + return try packCGroupNoMembers(&group, buf) else - return try self.packCGroup(group, buf); + return try self.packCGroup(&group, buf); } fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 { diff --git a/src/compress.zig b/src/compress.zig index ecb8a9d..53da613 100644 --- a/src/compress.zig +++ b/src/compress.zig @@ -112,6 +112,7 @@ pub const VarintSliceIterator = struct { if (self.remaining == 0) return null; const value = try uvarint(self.arr[self.idx..]); + //std.debug.print("ptr={*} idx={d:<10} arr.ptr={*}\n", .{ self, self.idx, self.arr.ptr }); self.idx += value.bytes_read; self.remaining -= 1; return value.value; @@ -334,3 +335,33 @@ test "overflow" { try testing.expectError(error.Overflow, uvarint(t)); } } + +const compress = @This(); + +const GroupMembersIter = struct { + vit: compress.VarintSliceIterator, + it: compress.DeltaDecompressionIterator, + total: usize, +}; + +pub fn groupMembersIter(members_slice: []const u8) GroupMembersIter { + var vit = compress.varintSliceIteratorMust(members_slice); + var it = compress.deltaDecompressionIterator(&vit); + return GroupMembersIter{ + .vit = vit, + .it = it, + .total = vit.remaining, + }; +} + +test "compress: trying to repro pointer change of DB.groupMembersIter" { + const members_slice = &[_]u8{ 4, 0, 60, 2, 2, 2, 64, 2 }; + + var members = groupMembersIter(members_slice); + + var i: usize = 0; + while (members.it.nextMust()) |member_offset| : (i += 1) { + _ = member_offset; + //std.debug.print("member_offset: {d}\n", .{member_offset}); + } +} diff --git a/src/libnss.zig b/src/libnss.zig index 3c62f58..fcaa230 100644 --- a/src/libnss.zig +++ b/src/libnss.zig @@ -342,9 +342,9 @@ fn getgrent_r( }; const cgroup1 = if (state.omit_members) - DB.packCGroupNoMembers(group, buffer[0..buflen]) + DB.packCGroupNoMembers(&group, buffer[0..buflen]) else - state.file.db.packCGroup(group, buffer[0..buflen]); + state.file.db.packCGroup(&group, buffer[0..buflen]); if (cgroup1) |cgroup| { result.* = cgroup;