context: run commands in the C locale by default
Subprocesses inherit the session environment, so a translated host locale leaked into builds: perl-based packaging tools (dpkg-architecture, dpkg-parsechangelog, quilt, ...) warned about missing locale settings, change their output with the environment, and dpkg-buildpackage treats some of that output as data. Default every command to LANG=C and LC_ALL=C; a caller can still override explicitly through envs().
This commit is contained in:
+38
-1
@@ -243,12 +243,22 @@ impl Context {
|
||||
}
|
||||
|
||||
/// Make a command inside context
|
||||
///
|
||||
/// Build tooling must not inherit the session's locale: dpkg-family
|
||||
/// tools and perl-based packaging scripts change their output (and
|
||||
/// dpkg-buildpackage treats some of it as data) with the environment,
|
||||
/// and a translated or mixed locale leaks host state into builds. The
|
||||
/// C locale is the default; a caller can still override it by setting
|
||||
/// LANG/LC_ALL through [`ContextCommand::envs`] afterwards.
|
||||
pub fn command<S: AsRef<OsStr>>(&self, program: S) -> ContextCommand<'_> {
|
||||
ContextCommand {
|
||||
context: self,
|
||||
program: program.as_ref().to_string_lossy().to_string(),
|
||||
args: Vec::new(),
|
||||
env: Vec::new(),
|
||||
env: vec![
|
||||
("LANG".to_string(), "C".to_string()),
|
||||
("LC_ALL".to_string(), "C".to_string()),
|
||||
],
|
||||
cwd: None,
|
||||
sink: None,
|
||||
}
|
||||
@@ -530,4 +540,31 @@ mod endpoint_tests {
|
||||
let err = ContextConfig::from_endpoint("host:99999").unwrap_err();
|
||||
assert_eq!(err, "Invalid port number");
|
||||
}
|
||||
|
||||
/// Commands run in the C locale whatever the session environment
|
||||
/// carries: host locale variables must not leak into builds. An
|
||||
/// explicit caller override still wins.
|
||||
#[test]
|
||||
fn commands_default_to_the_c_locale() {
|
||||
let ctx = Context::new(ContextConfig::Local).unwrap();
|
||||
|
||||
let locale = ctx
|
||||
.command("sh")
|
||||
.arg("-c")
|
||||
.arg("printf '%s' \"${LC_ALL:-unset}:${LANG:-unset}\"")
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
assert_eq!(String::from_utf8_lossy(&locale), "C:C");
|
||||
|
||||
let locale = ctx
|
||||
.command("sh")
|
||||
.arg("-c")
|
||||
.arg("printf '%s' \"$LC_ALL\"")
|
||||
.env("LC_ALL", "C.UTF-8")
|
||||
.output()
|
||||
.unwrap()
|
||||
.stdout;
|
||||
assert_eq!(String::from_utf8_lossy(&locale), "C.UTF-8");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user