diff --git a/src/backup.rs b/src/backup.rs index 11153f7..0fa974e 100644 --- a/src/backup.rs +++ b/src/backup.rs @@ -11,8 +11,11 @@ pub struct Engine<'a> { } impl<'a> Engine<'a> { - pub fn new(source_path: &'a Path, repository: &'a mut Repository<'a>) -> Self { - Engine { source_path, repository } + pub fn new(source_path: &'a Path, repository: &'a mut Repository<'a>) -> Result { + if source_path.ancestors().any(|a| a == repository.path()) { + return Err(BakareError::SourceSameAsRepository); + } + Ok(Engine { source_path, repository }) } pub fn backup(&mut self) -> Result<(), BakareError> { diff --git a/src/repository.rs b/src/repository.rs index 9a884c6..a9f8963 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -76,6 +76,10 @@ impl<'a> Repository<'a> { } } + pub fn path(&self) -> &Path { + &self.path + } + pub fn store(&mut self, source_path: &Path) -> Result<(), BakareError> { if !source_path.is_absolute() { return Err(BakareError::PathToStoreNotAbsolute); diff --git a/src/test/assertions.rs b/src/test/assertions.rs index 1160ddb..21536d8 100644 --- a/src/test/assertions.rs +++ b/src/test/assertions.rs @@ -6,10 +6,10 @@ use std::path::Path; use tempfile::tempdir; use walkdir::WalkDir; -use crate::{backup, restore}; use crate::error::BakareError; use crate::repository::{ItemVersion, Repository}; use crate::source::TempSource; +use crate::{backup, restore}; pub fn assert_target_file_contents(restored_path: &Path, expected_contents: &str) -> Result<(), BakareError> { let mut actual_contents = String::new(); @@ -29,7 +29,7 @@ pub fn assert_same_after_restore(source_path: &Path) -> Result<(), BakareError> Repository::init(repository_path.as_path())?; { let mut backup_repository = Repository::open(repository_path.as_path())?; - let mut backup_engine = backup::Engine::new(source_path, &mut backup_repository); + let mut backup_engine = backup::Engine::new(source_path, &mut backup_repository)?; backup_engine.backup()?; } { @@ -96,7 +96,7 @@ pub fn backup_file_with_contents( ) -> Result<(), BakareError> { { let mut backup_repository = Repository::open(repository_path)?; - let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository); + let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository)?; source.write_text_to_file(source_file_relative_path, contents)?; backup_engine.backup()?; Ok(()) diff --git a/tests/system_tests.rs b/tests/system_tests.rs index 91b884e..e586150 100644 --- a/tests/system_tests.rs +++ b/tests/system_tests.rs @@ -1,5 +1,6 @@ use tempfile::tempdir; +use bakare::backup; use bakare::error::BakareError; use bakare::repository::Repository; use bakare::source::TempSource; @@ -56,6 +57,23 @@ fn restore_older_version_of_file() -> Result<(), BakareError> { assert_restored_from_version_has_contents(&repository_path, &source_file_full_path, old_contents, &old_version) } +#[test] +fn forbid_backup_of_paths_within_repository() -> Result<(), BakareError> { + let repository_path = &tempdir()?.into_path(); + Repository::init(repository_path)?; + let mut repository = Repository::open(repository_path)?; + if let Err(e) = backup::Engine::new(repository_path, &mut repository) { + let correct_error = match e { + BakareError::SourceSameAsRepository => true, + _ => false, + }; + assert!(correct_error); + } else { + panic!("Expected error"); + } + Ok(()) +} + // TODO: restore latest version by default // TODO: deduplicate data // TODO: test that index is stored separately from data