refactor(config): parse config values from raw bytes like Zig
Zig parses config values (cli/args.zig, Config.zig field parsers, config/string.zig) from raw byte slices, and each field type decides whether it requires UTF-8 (InvalidValue otherwise) or stores bytes. The port escape-encoded raw bytes into Strings at the line reader and let fields parse the escaped text, so fields could observe encoding artifacts; successive audits kept finding such leaks (RV5-RV8). Field parsers now receive the original bytes: text fields validate UTF-8 where Zig does, byte/path fields store bytes (EncodedOs/OsString). This resolves all 9 RV8 findings (docs/rewrite/notes/review-rv8-codex.md), each with a regression test: Windows path conversion fails with BadPathName instead of substituting U+FFFD; Windows process launch uses strict UTF-8 like Zig's Command; the WTF-8 decoder accepts paired- surrogate encodings like Zig; literal U+FDD0 Unicode key triggers; selection-word-chars and clipboard-codepoint-map reject invalid UTF-8; font style / codepoint-map family names use original bytes; C title actions forward bytes; D-Bus new-window/Flatpak conversions match Zig. Design, sweep and validation: docs/rewrite/notes/final-bytes-refactor.md. Also moves the bundled iTerm2-Color-Schemes license out of resources/themes/ so +list-themes no longer lists it as a theme (output is now byte-identical to Ghostty 1.3.1). Done by Codex (gpt-6-astra), reviewed and verified by the orchestrator. Test Plan: - cargo test --workspace --no-fail-fast (3428 passed, exit 0) - just check-macos (both), just check-windows, just check-wasm - +show-config --default --docs, +list-keybinds, +list-actions --docs, +list-themes --plain compared with /usr/bin/ghostty
This commit is contained in:
1 parent
70c250cf2d
commit
6f9b3129e1
100 files changed
+2310
-1054
No files matched your search
@@ -459,10 +459,7 @@ impl Surface {
|
||||
// don't leak GHOSTTY_LOG to any subprocesses
|
||||
env.remove("GHOSTTY_LOG");
|
||||
|
||||
let mut ecfg = exec::Config::new(
|
||||
env,
|
||||
ghostty_os::osbytes::EncodedOs::from_encoded(config.term.clone()),
|
||||
);
|
||||
let mut ecfg = exec::Config::new(env, config.term.clone());
|
||||
ecfg.command = command.clone();
|
||||
ecfg.env_override = config.env.clone();
|
||||
ecfg.shell_integration = config.shell_integration;
|
||||
@@ -607,7 +604,7 @@ impl Surface {
|
||||
rt_app.perform_action(
|
||||
Target::Surface(id),
|
||||
RtAction::SetTitle(SetTitle {
|
||||
title: ghostty_os::osbytes::config_str_to_text(title),
|
||||
title: title.clone(),
|
||||
}),
|
||||
);
|
||||
} else if config.xdg_terminal_exec
|
||||
@@ -620,7 +617,7 @@ impl Surface {
|
||||
rt_app.perform_action(
|
||||
Target::Surface(id),
|
||||
RtAction::SetTitle(SetTitle {
|
||||
title: ghostty_os::osbytes::config_str_to_text(&cmd.string()),
|
||||
title: ghostty_os::osbytes::EncodedOs::from_encoded(cmd.string()),
|
||||
}),
|
||||
);
|
||||
} else if let Some(cmd) = &command {
|
||||
@@ -636,7 +633,7 @@ impl Surface {
|
||||
rt_app.perform_action(
|
||||
Target::Surface(id),
|
||||
RtAction::SetTitle(SetTitle {
|
||||
title: ghostty_os::osbytes::config_str_to_text(first),
|
||||
title: first.clone(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -872,8 +869,8 @@ impl Surface {
|
||||
}
|
||||
|
||||
let end = buf.iter().position(|&b| b == 0).unwrap_or(buf.len());
|
||||
let title = String::from_utf8_lossy(&buf[..end]).into_owned();
|
||||
log::debug!("changing title \"{title}\"");
|
||||
let title = ghostty_os::osbytes::EncodedOs::from_bytes(&buf[..end]);
|
||||
log::debug!("changing title {title:?}");
|
||||
self.perform(RtAction::SetTitle(SetTitle { title }));
|
||||
}
|
||||
|
||||
@@ -885,11 +882,14 @@ impl Surface {
|
||||
|
||||
let title = self.rt_surface.get_title();
|
||||
let data = match style {
|
||||
ghostty_apprt::surface::ReportTitleStyle::Csi21T => {
|
||||
format!("\x1b]l{}\x1b\\", title.unwrap_or_default())
|
||||
}
|
||||
ghostty_apprt::surface::ReportTitleStyle::Csi21T => [
|
||||
b"\x1b]l".as_slice(),
|
||||
&title.unwrap_or_default().to_bytes(),
|
||||
b"\x1b\\",
|
||||
]
|
||||
.concat(),
|
||||
};
|
||||
self.queue_io(IoMessage::write_req(data.as_bytes()));
|
||||
self.queue_io(IoMessage::write_req(data.as_slice()));
|
||||
}
|
||||
|
||||
Message::ColorChange(change) => {
|
||||
@@ -1306,7 +1306,7 @@ impl Surface {
|
||||
// configured title.
|
||||
if let Some(title) = &config.title {
|
||||
self.perform(RtAction::SetTitle(SetTitle {
|
||||
title: ghostty_os::osbytes::config_str_to_text(title),
|
||||
title: title.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user