fix: systematic byte fidelity for config strings and RV7 gaps
Resolves the 9 gap groups in docs/rewrite/notes/review-rv7-codex.md and
audits every string-typed config field against its consumers
(field -> consumers -> decode status table in final-Z9.md):
- Windows EnvMap keys use a port of Zig's nls.zig uppercase table
(upcaseW); Windows locale init follows Zig's chain (setlocale +
_putenv_s); malformed WTF-8 now fails process launch conversions like
Zig instead of substituting U+FFFD; kitty file paths convert WTF-8.
- bash --rcfile/--init-file, configured TERM and inherited GTK LANG
keep their original bytes.
- C API clipboard completion and ghostty_surface_binding_action take
bytes; complete_clipboard_request is byte-typed through the core.
- text:/csi:/esc: bindings, enquiry-response, input = path:, embedded
initial_input, search needles, titles, link regexes, clipboard
codepoint map, command palette text and GTK font/namespace values
decode the escape encoding before use.
Remaining by design: D-Bus a{ss} values and +new-window arguments are
UTF-8 by D-Bus type. C API key/preedit text follows separately.
Test Plan:
- cargo test --workspace
- just check-macos (both), just check-windows, just check-wasm
This commit is contained in:
1 parent
ffc91c31e4
commit
af094276f8
40 files changed
+986
-167
No files matched your search
@@ -88,8 +88,9 @@ impl Surface {
|
||||
|
||||
// The options we'll use for all formatting. We'll just override the
|
||||
// emit format.
|
||||
let codepoint_map: Vec<formatter::CodepointMap> =
|
||||
cfg.clipboard_codepoint_map.map.list.clone();
|
||||
// Replacement strings are config strings (reversible byte encoding);
|
||||
// the formatter produces text, so decode them to UTF-8 text first.
|
||||
let codepoint_map = decode_codepoint_map(&cfg.clipboard_codepoint_map.map.list);
|
||||
let opts = formatter::Options {
|
||||
emit: Format::Plain, // We'll override this below
|
||||
unwrap: true,
|
||||
@@ -195,20 +196,20 @@ impl Surface {
|
||||
pub fn complete_clipboard_request(
|
||||
&self,
|
||||
req: ClipboardRequest,
|
||||
data: &str,
|
||||
data: &[u8],
|
||||
confirmed: bool,
|
||||
) -> Result<(), ClipboardError> {
|
||||
match req {
|
||||
ClipboardRequest::Paste => self.complete_clipboard_paste(data.as_bytes(), confirmed),
|
||||
ClipboardRequest::Paste => self.complete_clipboard_paste(data, confirmed),
|
||||
|
||||
ClipboardRequest::Osc52Read(clipboard) => {
|
||||
self.complete_clipboard_read_osc52(data.as_bytes(), clipboard, confirmed)
|
||||
self.complete_clipboard_read_osc52(data, clipboard, confirmed)
|
||||
}
|
||||
|
||||
ClipboardRequest::Osc52Write(clipboard) => {
|
||||
self.rt_surface.set_clipboard(
|
||||
clipboard,
|
||||
&[("text/plain".to_owned(), data.as_bytes().to_vec())],
|
||||
&[("text/plain".to_owned(), data.to_vec())],
|
||||
!confirmed,
|
||||
);
|
||||
Ok(())
|
||||
@@ -407,3 +408,40 @@ impl Surface {
|
||||
self.complete_clipboard_paste(text, true)
|
||||
}
|
||||
}
|
||||
|
||||
/// The clipboard codepoint map with string replacements decoded from the
|
||||
/// config encoding (a literal `U+FDD0` is restored; bytes that are not
|
||||
/// UTF-8 can't be represented in the formatter's text output).
|
||||
fn decode_codepoint_map(list: &[formatter::CodepointMap]) -> Vec<formatter::CodepointMap> {
|
||||
list.iter()
|
||||
.map(|e| formatter::CodepointMap {
|
||||
range: e.range,
|
||||
replacement: match &e.replacement {
|
||||
formatter::Replacement::String(s) => {
|
||||
formatter::Replacement::String(ghostty_os::osbytes::config_str_to_text(s))
|
||||
}
|
||||
r @ formatter::Replacement::Codepoint(_) => r.clone(),
|
||||
},
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod decode_map_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn string_replacements_are_decoded() {
|
||||
let enc = ghostty_os::osbytes::valid_str_to_config_string("a\u{fdd0}");
|
||||
assert_ne!(enc, "a\u{fdd0}");
|
||||
let list = [formatter::CodepointMap {
|
||||
range: [1, 2],
|
||||
replacement: formatter::Replacement::String(enc),
|
||||
}];
|
||||
let out = decode_codepoint_map(&list);
|
||||
assert_eq!(
|
||||
out[0].replacement,
|
||||
formatter::Replacement::String("a\u{fdd0}".to_owned())
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user