Skip to content

Commit ecfabe6

Browse files
committed
Auto merge of #9164 - ehuss:config-search-stop, r=Eh2406
Prevent testsuite from loading config out of sandbox. This adds a limit to prevent config loading from walking outside of the test sandbox root. There was an environment variable for this, but that doesn't work too well for tests that were loading the config directly. Fixes #9107
2 parents ab64d13 + 9cb8f41 commit ecfabe6

File tree

7 files changed

+25
-8
lines changed

7 files changed

+25
-8
lines changed

src/bin/cargo/commands/install.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
7878
if let Some(path) = args.value_of_path("path", config) {
7979
config.reload_rooted_at(path)?;
8080
} else {
81+
// TODO: Consider calling set_search_stop_path(home).
8182
config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
8283
}
8384

src/cargo/core/workspace.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ impl<'cfg> Workspace<'cfg> {
461461
}
462462
}
463463

464-
for path in paths::ancestors(manifest_path).skip(2) {
464+
for path in paths::ancestors(manifest_path, None).skip(2) {
465465
if path.ends_with("target/package") {
466466
break;
467467
}

src/cargo/ops/cargo_new.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ fn find_tests_git_config(path: &Path) -> Option<GitConfig> {
872872
// Don't escape the test sandbox when looking for a git repository.
873873
// NOTE: libgit2 has support to define the path ceiling in
874874
// git_repository_discover, but the git2 bindings do not expose that.
875-
for path in paths::ancestors(path) {
875+
for path in paths::ancestors(path, None) {
876876
if let Ok(repo) = GitRepository::open(path) {
877877
return Some(repo.config().expect("test repo should have valid config"));
878878
}

src/cargo/util/config/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ pub struct Config {
132132
cli_config: Option<Vec<String>>,
133133
/// The current working directory of cargo
134134
cwd: PathBuf,
135+
/// Directory where config file searching should stop (inclusive).
136+
search_stop_path: Option<PathBuf>,
135137
/// The location of the cargo executable (path to current process)
136138
cargo_exe: LazyCell<PathBuf>,
137139
/// The location of the rustdoc executable
@@ -218,6 +220,7 @@ impl Config {
218220
home_path: Filesystem::new(homedir),
219221
shell: RefCell::new(shell),
220222
cwd,
223+
search_stop_path: None,
221224
values: LazyCell::new(),
222225
cli_config: None,
223226
cargo_exe: LazyCell::new(),
@@ -422,6 +425,14 @@ impl Config {
422425
}
423426
}
424427

428+
/// Sets the path where ancestor config file searching will stop. The
429+
/// given path is included, but its ancestors are not.
430+
pub fn set_search_stop_path<P: Into<PathBuf>>(&mut self, path: P) {
431+
let path = path.into();
432+
debug_assert!(self.cwd.starts_with(&path));
433+
self.search_stop_path = Some(path);
434+
}
435+
425436
/// Reloads on-disk configuration values, starting at the given path and
426437
/// walking up its ancestors.
427438
pub fn reload_rooted_at<P: AsRef<Path>>(&mut self, path: P) -> CargoResult<()> {
@@ -1028,7 +1039,7 @@ impl Config {
10281039
{
10291040
let mut stash: HashSet<PathBuf> = HashSet::new();
10301041

1031-
for current in paths::ancestors(pwd) {
1042+
for current in paths::ancestors(pwd, self.search_stop_path.as_deref()) {
10321043
if let Some(path) = self.get_file_path(&current.join(".cargo"), "config", true)? {
10331044
walk(&path)?;
10341045
stash.insert(path);

src/cargo/util/important_paths.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
55
/// Finds the root `Cargo.toml`.
66
pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult<PathBuf> {
77
let file = "Cargo.toml";
8-
for current in paths::ancestors(cwd) {
8+
for current in paths::ancestors(cwd, None) {
99
let manifest = current.join(file);
1010
if manifest.exists() {
1111
return Ok(manifest);

src/cargo/util/paths.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,8 @@ pub fn bytes2path(bytes: &[u8]) -> CargoResult<PathBuf> {
306306
}
307307
}
308308

309-
pub fn ancestors(path: &Path) -> PathAncestors<'_> {
310-
PathAncestors::new(path)
309+
pub fn ancestors<'a>(path: &'a Path, stop_root_at: Option<&Path>) -> PathAncestors<'a> {
310+
PathAncestors::new(path, stop_root_at)
311311
}
312312

313313
pub struct PathAncestors<'a> {
@@ -316,11 +316,15 @@ pub struct PathAncestors<'a> {
316316
}
317317

318318
impl<'a> PathAncestors<'a> {
319-
fn new(path: &Path) -> PathAncestors<'_> {
319+
fn new(path: &'a Path, stop_root_at: Option<&Path>) -> PathAncestors<'a> {
320+
let stop_at = env::var("__CARGO_TEST_ROOT")
321+
.ok()
322+
.map(PathBuf::from)
323+
.or_else(|| stop_root_at.map(|p| p.to_path_buf()));
320324
PathAncestors {
321325
current: Some(path),
322326
//HACK: avoid reading `~/.cargo/config` when testing Cargo itself.
323-
stop_at: env::var("__CARGO_TEST_ROOT").ok().map(PathBuf::from),
327+
stop_at,
324328
}
325329
}
326330
}

tests/testsuite/config.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl ConfigBuilder {
7777
let homedir = paths::home();
7878
let mut config = Config::new(shell, cwd, homedir);
7979
config.set_env(self.env.clone());
80+
config.set_search_stop_path(paths::root());
8081
config.configure(
8182
0,
8283
false,

0 commit comments

Comments
 (0)