mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-05 19:08:17 +00:00
pwd: fix hostname resolution on macos
When macOS's "Private WiFi address" feature is enabled it'll change the hostname to a mac address. Mac addresses look like URIs with a hostname and port component, e.g. 12:34:56:78:90:12 where `:12` looks like port 12. However, mac addresses can also contain letters a through f, so a valid mac address like ab💿ef🆎cd:ef is valid, but will not be parsed as a URI, because `:ef` is not a valid port. This commit attempts to fix that by checking if the hostname is a valid mac address when `std.Uri.parse()` fails and constructing a new std.Uri struct using that information. It's not perfect, but is equally compliant with the URI spec as std.Uri currently is.
This commit is contained in:
@@ -1041,6 +1041,13 @@ pub const StreamHandler = struct {
|
||||
self.terminal.markSemanticPrompt(.command);
|
||||
}
|
||||
|
||||
fn isUriPathSeparator(c: u8) bool {
|
||||
return switch (c) {
|
||||
'?', '#' => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn reportPwd(self: *StreamHandler, url: []const u8) !void {
|
||||
// Special handling for the empty URL. We treat the empty URL
|
||||
// as resetting the pwd as if we never saw a pwd. I can't find any
|
||||
@@ -1069,9 +1076,62 @@ pub const StreamHandler = struct {
|
||||
return;
|
||||
}
|
||||
|
||||
const uri = std.Uri.parse(url) catch |e| {
|
||||
log.warn("invalid url in OSC 7: {}", .{e});
|
||||
return;
|
||||
const uri: std.Uri = uri: {
|
||||
const uri = std.Uri.parse(url) catch |e| {
|
||||
// It's possible this is a mac address on macOS where the last 2 characters in the
|
||||
// address are non-digits, e.g. 'ff', and thus an invalid port.
|
||||
//
|
||||
// Example: file://12:34:56:78:90:12/path/to/file
|
||||
|
||||
// Insufficient length to have a mac address in the hostname.
|
||||
if (url.len < 24) {
|
||||
log.warn("invalid url in OSC 7: {}", .{e});
|
||||
return;
|
||||
}
|
||||
|
||||
// The first '/' after the scheme marks the end of the hostname. If the hostname is
|
||||
// not 17 characters, it's not a mac address.
|
||||
if (std.mem.indexOfScalarPos(u8, url, 7, '/') != 24) {
|
||||
log.warn("invalid url in OSC 7: {}", .{e});
|
||||
return;
|
||||
}
|
||||
|
||||
// At this point we have a potential mac address as the hostname.
|
||||
const mac_address = url[7..24];
|
||||
|
||||
for (0..mac_address.len) |i| {
|
||||
const c = mac_address[i];
|
||||
|
||||
if (i + 1 % 3 == 0) {
|
||||
if (c != ':') {
|
||||
log.warn("invalid url in OSC 7: {}", .{e});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!std.mem.containsAtLeastScalar(u8, "0123456789abcdef", 1, mac_address[i])) {
|
||||
log.warn("invalid url in OSC 7: {}", .{e});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we have what looks like a valid mac address.
|
||||
|
||||
var uri_path_end_idx: usize = 24;
|
||||
while (uri_path_end_idx < url.len and !isUriPathSeparator(url[uri_path_end_idx])) {
|
||||
uri_path_end_idx += 1;
|
||||
}
|
||||
|
||||
// Same compliance factor as std.Uri.parse(), i.e. not at all compliant with the URI
|
||||
// spec.
|
||||
break :uri .{
|
||||
.scheme = "file://",
|
||||
.host = .{ .percent_encoded = mac_address },
|
||||
.path = .{ .percent_encoded = url[24..uri_path_end_idx] },
|
||||
};
|
||||
};
|
||||
|
||||
break :uri uri;
|
||||
};
|
||||
|
||||
if (!std.mem.eql(u8, "file", uri.scheme) and
|
||||
|
Reference in New Issue
Block a user