fix: preserve non-UTF-8 bytes in OS, config and CLI layers
Zig treats paths, arguments and environment values as byte slices; the port converted them lossily in many places. Now (final-Z1.md): - argv, env (incl. present non-UTF-8 values), HOME, PATH lookup, passwd, resources dir, TMPDIR, cgroup, config path canonicalization, +validate-config, +list-themes and Zig-string escapes (\xFF) keep raw bytes. String-based config values carry bytes via ghostty_os::osbytes, a bijective escape (noncharacter U+FDD0 + byte) that leaves all valid UTF-8 - including Nerd Font private-use icons - unchanged. - os/file rlimit fallbacks exist on all targets. - i18n locale canonicalization is an exact port of libintl's tables (e.g. pa-Guru -> pa_IN). - New ghostty-build-info crate is the single source of version, channel, commit and build mode for all consumers. Test Plan: - cargo test -p ghostty-os -p ghostty-config -p ghostty-cli (incl. randomized osbytes round-trip property tests)
This commit is contained in:
1 parent
e4cdd8e007
commit
395cff8981
32 files changed
+1464
-333
No files matched your search
@@ -235,10 +235,24 @@ pub fn prepend_env(current: &str, value: &str) -> String {
|
||||
format!("{value}{DELIMITER}{current}")
|
||||
}
|
||||
|
||||
/// Gets the value of an environment variable, or None if not found
|
||||
/// (or not valid unicode).
|
||||
/// Gets the raw value of an environment variable, or None if not found.
|
||||
/// A present value that is not valid UTF-8 is returned as-is (never treated
|
||||
/// as absent).
|
||||
pub fn getenv_os(key: &str) -> Option<OsString> {
|
||||
std::env::var_os(key)
|
||||
}
|
||||
|
||||
/// Gets the raw value of an environment variable. Returns None if not found
|
||||
/// or the value is empty.
|
||||
pub fn getenv_not_empty_os(key: &str) -> Option<OsString> {
|
||||
getenv_os(key).filter(|v| !v.is_empty())
|
||||
}
|
||||
|
||||
/// Gets the value of an environment variable, or None if not found. A
|
||||
/// non-UTF-8 value is still present: its invalid bytes are carried through
|
||||
/// the reversible [`crate::osbytes`] encoding.
|
||||
pub fn getenv(key: &str) -> Option<String> {
|
||||
std::env::var(key).ok()
|
||||
getenv_os(key).map(|v| crate::osbytes::os_to_config_string(&v))
|
||||
}
|
||||
|
||||
/// Gets the value of an environment variable. Returns None if not found or
|
||||
@@ -294,6 +308,19 @@ mod tests {
|
||||
assert_eq!(append_env("a:b", "foo"), format!("a:b{DELIMITER}foo"));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn getenv_non_utf8_is_present() {
|
||||
let v = OsString::from_vec(vec![b'a', 0xff]);
|
||||
temp_env::with_var("GHOSTTY_RS_T3", Some(&v), || {
|
||||
assert_eq!(getenv_os("GHOSTTY_RS_T3").unwrap(), v);
|
||||
assert_eq!(getenv_not_empty_os("GHOSTTY_RS_T3").unwrap(), v);
|
||||
let s = getenv("GHOSTTY_RS_T3").unwrap();
|
||||
assert_eq!(crate::osbytes::config_str_to_bytes(&s), vec![b'a', 0xff]);
|
||||
assert!(getenv_not_empty("GHOSTTY_RS_T3").is_some());
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn os_variants_preserve_bytes() {
|
||||
|
||||
Reference in new issue
Block a user