safety checks in group parsing
This commit is contained in:
parent
e1cae43d08
commit
a447e7fdf4
24
src/DB.zig
24
src/DB.zig
@ -368,21 +368,25 @@ pub fn packCGroup(self: *const DB, group: *const PackedGroup, buf: []u8) error{
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getGroupByName(self: *const DB, name: []const u8) ?PackedGroup {
|
||||
pub fn getGroupByName(self: *const DB, name: []const u8) error{Overflow}!?PackedGroup {
|
||||
const idx = bdz.search(self.bdz_groupname, name);
|
||||
if (idx >= self.header.num_groups) return null;
|
||||
if (idx >= self.header.num_groups)
|
||||
return null;
|
||||
const offset = self.idx_groupname2group[idx];
|
||||
const group = PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..])).group;
|
||||
if (!mem.eql(u8, name, group.name())) return null;
|
||||
const group = (try PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..]))).group;
|
||||
if (!mem.eql(u8, name, group.name()))
|
||||
return null;
|
||||
return group;
|
||||
}
|
||||
|
||||
pub fn getGroupByGid(self: *const DB, gid: u32) ?PackedGroup {
|
||||
pub fn getGroupByGid(self: *const DB, gid: u32) error{Overflow}!?PackedGroup {
|
||||
const idx = bdz.search_u32(self.bdz_gid, gid);
|
||||
if (idx >= self.header.num_groups) return null;
|
||||
if (idx >= self.header.num_groups)
|
||||
return null;
|
||||
const offset = self.idx_gid2group[idx];
|
||||
const group = PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..])).group;
|
||||
if (gid != group.gid()) return null;
|
||||
const group = (try PackedGroup.fromBytes(@alignCast(8, self.groups[offset << 3 ..]))).group;
|
||||
if (gid != group.gid())
|
||||
return null;
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -393,7 +397,7 @@ pub fn getgrnam(
|
||||
buf: []u8,
|
||||
omit_members: bool,
|
||||
) error{ Overflow, BufferTooSmall }!?CGroup {
|
||||
const group = self.getGroupByName(name) orelse return null;
|
||||
const group = try self.getGroupByName(name) orelse return null;
|
||||
if (omit_members)
|
||||
return try packCGroupNoMembers(&group, buf)
|
||||
else
|
||||
@ -407,7 +411,7 @@ pub fn getgrgid(
|
||||
buf: []u8,
|
||||
omit_members: bool,
|
||||
) error{ Overflow, BufferTooSmall }!?CGroup {
|
||||
const group = self.getGroupByGid(gid) orelse return null;
|
||||
const group = try self.getGroupByGid(gid) orelse return null;
|
||||
if (omit_members)
|
||||
return try packCGroupNoMembers(&group, buf)
|
||||
else
|
||||
|
@ -39,13 +39,11 @@ pub const Entry = struct {
|
||||
end: usize,
|
||||
};
|
||||
|
||||
pub fn fromBytes(bytes: []align(8) const u8) Entry {
|
||||
pub fn fromBytes(bytes: []align(8) const u8) error{Overflow}!Entry {
|
||||
const inner = mem.bytesAsValue(Inner, bytes[0..@sizeOf(Inner)]);
|
||||
const start_blob = @sizeOf(Inner);
|
||||
const end_strings = @sizeOf(Inner) + inner.groupnameLen();
|
||||
const members_offset = compress.uvarint(bytes[end_strings..]) catch |err| switch (err) {
|
||||
error.Overflow => unreachable,
|
||||
};
|
||||
const members_offset = try compress.uvarint(bytes[end_strings..]);
|
||||
const end_blob = end_strings + members_offset.bytes_read;
|
||||
|
||||
return Entry{
|
||||
@ -70,9 +68,9 @@ pub const Iterator = struct {
|
||||
total: u32,
|
||||
advanced_by: usize = 0,
|
||||
|
||||
pub fn next(it: *Iterator) ?PackedGroup {
|
||||
pub fn next(it: *Iterator) error{Overflow}!?PackedGroup {
|
||||
if (it.idx == it.total) return null;
|
||||
const entry = fromBytes(@alignCast(8, it.section[it.next_start..]));
|
||||
const entry = try fromBytes(@alignCast(8, it.section[it.next_start..]));
|
||||
it.idx += 1;
|
||||
it.next_start += entry.end;
|
||||
it.advanced_by = entry.end;
|
||||
@ -149,7 +147,7 @@ test "PackedGroup construct" {
|
||||
|
||||
var i: u29 = 0;
|
||||
var it = PackedGroup.iterator(buf.items, groups.len);
|
||||
while (it.next()) |group| : (i += 1) {
|
||||
while (try it.next()) |group| : (i += 1) {
|
||||
try testing.expectEqual(groups[i].gid, group.gid());
|
||||
try testing.expectEqualStrings(groups[i].name, group.name());
|
||||
try testing.expectEqual(groups[i].members_offset, group.membersOffset());
|
||||
|
@ -369,7 +369,9 @@ fn getgrent_r(
|
||||
return c.NSS_STATUS_UNAVAIL;
|
||||
});
|
||||
|
||||
const group = it.next() orelse {
|
||||
const group = it.next() catch |err| switch (err) {
|
||||
error.Overflow => return badFile(errnop),
|
||||
} orelse {
|
||||
errnop.* = 0;
|
||||
return c.NSS_STATUS_NOTFOUND;
|
||||
};
|
||||
|
@ -159,7 +159,7 @@ fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) error{Over
|
||||
|
||||
for (keys) |key| {
|
||||
const keyZ = mem.span(key);
|
||||
const maybe_packed_group = if (fmt.parseUnsigned(u32, keyZ, 10)) |gid|
|
||||
const maybe_packed_group = try if (fmt.parseUnsigned(u32, keyZ, 10)) |gid|
|
||||
db.getGroupByGid(gid)
|
||||
else |_|
|
||||
db.getGroupByName(keyZ);
|
||||
@ -178,7 +178,7 @@ fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) error{Over
|
||||
|
||||
fn groupAll(stdout: anytype, db: *const DB) error{Overflow}!u8 {
|
||||
var it = PackedGroup.iterator(db.groups, db.header.num_groups);
|
||||
while (it.next()) |g|
|
||||
while (try it.next()) |g|
|
||||
if (try printGroup(stdout, db, &g)) |exit_code|
|
||||
return exit_code;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user