diff --git a/crates/nargo_toml/src/errors.rs b/crates/nargo_toml/src/errors.rs index 2b68f681f92..9abeab97b61 100644 --- a/crates/nargo_toml/src/errors.rs +++ b/crates/nargo_toml/src/errors.rs @@ -44,6 +44,9 @@ pub enum ManifestError { #[error("{} found in {toml}", if name.is_empty() { "Empty dependency name".into() } else { format!("Invalid dependency name `{name}`") })] InvalidDependencyName { toml: PathBuf, name: String }, + #[error("Invalid directory path {directory} in {toml}: It must point to a subdirectory")] + InvalidDirectory { toml: PathBuf, directory: PathBuf }, + /// Encountered error while downloading git repository. #[error("{0}")] GitError(String), diff --git a/crates/nargo_toml/src/lib.rs b/crates/nargo_toml/src/lib.rs index 8372942931b..1dd6ac0e695 100644 --- a/crates/nargo_toml/src/lib.rs +++ b/crates/nargo_toml/src/lib.rs @@ -238,16 +238,28 @@ struct PackageMetadata { /// Enum representing the different types of ways to /// supply a source for the dependency enum DependencyConfig { - Github { git: String, tag: String }, + Github { git: String, tag: String, directory: Option }, Path { path: String }, } impl DependencyConfig { fn resolve_to_dependency(&self, pkg_root: &Path) -> Result { let dep = match self { - Self::Github { git, tag } => { + Self::Github { git, tag, directory } => { let dir_path = clone_git_repo(git, tag).map_err(ManifestError::GitError)?; - let toml_path = dir_path.join("Nargo.toml"); + let project_path = if let Some(directory) = directory { + let internal_path = dir_path.join(directory).normalize(); + if !internal_path.starts_with(&dir_path) { + return Err(ManifestError::InvalidDirectory { + toml: pkg_root.join("Nargo.toml"), + directory: directory.into(), + }); + } + internal_path + } else { + dir_path + }; + let toml_path = project_path.join("Nargo.toml"); let package = resolve_package_from_toml(&toml_path)?; Dependency::Remote { package } }