Escape trailing backslashes in build script env vars (#714)
Fixes #710.
diff --git a/cargo/cargo_build_script_runner/lib.rs b/cargo/cargo_build_script_runner/lib.rs
index e6ef266..38f5bcc 100644
--- a/cargo/cargo_build_script_runner/lib.rs
+++ b/cargo/cargo_build_script_runner/lib.rs
@@ -125,7 +125,7 @@
v.iter()
.filter_map(|x| {
if let BuildScriptOutput::Env(env) = x {
- Some(Self::redact_exec_root(env, exec_root))
+ Some(Self::escape_for_serializing(Self::redact_exec_root(env, exec_root)))
} else {
None
}
@@ -143,7 +143,7 @@
Some(format!(
"{}{}",
prefix,
- Self::redact_exec_root(env, exec_root)
+ Self::escape_for_serializing(Self::redact_exec_root(env, exec_root))
))
} else {
None
@@ -176,6 +176,19 @@
fn redact_exec_root(value: &str, exec_root: &str) -> String {
value.replace(exec_root, "${pwd}")
}
+
+ // The process-wrapper treats trailing backslashes as escapes for following newlines.
+ // If the env var ends with a backslash (and accordingly doesn't have a following newline),
+ // escape it so that it doesn't get turned into a newline by the process-wrapper.
+ //
+ // Note that this code doesn't handle newlines in strings - that's because Cargo treats build
+ // script output as single-line-oriented, so stops processing at the end of a line regardless.
+ fn escape_for_serializing(mut value: String) -> String {
+ if value.ends_with('\\') {
+ value.push('\\');
+ }
+ value
+ }
}
#[cfg(test)]
diff --git a/test/build_env/src/build.rs b/test/build_env/src/build.rs
index 6efc76b..642b1d6 100644
--- a/test/build_env/src/build.rs
+++ b/test/build_env/src/build.rs
@@ -1,4 +1,5 @@
fn main() {
println!("cargo:rustc-env=CARGO_PKG_NAME_FROM_BUILD_SCRIPT={}", env!("CARGO_PKG_NAME"));
println!("cargo:rustc-env=CARGO_CRATE_NAME_FROM_BUILD_SCRIPT={}", env!("CARGO_CRATE_NAME"));
+ println!("cargo:rustc-env=HAS_TRAILING_SLASH=foo\\");
}
diff --git a/test/build_env/tests/cargo.rs b/test/build_env/tests/cargo.rs
index 1fea733..6caca65 100644
--- a/test/build_env/tests/cargo.rs
+++ b/test/build_env/tests/cargo.rs
@@ -4,4 +4,5 @@
assert_eq!(env!("CARGO_CRATE_NAME"), "cargo_env_vars_test");
assert_eq!(env!("CARGO_PKG_NAME_FROM_BUILD_SCRIPT"), "cargo_build_script_env-vars");
assert_eq!(env!("CARGO_CRATE_NAME_FROM_BUILD_SCRIPT"), "cargo_build_script_env_vars");
+ assert_eq!(env!("HAS_TRAILING_SLASH"), "foo\\");
}