From d136d3e52ec7693fac738421bbf640897772278e Mon Sep 17 00:00:00 2001 From: Martin Vlach Date: Tue, 27 Oct 2026 10:25:23 +0100 Subject: [PATCH] fix: validate non-empty backup paths in LocalSource::new Calling `LocalSource::new` with an empty `backup_paths` slice caused an immediate out-of-bounds indexing panic at `&backup_paths[0]`. Use `backup_paths.split_first()` to ensure at least one path is provided before initializing `WalkBuilder`, returning an `InvalidInput` error otherwise. Add a unit test verifying that empty backup paths return an error instead of panicking. Reported-by: BS.ehlas.cz --- crates/core/src/backend/ignore.rs | 34 +++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/crates/core/src/backend/ignore.rs b/crates/core/src/backend/ignore.rs index a36875453..87db8bdd7 100644 --- a/crates/core/src/backend/ignore.rs +++ b/crates/core/src/backend/ignore.rs @@ -124,6 +124,7 @@ impl LocalSource { /// /// # Errors /// + /// * If `backup_paths` is empty. /// * If the a glob pattern could not be added to the override builder. /// * If a glob file could not be read. #[allow(clippy::too_many_lines)] @@ -133,9 +134,16 @@ impl LocalSource { filter_opts: &LocalSourceFilterOptions, backup_paths: &[impl AsRef], ) -> RusticResult { - let mut walk_builder = WalkBuilder::new(&backup_paths[0]); + let (first, rest) = backup_paths.split_first().ok_or_else(|| { + RusticError::new( + ErrorKind::InvalidInput, + "Cannot create local source: backup_paths cannot be empty.", + ) + })?; + + let mut walk_builder = WalkBuilder::new(first); - for path in &backup_paths[1..] { + for path in rest { _ = walk_builder.add(path); } @@ -347,3 +355,25 @@ impl Iterator for LocalSourceWalker { }) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_local_source_new_empty_backup_paths() { + let save_opts = LocalSourceSaveOptions::default(); + let excludes = Excludes::default(); + let filter_opts = LocalSourceFilterOptions::default(); + let empty_paths: &[&Path] = &[]; + + let result = LocalSource::new(save_opts, &excludes, &filter_opts, empty_paths); + assert!(result.is_err()); + assert!( + result + .unwrap_err() + .to_string() + .contains("backup_paths cannot be empty") + ); + } +}