add strlen for PackedUser strings
This commit is contained in:
parent
c343bf64fb
commit
41ed32994f
@ -5,6 +5,7 @@ const math = std.math;
|
||||
const Allocator = mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const StringHashMap = std.StringHashMap;
|
||||
const fieldInfo = std.meta.fieldInfo;
|
||||
|
||||
const pad = @import("padding.zig");
|
||||
const validate = @import("validate.zig");
|
||||
@ -129,9 +130,7 @@ pub fn iterator(section: []const u8, shell_reader: shellImport.ShellReader) Iter
|
||||
return Iterator{ .section = section, .shell_reader = shell_reader };
|
||||
}
|
||||
|
||||
// packTo packs the User record and copies it to the given byte slice.
|
||||
// The slice must have at least maxRecordSize() bytes available. The
|
||||
// slice is passed as a pointer, so it can be mutated.
|
||||
// packTo packs the User record and copies it to the given arraylist.
|
||||
pub fn packTo(
|
||||
arr: *ArrayList(u8),
|
||||
user: User,
|
||||
@ -141,10 +140,11 @@ pub fn packTo(
|
||||
std.debug.assert(arr.items.len & 7 == 0);
|
||||
// function arguments are consts. We need to mutate the underlying
|
||||
// slice, so passing it via pointer instead.
|
||||
const home_len = try validate.downCast(u6, user.home.len - 1);
|
||||
const name_len = try validate.downCast(u5, user.name.len - 1);
|
||||
const shell_len = try validate.downCast(u8, user.shell.len - 1);
|
||||
const gecos_len = try validate.downCast(u8, user.gecos.len);
|
||||
//const home_len = try validate.downCast(u6, user.home.len - 1);
|
||||
const home_len = try validate.downCast(fieldInfo(Inner, .home_len).field_type, user.home.len - 1);
|
||||
const name_len = try validate.downCast(fieldInfo(Inner, .name_len).field_type, user.name.len - 1);
|
||||
const shell_len = try validate.downCast(fieldInfo(Inner, .shell_len_or_idx).field_type, user.shell.len - 1);
|
||||
const gecos_len = try validate.downCast(fieldInfo(Inner, .gecos_len).field_type, user.gecos.len);
|
||||
|
||||
try validate.utf8(user.home);
|
||||
try validate.utf8(user.name);
|
||||
@ -211,6 +211,11 @@ pub fn shell(self: PackedUser, shell_reader: shellImport.ShellReader) []const u8
|
||||
return shell_reader.get(self.inner.shell_len_or_idx);
|
||||
}
|
||||
|
||||
pub const max_str_len = math.maxInt(fieldInfo(Inner, .shell_len_or_idx).field_type) + 1 +
|
||||
math.maxInt(fieldInfo(Inner, .home_len).field_type) + 1 +
|
||||
math.maxInt(fieldInfo(Inner, .name_len).field_type) + 1 +
|
||||
math.maxInt(fieldInfo(Inner, .gecos_len).field_type);
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "PackedUser internal and external alignment" {
|
||||
@ -232,6 +237,33 @@ const test_shell_reader = shellImport.ShellReader{
|
||||
.index = &[_]u16{ 0, 9, 17 },
|
||||
};
|
||||
|
||||
const max_user = User{
|
||||
.uid = 0,
|
||||
.gid = math.maxInt(u32),
|
||||
.name = "Name" ** 8,
|
||||
.gecos = "realname" ** 255 ++ "realnam",
|
||||
.home = "Home" ** 16,
|
||||
.shell = "She.LllL" ** 32,
|
||||
};
|
||||
|
||||
test "max_user and max_str_len are consistent" {
|
||||
const total_len = max_user.name.len +
|
||||
max_user.gecos.len +
|
||||
max_user.home.len +
|
||||
max_user.shell.len;
|
||||
try testing.expectEqual(total_len, max_str_len);
|
||||
}
|
||||
|
||||
test "pack max_user" {
|
||||
var arr = ArrayList(u8).init(testing.allocator);
|
||||
defer arr.deinit();
|
||||
|
||||
var idx_noop = StringHashMap(u8).init(testing.allocator);
|
||||
defer idx_noop.deinit();
|
||||
|
||||
try packTo(&arr, max_user, 0, idx_noop);
|
||||
}
|
||||
|
||||
test "construct PackedUser section" {
|
||||
var buf = ArrayList(u8).init(testing.allocator);
|
||||
defer buf.deinit();
|
||||
@ -250,14 +282,7 @@ test "construct PackedUser section" {
|
||||
.gecos = "Service Account",
|
||||
.home = "/home/service1",
|
||||
.shell = "/usr/bin/nologin",
|
||||
}, User{
|
||||
.uid = 0,
|
||||
.gid = math.maxInt(u32),
|
||||
.name = "Name" ** 8,
|
||||
.gecos = "Gecos" ** 51,
|
||||
.home = "Home" ** 16,
|
||||
.shell = "She.LllL" ** 32,
|
||||
}, User{
|
||||
}, max_user, User{
|
||||
.uid = 1002,
|
||||
.gid = 1002,
|
||||
.name = "svc-bar",
|
||||
|
13
lib/User.zig
13
lib/User.zig
@ -1,6 +1,8 @@
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const Allocator = mem.Allocator;
|
||||
const ArrayList = std.ArrayList;
|
||||
const maxInt = std.math.maxInt;
|
||||
|
||||
const User = @This();
|
||||
|
||||
@ -48,6 +50,17 @@ pub fn deinit(self: *User, allocator: Allocator) void {
|
||||
self.* = undefined;
|
||||
}
|
||||
|
||||
pub fn fromReader(allocator: Allocator, reader: anytype) ![]User {
|
||||
var users = ArrayList(User).init(allocator);
|
||||
var scratch = ArrayList(u8).init(allocator);
|
||||
defer scratch.deinit();
|
||||
while (true) {
|
||||
const line = reader.readUntilDelimiterArrayList(&scratch, '\n', maxInt(usize));
|
||||
_ = line;
|
||||
}
|
||||
_ = users;
|
||||
}
|
||||
|
||||
const testing = std.testing;
|
||||
|
||||
test "User.clone" {
|
||||
|
Loading…
Reference in New Issue
Block a user