Skip to content

Commit 0750a6f

Browse files
committed
Handle env var escaping
1 parent a6bf36e commit 0750a6f

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/cargo/core/compiler/fingerprint.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,11 +1980,14 @@ pub fn parse_rustc_dep_info(rustc_dep_info: &Path) -> CargoResult<RustcDepInfo>
19801980
let rest = &line[env_dep_prefix.len()..];
19811981
let mut parts = rest.splitn(2, '=');
19821982
let env_var = match parts.next() {
1983-
Some(s) => s.to_string(),
1983+
Some(s) => s,
19841984
None => continue,
19851985
};
1986-
let env_val = parts.next().map(|s| s.to_string());
1987-
ret.env.push((env_var, env_val));
1986+
let env_val = match parts.next() {
1987+
Some(s) => Some(unescape_env(s)?),
1988+
None => None,
1989+
};
1990+
ret.env.push((unescape_env(env_var)?, env_val));
19881991
} else if let Some(pos) = line.find(": ") {
19891992
if found_deps {
19901993
continue;
@@ -2005,5 +2008,27 @@ pub fn parse_rustc_dep_info(rustc_dep_info: &Path) -> CargoResult<RustcDepInfo>
20052008
}
20062009
}
20072010
}
2008-
Ok(ret)
2011+
return Ok(ret);
2012+
2013+
// rustc tries to fit env var names and values all on a single line, which
2014+
// means it needs to escape `\r` and `\n`. The escape syntax used is "\n"
2015+
// which means that `\` also needs to be escaped.
2016+
fn unescape_env(s: &str) -> CargoResult<String> {
2017+
let mut ret = String::with_capacity(s.len());
2018+
let mut chars = s.chars();
2019+
while let Some(c) = chars.next() {
2020+
if c != '\\' {
2021+
ret.push(c);
2022+
continue;
2023+
}
2024+
match chars.next() {
2025+
Some('\\') => ret.push('\\'),
2026+
Some('n') => ret.push('\n'),
2027+
Some('r') => ret.push('\r'),
2028+
Some(c) => bail!("unknown escape character `{}`", c),
2029+
None => bail!("unterminated escape character"),
2030+
}
2031+
}
2032+
Ok(ret)
2033+
}
20092034
}

tests/testsuite/freshness.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2493,6 +2493,7 @@ fn env_in_code_causes_rebuild() {
24932493
r#"
24942494
fn main() {
24952495
println!("{:?}", option_env!("FOO"));
2496+
println!("{:?}", option_env!("FOO\nBAR"));
24962497
}
24972498
"#,
24982499
)
@@ -2527,6 +2528,19 @@ fn env_in_code_causes_rebuild() {
25272528
.env_remove("FOO")
25282529
.with_stderr("[FINISHED][..]")
25292530
.run();
2531+
2532+
let interesting = " #!$\nabc\r\\\t\u{8}\r\n";
2533+
p.cargo("build").env("FOO", interesting).run();
2534+
p.cargo("build")
2535+
.env("FOO", interesting)
2536+
.with_stderr("[FINISHED][..]")
2537+
.run();
2538+
2539+
p.cargo("build").env("FOO\nBAR", interesting).run();
2540+
p.cargo("build")
2541+
.env("FOO\nBAR", interesting)
2542+
.with_stderr("[FINISHED][..]")
2543+
.run();
25302544
}
25312545

25322546
#[cargo_test]

0 commit comments

Comments
 (0)