pub fn validate(bytes: []const u8) ValidateError!void bytes: []const u8NameTooLongInvalidHostName50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87pub fn validate(bytes: []const u8) ValidateError!void {
if (bytes.len == 0) return error.InvalidHostName;
// Ignore trailing dot (FQDN).
const end = if (bytes[bytes.len - 1] == '.') bytes.len - 1 else bytes.len;
// The accepted maximum length of a hostname, including labels and dots.
if (end > max_len_without_root) return error.NameTooLong;
// Hostnames are divided into dot-separated "labels", which:
//
// - Start with a letter or digit
// - Can contain letters, digits, or hyphens
// - Must end with a letter or digit
// - Have a minimum of 1 character and a maximum of 63
var label_len: usize = 0;
for (bytes[0..end], 0..) |c, i| {
switch (c) {
'.' => {
if (label_len == 0 or label_len > 63) return error.InvalidHostName;
if (!std.ascii.isAlphanumeric(bytes[i - 1])) return error.InvalidHostName;
label_len = 0;
},
'-' => {
if (label_len == 0) return error.InvalidHostName;
label_len += 1;
},
else => {
if (!std.ascii.isAlphanumeric(c)) return error.InvalidHostName;
label_len += 1;
},
}
}
// Validate the final label
if (label_len == 0 or label_len > 63) return error.InvalidHostName;
if (!std.ascii.isAlphanumeric(bytes[end - 1])) return error.InvalidHostName;
}
Validates a hostname according to RFC 1123