Skip to content

Commit 229489e

Browse files
committed
Added invalid variable validation for build.buil-dir path templating.
This commit adds logic to check for unexpected variables in templated paths like `build.build-dir`. Cargo will error if it finds a variable that it does not know how to expand.
1 parent 76e5433 commit 229489e

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

src/cargo/util/context/mod.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,17 @@ impl GlobalContext {
681681
}),
682682
];
683683

684-
let path = val.resolve_templated_path(self, replacements);
684+
let path = val
685+
.resolve_templated_path(self, replacements)
686+
.map_err(|e| match e {
687+
path::ResolveTemplateError::UnexpectedVariable {
688+
variable,
689+
raw_template,
690+
} => anyhow!(
691+
"unexpected variable `{variable}` in build.build-dir path `{raw_template}`"
692+
),
693+
})?;
694+
685695
// Check if the target directory is set to an empty string in the config.toml file.
686696
if val.raw_value().is_empty() {
687697
bail!(

src/cargo/util/context/path.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{GlobalContext, StringList, Value};
2+
use regex::Regex;
23
use serde::{de::Error, Deserialize};
34
use std::path::PathBuf;
45

@@ -41,14 +42,23 @@ impl ConfigRelativePath {
4142
&self,
4243
gctx: &GlobalContext,
4344
replacements: impl IntoIterator<Item = (impl AsRef<str>, impl AsRef<str>)>,
44-
) -> PathBuf {
45+
) -> Result<PathBuf, ResolveTemplateError> {
4546
let mut value = self.0.val.clone();
4647

4748
for (from, to) in replacements {
4849
value = value.replace(from.as_ref(), to.as_ref());
4950
}
5051

51-
self.0.definition.root(gctx).join(&value)
52+
// Check for expected variables
53+
let re = Regex::new(r"\{(.*)\}").unwrap();
54+
if let Some(caps) = re.captures(&value) {
55+
return Err(ResolveTemplateError::UnexpectedVariable {
56+
variable: caps[1].to_string(),
57+
raw_template: self.0.val.clone(),
58+
});
59+
};
60+
61+
Ok(self.0.definition.root(gctx).join(&value))
5262
}
5363

5464
/// Resolves this configuration-relative path to either an absolute path or
@@ -122,3 +132,11 @@ impl PathAndArgs {
122132
}
123133
}
124134
}
135+
136+
#[derive(Debug)]
137+
pub enum ResolveTemplateError {
138+
UnexpectedVariable {
139+
variable: String,
140+
raw_template: String,
141+
},
142+
}

tests/testsuite/build_dir.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use std::path::PathBuf;
1313

1414
use cargo_test_support::prelude::*;
15-
use cargo_test_support::{paths, project};
15+
use cargo_test_support::{paths, project, str};
1616
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX, EXE_SUFFIX};
1717

1818
#[cargo_test]
@@ -508,6 +508,11 @@ fn template_should_error_for_invalid_variables() {
508508
p.cargo("build -Z build-dir")
509509
.masquerade_as_nightly_cargo(&["build-dir"])
510510
.enable_mac_dsym()
511+
.with_status(101)
512+
.with_stderr_data(str![[r#"
513+
[ERROR] unexpected variable `fake` in build.build-dir path `{fake}/build-dir`
514+
515+
"#]])
511516
.run();
512517
}
513518

0 commit comments

Comments
 (0)