handle duplicate gid
This commit is contained in:
parent
e6b9d43646
commit
eaccd00960
|
@ -5,6 +5,7 @@ const sort = std.sort;
|
|||
const unicode = std.unicode;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const ArenaAllocator = std.heap.ArenaAllocator;
|
||||
const AutoHashMap = std.AutoHashMap;
|
||||
const StringHashMap = std.StringHashMap;
|
||||
const MultiArrayList = std.MultiArrayList;
|
||||
const ArrayListUnmanaged = std.ArrayListUnmanaged;
|
||||
|
@ -69,20 +70,43 @@ pub fn init(
|
|||
for (groups_arr) |group|
|
||||
groups.appendAssumeCapacity(group);
|
||||
|
||||
// verify whatever comes to cmph are unique: user names
|
||||
var name2user = StringHashMap(u32).init(allocator);
|
||||
var name2group = StringHashMap(u32).init(allocator);
|
||||
for (users.items(.name)) |name, i| {
|
||||
var res1 = try name2user.getOrPut(name);
|
||||
if (res1.found_existing)
|
||||
var result = try name2user.getOrPut(name);
|
||||
if (result.found_existing)
|
||||
return error.Duplicate;
|
||||
res1.value_ptr.* = @intCast(u32, i);
|
||||
result.value_ptr.* = @intCast(u32, i);
|
||||
}
|
||||
// verify whatever comes to cmph are unique: group names
|
||||
var name2group = StringHashMap(u32).init(allocator);
|
||||
for (groups.items(.name)) |name, i| {
|
||||
var result = try name2group.getOrPut(name);
|
||||
if (result.found_existing)
|
||||
return error.Duplicate;
|
||||
result.value_ptr.* = @intCast(u32, i);
|
||||
}
|
||||
|
||||
for (groups.items(.name)) |name, i| {
|
||||
var res1 = try name2group.getOrPut(name);
|
||||
if (res1.found_existing)
|
||||
return error.Duplicate;
|
||||
res1.value_ptr.* = @intCast(u32, i);
|
||||
// verify whatever comes to cmph are unique: gids
|
||||
{
|
||||
const gids = groups.items(.gid);
|
||||
var last_gid = gids[0];
|
||||
for (gids[1..]) |gid| {
|
||||
if (gid == last_gid)
|
||||
return err.returnf("duplicate gid {d}", .{gid}, error.Duplicate);
|
||||
last_gid = gid;
|
||||
}
|
||||
}
|
||||
|
||||
// verify whatever comes to cmph are unique: uids
|
||||
{
|
||||
var uid_map = AutoHashMap(u32, void).init(allocator);
|
||||
defer uid_map.deinit();
|
||||
for (users.items(.uid)) |uid| {
|
||||
const result = try uid_map.getOrPut(uid);
|
||||
if (result.found_existing)
|
||||
return err.returnf("duplicate uid {d}", .{uid}, error.Duplicate);
|
||||
}
|
||||
}
|
||||
|
||||
var group2users = try allocator.alloc([]u32, groups.len);
|
||||
|
@ -236,9 +260,9 @@ pub fn testCorpus(allocator: Allocator) !Corpus {
|
|||
|
||||
const groups = [_]Group{ group0, group1, group2, group3 };
|
||||
|
||||
var err_ctx = ErrCtx{};
|
||||
const result = try Corpus.init(allocator, users[0..], groups[0..], &err_ctx);
|
||||
try testing.expectEqualStrings("", err_ctx.unwrap().constSlice());
|
||||
var errc = ErrCtx{};
|
||||
const result = try Corpus.init(allocator, users[0..], groups[0..], &errc);
|
||||
try testing.expectEqualStrings("", errc.unwrap().constSlice());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
16
src/DB.zig
16
src/DB.zig
|
@ -10,6 +10,7 @@ const ArrayList = std.ArrayList;
|
|||
const AutoHashMap = std.AutoHashMap;
|
||||
const BoundedArray = std.BoundedArray;
|
||||
|
||||
const ErrCtx = @import("ErrCtx.zig");
|
||||
const Corpus = @import("Corpus.zig");
|
||||
const pad = @import("padding.zig");
|
||||
const compress = @import("compress.zig");
|
||||
|
@ -54,7 +55,10 @@ additional_gids: []const u8,
|
|||
pub fn fromCorpus(
|
||||
allocator: Allocator,
|
||||
corpus: *const Corpus,
|
||||
err: *ErrCtx,
|
||||
) error{ OutOfMemory, InvalidRecord, TooMany }!DB {
|
||||
_ = err;
|
||||
|
||||
const gids = corpus.groups.items(.gid);
|
||||
const gnames = corpus.groups.items(.name);
|
||||
const uids = corpus.users.items(.uid);
|
||||
|
@ -630,7 +634,8 @@ test "read/write via iovec" {
|
|||
var corpus = try Corpus.testCorpus(allocator);
|
||||
defer corpus.deinit();
|
||||
|
||||
var db = try DB.fromCorpus(allocator, &corpus);
|
||||
var errc = ErrCtx{};
|
||||
var db = try DB.fromCorpus(allocator, &corpus, &errc);
|
||||
defer db.deinit(allocator);
|
||||
|
||||
const fd = try os.memfd_create("test_turbonss_db", 0);
|
||||
|
@ -648,12 +653,14 @@ test "read/write via iovec" {
|
|||
|
||||
try testing.expectEqualSlices(u32, db.idx_gid2group, db2.idx_gid2group[0..num_groups]);
|
||||
try testing.expectEqualSlices(u32, db.idx_uid2user, db2.idx_uid2user[0..num_users]);
|
||||
try testing.expectEqualStrings("", errc.unwrap().constSlice());
|
||||
}
|
||||
|
||||
test "getgrnam/getgrgid" {
|
||||
var corpus = try Corpus.testCorpus(testing.allocator);
|
||||
defer corpus.deinit();
|
||||
var db = try DB.fromCorpus(testing.allocator, &corpus);
|
||||
var errc = ErrCtx{};
|
||||
var db = try DB.fromCorpus(testing.allocator, &corpus, &errc);
|
||||
defer db.deinit(testing.allocator);
|
||||
var buf = try testing.allocator.alloc(u8, db.getgrBufsize());
|
||||
defer testing.allocator.free(buf);
|
||||
|
@ -677,6 +684,7 @@ test "getgrnam/getgrgid" {
|
|||
try testing.expectEqual(all.gid, 9999);
|
||||
try testing.expectEqualStrings(all.name[0..3], "all");
|
||||
}
|
||||
try testing.expectEqualStrings("", errc.unwrap().constSlice());
|
||||
|
||||
_ = try db.getgrnam("all", buf);
|
||||
buf.len -= 1;
|
||||
|
@ -686,7 +694,8 @@ test "getgrnam/getgrgid" {
|
|||
test "getpwnam/getpwuid" {
|
||||
var corpus = try Corpus.testCorpus(testing.allocator);
|
||||
defer corpus.deinit();
|
||||
var db = try DB.fromCorpus(testing.allocator, &corpus);
|
||||
var errc = ErrCtx{};
|
||||
var db = try DB.fromCorpus(testing.allocator, &corpus, &errc);
|
||||
defer db.deinit(testing.allocator);
|
||||
var buf = try testing.allocator.alloc(u8, db.getpwBufsize());
|
||||
defer testing.allocator.free(buf);
|
||||
|
@ -708,6 +717,7 @@ test "getpwnam/getpwuid" {
|
|||
try testing.expectEqual(vidmantas.pw_gid, 128);
|
||||
try testing.expectEqualStrings(vidmantas.pw_name[0..10], "vidmantas\x00");
|
||||
}
|
||||
try testing.expectEqualStrings("", errc.unwrap().constSlice());
|
||||
|
||||
const long = try db.getpwnam("Name" ** 8, buf);
|
||||
try testing.expectEqualStrings(long.?.pw_name[0..33], "Name" ** 8 ++ "\x00");
|
||||
|
|
|
@ -5,6 +5,7 @@ const Allocator = std.mem.Allocator;
|
|||
|
||||
const Corpus = @import("Corpus.zig");
|
||||
const DB = @import("DB.zig");
|
||||
const ErrCtx = @import("ErrCtx.zig");
|
||||
const InvalidHeader = @import("header.zig").Invalid;
|
||||
|
||||
const File = @This();
|
||||
|
@ -42,11 +43,11 @@ pub const TestDB = struct {
|
|||
dir: testing.TmpDir,
|
||||
path: [:0]const u8,
|
||||
|
||||
pub fn init(allocator: Allocator) !TestDB {
|
||||
pub fn init(allocator: Allocator, errc: *ErrCtx) !TestDB {
|
||||
var corpus = try Corpus.testCorpus(allocator);
|
||||
defer corpus.deinit();
|
||||
|
||||
var db = try DB.fromCorpus(allocator, &corpus);
|
||||
var db = try DB.fromCorpus(allocator, &corpus, errc);
|
||||
defer db.deinit(allocator);
|
||||
|
||||
var tmp = testing.tmpDir(.{});
|
||||
|
|
|
@ -6,6 +6,7 @@ const process = std.process;
|
|||
|
||||
const DB = @import("DB.zig");
|
||||
const File = @import("File.zig");
|
||||
const ErrCtx = @import("ErrCtx.zig");
|
||||
const CGroup = @import("Group.zig").CGroup;
|
||||
const PackedGroup = @import("PackedGroup.zig");
|
||||
const CUser = @import("User.zig").CUser;
|
||||
|
@ -131,7 +132,8 @@ export fn _nss_turbo_getpwuid_r(
|
|||
const testing = std.testing;
|
||||
|
||||
test "nss_turbo_getpwuid_r" {
|
||||
var tf = try File.TestDB.init(testing.allocator);
|
||||
var errc = ErrCtx{};
|
||||
var tf = try File.TestDB.init(testing.allocator, &errc);
|
||||
defer tf.deinit();
|
||||
|
||||
var env = try process.getEnvMap(testing.allocator);
|
||||
|
|
|
@ -97,8 +97,8 @@ fn execute(
|
|||
return fail(errc.wrap("init corpus"), stderr, err);
|
||||
|
||||
defer corpus.deinit();
|
||||
var db = DB.fromCorpus(allocator, &corpus) catch |err|
|
||||
return fail(errc.wrap("construct db from corpus"), stderr, err);
|
||||
var db = DB.fromCorpus(allocator, &corpus, &errc) catch |err|
|
||||
return fail(errc.wrap("construct DB from corpus"), stderr, err);
|
||||
defer db.deinit(allocator);
|
||||
|
||||
const fd = os.open(outFile, os.O.WRONLY | os.O.TRUNC | os.O.CREAT, 0644) catch |err|
|
||||
|
|
Loading…
Reference in New Issue