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