group names are sentinel-terminated

This commit is contained in:
Motiejus Jakštys 2022-07-07 07:00:13 +03:00
parent 5f49a9f881
commit 50e116275c
3 changed files with 21 additions and 7 deletions

View File

@ -315,7 +315,7 @@ fn getGroup(self: *const DB, group: PackedGroup, buf: []u8) error{BufferTooSmall
return CGroup{ return CGroup{
.gid = group.gid(), .gid = group.gid(),
.name = buf[buf_offset .. buf_offset + name.len].ptr, .name = buf[buf_offset .. buf_offset + name.len :0].ptr,
.members = member_ptrs.ptr, .members = member_ptrs.ptr,
}; };
} }
@ -347,7 +347,7 @@ fn pushStr(str: []const u8, buf: []u8, offset: *usize) [*:0]const u8 {
mem.copy(u8, buf[start..], str); mem.copy(u8, buf[start..], str);
buf[start + str.len] = 0; buf[start + str.len] = 0;
offset.* += str.len + 1; offset.* += str.len + 1;
return @ptrCast([*:0]const u8, &buf[start]); return buf[start .. start + str.len :0].ptr;
} }
fn getUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!CUser { fn getUser(self: *const DB, user: PackedUser, buf: []u8) error{BufferTooSmall}!CUser {

View File

@ -128,14 +128,11 @@ pub fn strlenZ(self: *const Group) usize {
return count; return count;
} }
// Name type should be 0-terminated, members should be null-terminated, but
// sentinel is not part of the type (but is always there). Adding sentinel
// crashes zig compiler in pre-0.10. https://github.com/ziglang/zig/issues/7517
pub const CGroup = extern struct { pub const CGroup = extern struct {
gid: u32, gid: u32,
// should be [*:0]const u8 name: [*:0]const u8,
name: [*]const u8,
// Should be [*:null]align(1) const ?[*:0]const u8 // Should be [*:null]align(1) const ?[*:0]const u8
// https://github.com/ziglang/zig/issues/7517
members: [*]align(1) const ?[*:0]const u8, members: [*]align(1) const ?[*:0]const u8,
}; };

View File

@ -275,10 +275,27 @@ test "getgrgid_r and getgrnam_r" {
); );
try testing.expectEqual(@as(c_int, 0), errno); try testing.expectEqual(@as(c_int, 0), errno);
try testVidmantasGroup(group); try testVidmantasGroup(group);
group = undefined;
try testing.expectEqual(
c.NSS_STATUS_SUCCESS,
_nss_turbo_getgrnam_r("vidmantas", &group, &buffer, buffer.len, &errno),
);
try testing.expectEqual(@as(c_int, 0), errno);
try testVidmantasGroup(group);
group = undefined;
try testing.expectEqual(
c.NSS_STATUS_NOTFOUND,
_nss_turbo_getgrnam_r("does not exist", &group, &buffer, buffer.len, &errno),
);
try testing.expectEqual(@enumToInt(os.E.NOENT), @intCast(u16, errno));
} }
fn testVidmantasGroup(g: CGroup) !void { fn testVidmantasGroup(g: CGroup) !void {
try testing.expectEqual(@as(u32, 128), g.gid); try testing.expectEqual(@as(u32, 128), g.gid);
try testing.expectEqualStrings("vidmantas", mem.sliceTo(g.name, 0));
const members = g.members; const members = g.members;
try testing.expect(members[0] != null); try testing.expect(members[0] != null);
try testing.expectEqualStrings("vidmantas", mem.sliceTo(members[0].?, 0));
} }