mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
std.Io.net.HostName: simplify validate logic (#30764)
Follow-up of efe649b13e
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30764
Reviewed-by: Andrew Kelley <andrew@ziglang.org>
Co-authored-by: Guillaume <guillaume.alabre@gmail.com>
Co-committed-by: Guillaume <guillaume.alabre@gmail.com>
This commit is contained in:
@@ -27,13 +27,9 @@ pub const ValidateError = error{
|
||||
/// Validates a hostname according to [RFC 1123](https://www.rfc-editor.org/rfc/rfc1123)
|
||||
pub fn validate(bytes: []const u8) ValidateError!void {
|
||||
if (bytes.len == 0) return error.InvalidHostName;
|
||||
if (bytes[0] == '.') return error.InvalidHostName;
|
||||
|
||||
// Ignore trailing dot (FQDN). It doesn't count toward our length.
|
||||
const end = if (bytes[bytes.len - 1] == '.') end: {
|
||||
if (bytes.len == 1) return error.InvalidHostName;
|
||||
break :end bytes.len - 1;
|
||||
} else bytes.len;
|
||||
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) return error.NameTooLong;
|
||||
@@ -44,19 +40,16 @@ pub fn validate(bytes: []const u8) ValidateError!void {
|
||||
// - 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_start: usize = 0;
|
||||
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[label_start])) return error.InvalidHostName;
|
||||
if (!std.ascii.isAlphanumeric(bytes[i - 1])) return error.InvalidHostName;
|
||||
|
||||
label_start = i + 1;
|
||||
label_len = 0;
|
||||
},
|
||||
'-' => {
|
||||
if (label_len == 0) return error.InvalidHostName;
|
||||
label_len += 1;
|
||||
},
|
||||
else => {
|
||||
@@ -68,7 +61,6 @@ pub fn validate(bytes: []const u8) ValidateError!void {
|
||||
|
||||
// Validate the final label
|
||||
if (label_len == 0 or label_len > 63) return error.InvalidHostName;
|
||||
if (!std.ascii.isAlphanumeric(bytes[label_start])) return error.InvalidHostName;
|
||||
if (!std.ascii.isAlphanumeric(bytes[end - 1])) return error.InvalidHostName;
|
||||
}
|
||||
|
||||
@@ -86,6 +78,7 @@ test validate {
|
||||
try validate("127.0.0.1"); // Also a valid hostname
|
||||
try validate("a" ** 63 ++ ".com"); // Label exactly 63 chars (valid)
|
||||
try validate("a." ** 127 ++ "a"); // Total length 255 (valid)
|
||||
try validate("a." ** 127 ++ "a."); // Total length 255 + trailing dot (valid)
|
||||
|
||||
// Invalid hostnames
|
||||
try std.testing.expectError(error.InvalidHostName, validate(""));
|
||||
@@ -94,12 +87,14 @@ test validate {
|
||||
try std.testing.expectError(error.InvalidHostName, validate("host..domain"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("-hostname"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("hostname-"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("hostname-.com"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("a.-.b"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("host_name.com"));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("."));
|
||||
try std.testing.expectError(error.InvalidHostName, validate(".."));
|
||||
try std.testing.expectError(error.InvalidHostName, validate("a" ** 64 ++ ".com")); // Label length 64 (too long)
|
||||
try std.testing.expectError(error.NameTooLong, validate("a." ** 127 ++ "ab")); // Total length 256 (too long)
|
||||
try std.testing.expectError(error.NameTooLong, validate("a." ** 127 ++ "ab.")); // Total length 256 + trailing dot (too long)
|
||||
}
|
||||
|
||||
pub fn init(bytes: []const u8) ValidateError!HostName {
|
||||
|
||||
Reference in New Issue
Block a user