pointer size checker
This commit is contained in:
parent
64bd5df633
commit
3c507ffe08
@ -154,8 +154,8 @@ OFFSET TYPE NAME DESCRIPTION
|
||||
40 u64 nblocks_users
|
||||
48 u64 nblocks_groupmembers
|
||||
56 u64 nblocks_additional_gids
|
||||
64 u64 getgr_max
|
||||
72 u64 getpw_max
|
||||
64 u64 getgr_bufsize
|
||||
72 u64 getpw_bufsize
|
||||
80 [48]u8 padding
|
||||
```
|
||||
|
||||
@ -168,7 +168,7 @@ number of bytes. However, interpreting `[2]u6` with `xxd(1)` is harder than
|
||||
interpreting `[2]u8`. Therefore we are using the space we have to make these
|
||||
integers byte-wide.
|
||||
|
||||
`getgr_max` and `getpw_max` is a hint for the caller of `getgr*` and
|
||||
`getgr_bufsize` and `getpw_bufsize` is a hint for the caller of `getgr*` and
|
||||
`getpw*`-family calls. This is the recommended size of the buffer, so the
|
||||
caller does not receive `ENOMEM`.
|
||||
|
||||
|
@ -26,8 +26,8 @@ name2group: StringHashMap(u32),
|
||||
group2users: []const []const u32,
|
||||
user2groups: []const []const u32,
|
||||
|
||||
getgr_max: usize,
|
||||
getpw_max: usize,
|
||||
getgr_bufsize: usize,
|
||||
getpw_bufsize: usize,
|
||||
|
||||
pub fn init(
|
||||
baseAllocator: Allocator,
|
||||
@ -43,15 +43,15 @@ pub fn init(
|
||||
|
||||
var groups_arr = try allocator.alloc(Group, groupsConst.len);
|
||||
var users_arr = try allocator.alloc(User, usersConst.len);
|
||||
var getgr_max: usize = 0;
|
||||
var getgr_bufsize: usize = 0;
|
||||
for (groupsConst) |*group, i| {
|
||||
groups_arr[i] = try group.clone(allocator);
|
||||
getgr_max = math.max(getgr_max, groups_arr[i].strlenZ());
|
||||
getgr_bufsize = math.max(getgr_bufsize, groups_arr[i].strlenZ());
|
||||
}
|
||||
var getpw_max: usize = 0;
|
||||
var getpw_bufsize: usize = 0;
|
||||
for (usersConst) |*user, i| {
|
||||
users_arr[i] = try user.clone(allocator);
|
||||
getpw_max = math.max(getpw_max, users_arr[i].strlenZ());
|
||||
getpw_bufsize = math.max(getpw_bufsize, users_arr[i].strlenZ());
|
||||
}
|
||||
|
||||
sort.sort(User, users_arr, {}, cmpUser);
|
||||
@ -123,8 +123,8 @@ pub fn init(
|
||||
.name2group = name2group,
|
||||
.group2users = group2users,
|
||||
.user2groups = user2groups_final,
|
||||
.getgr_max = getgr_max,
|
||||
.getpw_max = getpw_max,
|
||||
.getgr_bufsize = getgr_bufsize,
|
||||
.getpw_bufsize = getpw_bufsize,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,8 @@ pub fn fromCorpus(
|
||||
.nblocks_users = nblocks(u64, users.blob),
|
||||
.nblocks_groupmembers = nblocks(u64, groupmembers.blob),
|
||||
.nblocks_additional_gids = nblocks(u64, additional_gids.blob),
|
||||
.getgr_max = corpus.getgr_max,
|
||||
.getpw_max = corpus.getpw_max,
|
||||
.getgr_bufsize = corpus.getgr_bufsize,
|
||||
.getpw_bufsize = corpus.getpw_bufsize,
|
||||
};
|
||||
|
||||
return DB{
|
||||
@ -518,7 +518,7 @@ fn nblocks(comptime T: type, arr: []const u8) T {
|
||||
|
||||
fn assertDefinedLayout(comptime T: type) void {
|
||||
return switch (T) {
|
||||
u8, u16, u32, u64 => {},
|
||||
u4, u8, u16, u32, u64 => {},
|
||||
else => switch (@typeInfo(T)) {
|
||||
.Array => assertDefinedLayout(meta.Elem(T)),
|
||||
.Pointer => |info| assertDefinedLayout(info.child),
|
||||
@ -599,7 +599,7 @@ test "high-level API" {
|
||||
defer db.deinit(allocator);
|
||||
|
||||
// TODO: should accept a buffer instead of an allocator instead.
|
||||
var buf = try allocator.alloc(u8, db.header.getgr_max);
|
||||
var buf = try allocator.alloc(u8, db.header.getgr_bufsize);
|
||||
defer allocator.free(buf);
|
||||
const all = try db.getgrnam("all", &buf);
|
||||
try testing.expect(all != null);
|
||||
|
@ -7,7 +7,7 @@ const max_shells = @import("shell.zig").max_shells;
|
||||
const magic = [4]u8{ 0xf0, 0x9f, 0xa4, 0xb7 };
|
||||
const version = 0;
|
||||
|
||||
const Endian = enum(u8) {
|
||||
const Endian = enum(u4) {
|
||||
big,
|
||||
little,
|
||||
|
||||
@ -26,12 +26,14 @@ pub const Invalid = error{
|
||||
InvalidMagic,
|
||||
InvalidVersion,
|
||||
InvalidEndianess,
|
||||
InvalidPointerSize,
|
||||
};
|
||||
|
||||
pub const Header = packed struct {
|
||||
magic: [4]u8 = magic,
|
||||
version: u8 = version,
|
||||
endian: Endian = Endian.native(),
|
||||
ptr_size: u4 = @sizeOf(?[*:0]const u8),
|
||||
nblocks_shell_blob: u8,
|
||||
num_shells: u8,
|
||||
num_groups: u32,
|
||||
@ -44,8 +46,8 @@ pub const Header = packed struct {
|
||||
nblocks_users: u64,
|
||||
nblocks_groupmembers: u64,
|
||||
nblocks_additional_gids: u64,
|
||||
getgr_max: u64,
|
||||
getpw_max: u64,
|
||||
getgr_bufsize: u64,
|
||||
getpw_bufsize: u64,
|
||||
padding: [48]u8 = [1]u8{0} ** 48,
|
||||
|
||||
pub fn fromBytes(blob: *const [@sizeOf(Header)]u8) Invalid!*const Header {
|
||||
@ -60,6 +62,12 @@ pub const Header = packed struct {
|
||||
if (self.endian != Endian.native())
|
||||
return error.InvalidEndianess;
|
||||
|
||||
// when ptr size is larger than on the host that constructed it the DB,
|
||||
// getgr_bufsize/getpw_bufsize may return insufficient values, causing
|
||||
// OutOfMemory for getgr* and getpw* calls.
|
||||
if (self.ptr_size < @sizeOf(?[*:0]const u8))
|
||||
return error.InvalidPointerSize;
|
||||
|
||||
return self;
|
||||
}
|
||||
};
|
||||
@ -92,8 +100,8 @@ test "header pack and unpack" {
|
||||
.nblocks_users = 0,
|
||||
.nblocks_groupmembers = 0,
|
||||
.nblocks_additional_gids = 1,
|
||||
.getgr_max = 16,
|
||||
.getpw_max = 32,
|
||||
.getgr_bufsize = 16,
|
||||
.getpw_bufsize = 32,
|
||||
};
|
||||
|
||||
const bytes = mem.asBytes(&header1);
|
||||
|
Loading…
Reference in New Issue
Block a user