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 Allocator = mem.Allocator;
|
||||||
const ArrayList = std.ArrayList;
|
const ArrayList = std.ArrayList;
|
||||||
const StringHashMap = std.StringHashMap;
|
const StringHashMap = std.StringHashMap;
|
||||||
|
const fieldInfo = std.meta.fieldInfo;
|
||||||
|
|
||||||
const pad = @import("padding.zig");
|
const pad = @import("padding.zig");
|
||||||
const validate = @import("validate.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 };
|
return Iterator{ .section = section, .shell_reader = shell_reader };
|
||||||
}
|
}
|
||||||
|
|
||||||
// packTo packs the User record and copies it to the given byte slice.
|
// packTo packs the User record and copies it to the given arraylist.
|
||||||
// The slice must have at least maxRecordSize() bytes available. The
|
|
||||||
// slice is passed as a pointer, so it can be mutated.
|
|
||||||
pub fn packTo(
|
pub fn packTo(
|
||||||
arr: *ArrayList(u8),
|
arr: *ArrayList(u8),
|
||||||
user: User,
|
user: User,
|
||||||
@ -141,10 +140,11 @@ pub fn packTo(
|
|||||||
std.debug.assert(arr.items.len & 7 == 0);
|
std.debug.assert(arr.items.len & 7 == 0);
|
||||||
// function arguments are consts. We need to mutate the underlying
|
// function arguments are consts. We need to mutate the underlying
|
||||||
// slice, so passing it via pointer instead.
|
// slice, so passing it via pointer instead.
|
||||||
const home_len = try validate.downCast(u6, user.home.len - 1);
|
//const home_len = try validate.downCast(u6, user.home.len - 1);
|
||||||
const name_len = try validate.downCast(u5, user.name.len - 1);
|
const home_len = try validate.downCast(fieldInfo(Inner, .home_len).field_type, user.home.len - 1);
|
||||||
const shell_len = try validate.downCast(u8, user.shell.len - 1);
|
const name_len = try validate.downCast(fieldInfo(Inner, .name_len).field_type, user.name.len - 1);
|
||||||
const gecos_len = try validate.downCast(u8, user.gecos.len);
|
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.home);
|
||||||
try validate.utf8(user.name);
|
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);
|
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;
|
const testing = std.testing;
|
||||||
|
|
||||||
test "PackedUser internal and external alignment" {
|
test "PackedUser internal and external alignment" {
|
||||||
@ -232,6 +237,33 @@ const test_shell_reader = shellImport.ShellReader{
|
|||||||
.index = &[_]u16{ 0, 9, 17 },
|
.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" {
|
test "construct PackedUser section" {
|
||||||
var buf = ArrayList(u8).init(testing.allocator);
|
var buf = ArrayList(u8).init(testing.allocator);
|
||||||
defer buf.deinit();
|
defer buf.deinit();
|
||||||
@ -250,14 +282,7 @@ test "construct PackedUser section" {
|
|||||||
.gecos = "Service Account",
|
.gecos = "Service Account",
|
||||||
.home = "/home/service1",
|
.home = "/home/service1",
|
||||||
.shell = "/usr/bin/nologin",
|
.shell = "/usr/bin/nologin",
|
||||||
}, User{
|
}, max_user, User{
|
||||||
.uid = 0,
|
|
||||||
.gid = math.maxInt(u32),
|
|
||||||
.name = "Name" ** 8,
|
|
||||||
.gecos = "Gecos" ** 51,
|
|
||||||
.home = "Home" ** 16,
|
|
||||||
.shell = "She.LllL" ** 32,
|
|
||||||
}, User{
|
|
||||||
.uid = 1002,
|
.uid = 1002,
|
||||||
.gid = 1002,
|
.gid = 1002,
|
||||||
.name = "svc-bar",
|
.name = "svc-bar",
|
||||||
|
13
lib/User.zig
13
lib/User.zig
@ -1,6 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
|
const ArrayList = std.ArrayList;
|
||||||
|
const maxInt = std.math.maxInt;
|
||||||
|
|
||||||
const User = @This();
|
const User = @This();
|
||||||
|
|
||||||
@ -48,6 +50,17 @@ pub fn deinit(self: *User, allocator: Allocator) void {
|
|||||||
self.* = undefined;
|
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;
|
const testing = std.testing;
|
||||||
|
|
||||||
test "User.clone" {
|
test "User.clone" {
|
||||||
|
Loading…
Reference in New Issue
Block a user