name validation
This commit is contained in:
parent
b703eeb37c
commit
942c05f348
@ -76,10 +76,32 @@ pub fn iterator(self: *const ErrCtx) mem.SplitIterator(u8) {
|
|||||||
|
|
||||||
pub fn rev(self: *const ErrCtx) SplitIteratorRev(u8) {
|
pub fn rev(self: *const ErrCtx) SplitIteratorRev(u8) {
|
||||||
const slice = self.buf.constSlice();
|
const slice = self.buf.constSlice();
|
||||||
|
if (slice.len == 0) {
|
||||||
|
return SplitIteratorRev(u8){
|
||||||
|
.buffer = slice,
|
||||||
|
.index = null,
|
||||||
|
.delimiter = "\x00",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const last_byte = if (slice[slice.len - 1] == 0) (slice.len - 1) else slice.len;
|
const last_byte = if (slice[slice.len - 1] == 0) (slice.len - 1) else slice.len;
|
||||||
return splitRev(u8, slice[0..last_byte], "\x00");
|
return splitRev(u8, slice[0..last_byte], "\x00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap(self: *const ErrCtx) BoundedArray(u8, capacity * 2) {
|
||||||
|
var result = BoundedArray(u8, capacity * 2).init(0) catch unreachable;
|
||||||
|
var wr = result.writer();
|
||||||
|
|
||||||
|
var it = self.rev();
|
||||||
|
if (it.next()) |msg| {
|
||||||
|
wr.print("{s}", .{msg}) catch unreachable;
|
||||||
|
} else return result;
|
||||||
|
|
||||||
|
while (it.next()) |msg|
|
||||||
|
wr.print(": {s}", .{msg}) catch unreachable;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
|
|
||||||
test "basics" {
|
test "basics" {
|
||||||
|
19
src/User.zig
19
src/User.zig
@ -177,6 +177,7 @@ pub const max_user = User{
|
|||||||
const from_line_examples = [_]struct {
|
const from_line_examples = [_]struct {
|
||||||
line: []const u8,
|
line: []const u8,
|
||||||
want: error{InvalidUser}!User,
|
want: error{InvalidUser}!User,
|
||||||
|
wantErrStr: []const u8 = &[_]u8{},
|
||||||
}{
|
}{
|
||||||
.{
|
.{
|
||||||
.line = "root:x:0:0:root:/root:/bin/bash",
|
.line = "root:x:0:0:root:/root:/bin/bash",
|
||||||
@ -189,12 +190,19 @@ const from_line_examples = [_]struct {
|
|||||||
.shell = "/bin/bash",
|
.shell = "/bin/bash",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.{
|
||||||
|
.line = "\x00emas:x:0:0:root:/root:/bin/bash",
|
||||||
|
.want = error.InvalidUser,
|
||||||
|
.wantErrStr = "foobar",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
test "User.fromLine" {
|
test "User.fromLine" {
|
||||||
|
if (true) return error.SkipZigTest;
|
||||||
const allocator = testing.allocator;
|
const allocator = testing.allocator;
|
||||||
var err_ctx = ErrCtx{};
|
|
||||||
for (from_line_examples) |tt| {
|
for (from_line_examples) |tt| {
|
||||||
|
var err_ctx = ErrCtx{};
|
||||||
|
|
||||||
if (tt.want) |want_user| {
|
if (tt.want) |want_user| {
|
||||||
var got = try fromLine(allocator, &err_ctx, tt.line);
|
var got = try fromLine(allocator, &err_ctx, tt.line);
|
||||||
defer got.deinit(allocator);
|
defer got.deinit(allocator);
|
||||||
@ -205,7 +213,14 @@ test "User.fromLine" {
|
|||||||
try testing.expectEqualStrings(want_user.home, got.home);
|
try testing.expectEqualStrings(want_user.home, got.home);
|
||||||
try testing.expectEqualStrings(want_user.shell, got.shell);
|
try testing.expectEqualStrings(want_user.shell, got.shell);
|
||||||
} else |want_err| {
|
} else |want_err| {
|
||||||
try testing.expectError(want_err, fromLine(allocator, &err_ctx, tt.line));
|
try testing.expectError(
|
||||||
|
want_err,
|
||||||
|
fromLine(allocator, &err_ctx, tt.line),
|
||||||
|
);
|
||||||
|
try testing.expectEqualStrings(
|
||||||
|
tt.wantErrStr,
|
||||||
|
err_ctx.unwrap().constSlice(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const ascii = std.ascii;
|
||||||
|
|
||||||
|
const ErrCtx = @import("ErrCtx.zig");
|
||||||
|
|
||||||
pub fn downCast(comptime T: type, n: u64) error{InvalidRecord}!T {
|
pub fn downCast(comptime T: type, n: u64) error{InvalidRecord}!T {
|
||||||
return std.math.cast(T, n) orelse return error.InvalidRecord;
|
return std.math.cast(T, n) orelse return error.InvalidRecord;
|
||||||
@ -9,3 +12,65 @@ pub fn utf8(s: []const u8) error{InvalidRecord}!void {
|
|||||||
return error.InvalidRecord;
|
return error.InvalidRecord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// # adduser žmogus
|
||||||
|
// adduser: To avoid problems, the username should consist only of letters,
|
||||||
|
// digits, underscores, periods, at signs and dashes, and not start with a dash
|
||||||
|
// (as defined by IEEE Std 1003.1-2001). For compatibility with Samba machine
|
||||||
|
// accounts $ is also supported at the end of the username
|
||||||
|
pub fn name(s: []const u8, err: *ErrCtx) error{InvalidRecord}!void {
|
||||||
|
if (s.len == 0)
|
||||||
|
return err.returnf("cannot be empty", .{}, error.InvalidRecord);
|
||||||
|
|
||||||
|
const c0 = s[0];
|
||||||
|
if (!(ascii.isAlNum(c0) or c0 == '_' or c0 == '.' or c0 == '@'))
|
||||||
|
return err.returnf("invalid character at position 0", .{}, error.InvalidRecord);
|
||||||
|
|
||||||
|
for (s[1..]) |c, i| {
|
||||||
|
if (!(ascii.isAlNum(c) or c == '_' or c == '.' or c == '@' or c == '-'))
|
||||||
|
return err.returnf(
|
||||||
|
"invalid character at position {d}",
|
||||||
|
.{i + 2},
|
||||||
|
error.InvalidRecord,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const testing = std.testing;
|
||||||
|
|
||||||
|
test "validate name" {
|
||||||
|
const examples = [_]struct {
|
||||||
|
name: []const u8,
|
||||||
|
wantErr: ?[]const u8 = null,
|
||||||
|
}{
|
||||||
|
.{
|
||||||
|
.name = "all-good",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.name = "...",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.name = "",
|
||||||
|
.wantErr = "cannot be empty",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.name = "-no-start-dash",
|
||||||
|
.wantErr = "invalid character at position 0",
|
||||||
|
},
|
||||||
|
.{
|
||||||
|
.name = "Herbasž",
|
||||||
|
.wantErr = "invalid character at position 7",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
for (examples) |tt| {
|
||||||
|
var err = ErrCtx{};
|
||||||
|
|
||||||
|
if (tt.wantErr) |wantErr| {
|
||||||
|
try testing.expectError(error.InvalidRecord, name(tt.name, &err));
|
||||||
|
try testing.expectEqualStrings(wantErr, err.unwrap().constSlice());
|
||||||
|
} else {
|
||||||
|
try name(tt.name, &err);
|
||||||
|
try testing.expectEqualStrings("", err.unwrap().constSlice());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user