From 41fd2901944d0b3f3ccc16257f24c40a026ec5b5 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Thu, 29 Apr 2021 11:10:39 +0100 Subject: [PATCH] Escape trailing backslashes in build script env vars Fixes #710. --- cargo/cargo_build_script_runner/lib.rs | 17 +++++++++++++++-- test/build_env/src/build.rs | 1 + test/build_env/tests/cargo.rs | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cargo/cargo_build_script_runner/lib.rs b/cargo/cargo_build_script_runner/lib.rs index e6ef266b21..38f5bccb12 100644 --- a/cargo/cargo_build_script_runner/lib.rs +++ b/cargo/cargo_build_script_runner/lib.rs @@ -125,7 +125,7 @@ impl BuildScriptOutput { 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 @@ impl BuildScriptOutput { 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 @@ impl BuildScriptOutput { 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 6efc76b608..642b1d6f6a 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 1fea7334cc..6caca65cce 100644 --- a/test/build_env/tests/cargo.rs +++ b/test/build_env/tests/cargo.rs @@ -4,4 +4,5 @@ fn cargo_env_vars() { 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\\"); }