stylistic changes

This commit is contained in:
Mitchell Hashimoto
2024-11-05 10:30:48 -08:00
parent 9c2f260351
commit 4a263f43af
3 changed files with 53 additions and 49 deletions

View File

@ -1,22 +1,21 @@
const std = @import("std"); const std = @import("std");
const posix = std.posix; const posix = std.posix;
const HostnameParsingError = error{ pub const HostnameParsingError = error{
NoHostnameInUri, NoHostnameInUri,
NoSpaceLeft, NoSpaceLeft,
}; };
const LocalHostnameValidationError = error{ /// Print the hostname from a file URI into a buffer.
PermissionDenied, pub fn bufPrintHostnameFromFileUri(
Unexpected, buf: []u8,
}; uri: std.Uri,
) HostnameParsingError![]const u8 {
pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) HostnameParsingError![]const u8 {
// Get the raw string of the URI. Its unclear to me if the various // Get the raw string of the URI. Its unclear to me if the various
// tags of this enum guarantee no percent-encoding so we just // tags of this enum guarantee no percent-encoding so we just
// check all of it. This isn't a performance critical path. // check all of it. This isn't a performance critical path.
const host_component = uri.host orelse return HostnameParsingError.NoHostnameInUri; const host_component = uri.host orelse return error.NoHostnameInUri;
const host = switch (host_component) { const host: []const u8 = switch (host_component) {
.raw => |v| v, .raw => |v| v,
.percent_encoded => |v| v, .percent_encoded => |v| v,
}; };
@ -31,42 +30,42 @@ pub fn bufPrintHostnameFromFileUri(buf: []u8, uri: std.Uri) HostnameParsingError
// If that's not the case we just return the plain URI hostname directly. // If that's not the case we just return the plain URI hostname directly.
// NOTE: This implementation is not sufficient to verify a valid mac address, but // NOTE: This implementation is not sufficient to verify a valid mac address, but
// it's probably sufficient for this specific purpose. // it's probably sufficient for this specific purpose.
if (host.len != 14 or std.mem.count(u8, host, ":") != 4) { if (host.len != 14 or std.mem.count(u8, host, ":") != 4) return host;
return host;
}
if (uri.port) |port| { // If we don't have a port then we can return the hostname as-is because
// If the port is not a 2-digit number we're not looking at a partial MAC-address, // it's not a partial MAC-address.
// and instead just a regular port so we return the plain URI hostname. const port = uri.port orelse return host;
if (port < 10 or port > 99) {
return host;
}
var fbs = std.io.fixedBufferStream(buf); // If the port is not a 2-digit number we're not looking at a partial
std.fmt.format(fbs.writer().any(), "{s}:{d}", .{ host, port }) catch |err| switch (err) { // MAC-address, and instead just a regular port so we return the plain
error.NoSpaceLeft => return HostnameParsingError.NoSpaceLeft, // URI hostname.
else => unreachable, if (port < 10 or port > 99) return host;
};
return fbs.getWritten(); var fbs = std.io.fixedBufferStream(buf);
} try std.fmt.format(
fbs.writer(),
"{s}:{d}",
.{ host, port },
);
return host; return fbs.getWritten();
} }
pub const LocalHostnameValidationError = error{
PermissionDenied,
Unexpected,
};
/// Checks if a hostname is local to the current machine. This matches
/// both "localhost" and the current hostname of the machine (as returned
/// by `gethostname`).
pub fn isLocalHostname(hostname: []const u8) LocalHostnameValidationError!bool { pub fn isLocalHostname(hostname: []const u8) LocalHostnameValidationError!bool {
// A 'localhost' hostname is always considered local. // A 'localhost' hostname is always considered local.
if (std.mem.eql(u8, "localhost", hostname)) { if (std.mem.eql(u8, "localhost", hostname)) return true;
return true;
}
// If hostname is not "localhost" it must match our hostname. // If hostname is not "localhost" it must match our hostname.
var buf: [posix.HOST_NAME_MAX]u8 = undefined; var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const ourHostname = posix.gethostname(&buf) catch |err| switch (err) { const ourHostname = try posix.gethostname(&buf);
error.PermissionDenied => return LocalHostnameValidationError.PermissionDenied,
error.Unexpected => return LocalHostnameValidationError.Unexpected,
};
return std.mem.eql(u8, hostname, ourHostname); return std.mem.eql(u8, hostname, ourHostname);
} }
@ -75,7 +74,6 @@ test "bufPrintHostnameFromFileUri succeeds with ascii hostname" {
var buf: [posix.HOST_NAME_MAX]u8 = undefined; var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const actual = try bufPrintHostnameFromFileUri(&buf, uri); const actual = try bufPrintHostnameFromFileUri(&buf, uri);
try std.testing.expectEqualStrings("localhost", actual); try std.testing.expectEqualStrings("localhost", actual);
} }
@ -84,7 +82,6 @@ test "bufPrintHostnameFromFileUri succeeds with hostname as mac address" {
var buf: [posix.HOST_NAME_MAX]u8 = undefined; var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const actual = try bufPrintHostnameFromFileUri(&buf, uri); const actual = try bufPrintHostnameFromFileUri(&buf, uri);
try std.testing.expectEqualStrings("12:34:56:78:90:12", actual); try std.testing.expectEqualStrings("12:34:56:78:90:12", actual);
} }
@ -94,7 +91,6 @@ test "bufPrintHostnameFromFileUri returns only hostname when there is a port com
var four_port_buf: [posix.HOST_NAME_MAX]u8 = undefined; var four_port_buf: [posix.HOST_NAME_MAX]u8 = undefined;
const four_port_actual = try bufPrintHostnameFromFileUri(&four_port_buf, four_port_uri); const four_port_actual = try bufPrintHostnameFromFileUri(&four_port_buf, four_port_uri);
try std.testing.expectEqualStrings("has-a-port", four_port_actual); try std.testing.expectEqualStrings("has-a-port", four_port_actual);
// Second: try with a 2-digit port to test mac-address handling. // Second: try with a 2-digit port to test mac-address handling.
@ -102,7 +98,6 @@ test "bufPrintHostnameFromFileUri returns only hostname when there is a port com
var two_port_buf: [posix.HOST_NAME_MAX]u8 = undefined; var two_port_buf: [posix.HOST_NAME_MAX]u8 = undefined;
const two_port_actual = try bufPrintHostnameFromFileUri(&two_port_buf, two_port_uri); const two_port_actual = try bufPrintHostnameFromFileUri(&two_port_buf, two_port_uri);
try std.testing.expectEqualStrings("has-a-port", two_port_actual); try std.testing.expectEqualStrings("has-a-port", two_port_actual);
// Third: try with a mac-address that has a port-component added to it to test mac-address handling. // Third: try with a mac-address that has a port-component added to it to test mac-address handling.
@ -110,7 +105,6 @@ test "bufPrintHostnameFromFileUri returns only hostname when there is a port com
var mac_with_port_buf: [posix.HOST_NAME_MAX]u8 = undefined; var mac_with_port_buf: [posix.HOST_NAME_MAX]u8 = undefined;
const mac_with_port_actual = try bufPrintHostnameFromFileUri(&mac_with_port_buf, mac_with_port_uri); const mac_with_port_actual = try bufPrintHostnameFromFileUri(&mac_with_port_buf, mac_with_port_uri);
try std.testing.expectEqualStrings("12:34:56:78:90:12", mac_with_port_actual); try std.testing.expectEqualStrings("12:34:56:78:90:12", mac_with_port_actual);
} }
@ -119,7 +113,6 @@ test "bufPrintHostnameFromFileUri returns NoHostnameInUri error when hostname is
var buf: [posix.HOST_NAME_MAX]u8 = undefined; var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const actual = bufPrintHostnameFromFileUri(&buf, uri); const actual = bufPrintHostnameFromFileUri(&buf, uri);
try std.testing.expectError(HostnameParsingError.NoHostnameInUri, actual); try std.testing.expectError(HostnameParsingError.NoHostnameInUri, actual);
} }
@ -128,7 +121,6 @@ test "bufPrintHostnameFromFileUri returns NoSpaceLeft error when provided buffer
var buf: [5]u8 = undefined; var buf: [5]u8 = undefined;
const actual = bufPrintHostnameFromFileUri(&buf, uri); const actual = bufPrintHostnameFromFileUri(&buf, uri);
try std.testing.expectError(HostnameParsingError.NoSpaceLeft, actual); try std.testing.expectError(HostnameParsingError.NoSpaceLeft, actual);
} }
@ -139,10 +131,12 @@ test "isLocalHostname returns true when provided hostname is localhost" {
test "isLocalHostname returns true when hostname is local" { test "isLocalHostname returns true when hostname is local" {
var buf: [posix.HOST_NAME_MAX]u8 = undefined; var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const localHostname = try posix.gethostname(&buf); const localHostname = try posix.gethostname(&buf);
try std.testing.expect(try isLocalHostname(localHostname)); try std.testing.expect(try isLocalHostname(localHostname));
} }
test "isLocalHostname returns false when hostname is not local" { test "isLocalHostname returns false when hostname is not local" {
try std.testing.expectEqual(false, try isLocalHostname("not-the-local-hostname")); try std.testing.expectEqual(
false,
try isLocalHostname("not-the-local-hostname"),
);
} }

View File

@ -17,6 +17,7 @@ const resourcesdir = @import("resourcesdir.zig");
// Namespaces // Namespaces
pub const args = @import("args.zig"); pub const args = @import("args.zig");
pub const cgroup = @import("cgroup.zig"); pub const cgroup = @import("cgroup.zig");
pub const hostname = @import("hostname.zig");
pub const passwd = @import("passwd.zig"); pub const passwd = @import("passwd.zig");
pub const xdg = @import("xdg.zig"); pub const xdg = @import("xdg.zig");
pub const windows = @import("windows.zig"); pub const windows = @import("windows.zig");
@ -42,3 +43,7 @@ pub const clickInterval = mouse.clickInterval;
pub const open = openpkg.open; pub const open = openpkg.open;
pub const pipe = pipepkg.pipe; pub const pipe = pipepkg.pipe;
pub const resourcesDir = resourcesdir.resourcesDir; pub const resourcesDir = resourcesdir.resourcesDir;
test {
@import("std").testing.refAllDecls(@This());
}

View File

@ -5,7 +5,7 @@ const xev = @import("xev");
const apprt = @import("../apprt.zig"); const apprt = @import("../apprt.zig");
const build_config = @import("../build_config.zig"); const build_config = @import("../build_config.zig");
const configpkg = @import("../config.zig"); const configpkg = @import("../config.zig");
const hostname = @import("../os/hostname.zig"); const internal_os = @import("../os/main.zig");
const renderer = @import("../renderer.zig"); const renderer = @import("../renderer.zig");
const termio = @import("../termio.zig"); const termio = @import("../termio.zig");
const terminal = @import("../terminal/main.zig"); const terminal = @import("../terminal/main.zig");
@ -1055,8 +1055,10 @@ pub const StreamHandler = struct {
const PORT_NUMBER_MAX_DIGITS = 5; const PORT_NUMBER_MAX_DIGITS = 5;
// Make sure there is space for a max length hostname + the max number of digits. // Make sure there is space for a max length hostname + the max number of digits.
var host_and_port_buf: [posix.HOST_NAME_MAX + PORT_NUMBER_MAX_DIGITS]u8 = undefined; var host_and_port_buf: [posix.HOST_NAME_MAX + PORT_NUMBER_MAX_DIGITS]u8 = undefined;
const hostname_from_uri = internal_os.hostname.bufPrintHostnameFromFileUri(
const hostname_from_uri = hostname.bufPrintHostnameFromFileUri(&host_and_port_buf, uri) catch |err| switch (err) { &host_and_port_buf,
uri,
) catch |err| switch (err) {
error.NoHostnameInUri => { error.NoHostnameInUri => {
log.warn("OSC 7 uri must contain a hostname: {}", .{err}); log.warn("OSC 7 uri must contain a hostname: {}", .{err});
return; return;
@ -1070,13 +1072,16 @@ pub const StreamHandler = struct {
// OSC 7 is a little sketchy because anyone can send any value from // OSC 7 is a little sketchy because anyone can send any value from
// any host (such an SSH session). The best practice terminals follow // any host (such an SSH session). The best practice terminals follow
// is to valid the hostname to be local. // is to valid the hostname to be local.
const host_valid = hostname.isLocalHostname(hostname_from_uri) catch |err| switch (err) { const host_valid = internal_os.hostname.isLocalHostname(
error.PermissionDenied, error.Unexpected => { hostname_from_uri,
) catch |err| switch (err) {
error.PermissionDenied,
error.Unexpected,
=> {
log.warn("failed to get hostname for OSC 7 validation: {}", .{err}); log.warn("failed to get hostname for OSC 7 validation: {}", .{err});
return; return;
}, },
}; };
if (!host_valid) { if (!host_valid) {
log.warn("OSC 7 host must be local", .{}); log.warn("OSC 7 host must be local", .{});
return; return;