Skip to content

Commit

Permalink
Auto merge of rust-lang#9164 - ehuss:config-search-stop, r=Eh2406
Browse files Browse the repository at this point in the history
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 rust-lang#9107
  • Loading branch information
bors committed Feb 11, 2021
2 parents ab64d13 + 9cb8f41 commit ecfabe6
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/bin/cargo/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult {
if let Some(path) = args.value_of_path("path", config) {
config.reload_rooted_at(path)?;
} else {
// TODO: Consider calling set_search_stop_path(home).
config.reload_rooted_at(config.home().clone().into_path_unlocked())?;
}

Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ impl<'cfg> Workspace<'cfg> {
}
}

for path in paths::ancestors(manifest_path).skip(2) {
for path in paths::ancestors(manifest_path, None).skip(2) {
if path.ends_with("target/package") {
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ fn find_tests_git_config(path: &Path) -> Option<GitConfig> {
// Don't escape the test sandbox when looking for a git repository.
// NOTE: libgit2 has support to define the path ceiling in
// git_repository_discover, but the git2 bindings do not expose that.
for path in paths::ancestors(path) {
for path in paths::ancestors(path, None) {
if let Ok(repo) = GitRepository::open(path) {
return Some(repo.config().expect("test repo should have valid config"));
}
Expand Down
13 changes: 12 additions & 1 deletion src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ pub struct Config {
cli_config: Option<Vec<String>>,
/// The current working directory of cargo
cwd: PathBuf,
/// Directory where config file searching should stop (inclusive).
search_stop_path: Option<PathBuf>,
/// The location of the cargo executable (path to current process)
cargo_exe: LazyCell<PathBuf>,
/// The location of the rustdoc executable
Expand Down Expand Up @@ -218,6 +220,7 @@ impl Config {
home_path: Filesystem::new(homedir),
shell: RefCell::new(shell),
cwd,
search_stop_path: None,
values: LazyCell::new(),
cli_config: None,
cargo_exe: LazyCell::new(),
Expand Down Expand Up @@ -422,6 +425,14 @@ impl Config {
}
}

/// Sets the path where ancestor config file searching will stop. The
/// given path is included, but its ancestors are not.
pub fn set_search_stop_path<P: Into<PathBuf>>(&mut self, path: P) {
let path = path.into();
debug_assert!(self.cwd.starts_with(&path));
self.search_stop_path = Some(path);
}

/// Reloads on-disk configuration values, starting at the given path and
/// walking up its ancestors.
pub fn reload_rooted_at<P: AsRef<Path>>(&mut self, path: P) -> CargoResult<()> {
Expand Down Expand Up @@ -1028,7 +1039,7 @@ impl Config {
{
let mut stash: HashSet<PathBuf> = HashSet::new();

for current in paths::ancestors(pwd) {
for current in paths::ancestors(pwd, self.search_stop_path.as_deref()) {
if let Some(path) = self.get_file_path(&current.join(".cargo"), "config", true)? {
walk(&path)?;
stash.insert(path);
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/util/important_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf};
/// Finds the root `Cargo.toml`.
pub fn find_root_manifest_for_wd(cwd: &Path) -> CargoResult<PathBuf> {
let file = "Cargo.toml";
for current in paths::ancestors(cwd) {
for current in paths::ancestors(cwd, None) {
let manifest = current.join(file);
if manifest.exists() {
return Ok(manifest);
Expand Down
12 changes: 8 additions & 4 deletions src/cargo/util/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ pub fn bytes2path(bytes: &[u8]) -> CargoResult<PathBuf> {
}
}

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

pub struct PathAncestors<'a> {
Expand All @@ -316,11 +316,15 @@ pub struct PathAncestors<'a> {
}

impl<'a> PathAncestors<'a> {
fn new(path: &Path) -> PathAncestors<'_> {
fn new(path: &'a Path, stop_root_at: Option<&Path>) -> PathAncestors<'a> {
let stop_at = env::var("__CARGO_TEST_ROOT")
.ok()
.map(PathBuf::from)
.or_else(|| stop_root_at.map(|p| p.to_path_buf()));
PathAncestors {
current: Some(path),
//HACK: avoid reading `~/.cargo/config` when testing Cargo itself.
stop_at: env::var("__CARGO_TEST_ROOT").ok().map(PathBuf::from),
stop_at,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ impl ConfigBuilder {
let homedir = paths::home();
let mut config = Config::new(shell, cwd, homedir);
config.set_env(self.env.clone());
config.set_search_stop_path(paths::root());
config.configure(
0,
false,
Expand Down

0 comments on commit ecfabe6

Please sign in to comment.