From c73e62ddbdd102ca3b28f49be61cebfc4db04cdb Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 9 May 2026 16:45:50 -0700 Subject: [PATCH 1/2] Add a test for index add_all with empty pathspec This particular situation with a callback is crashing. --- src/index.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/index.rs b/src/index.rs index bed3dba22a..9ee698b22f 100644 --- a/src/index.rs +++ b/src/index.rs @@ -1083,4 +1083,20 @@ mod tests { fn smoke_in_memory_index_sha256() { let _index = Index::new_ext(ObjectFormat::Sha256).unwrap(); } + + #[test] + fn empty_pathspec_with_cb() { + let (td, repo) = crate::test::repo_init(); + crate::test::commit(&repo); + fs::write(td.path().join("foo"), "modified").unwrap(); + let pathspecs: &[&str] = &[]; + let mut index = repo.index().unwrap(); + index + .add_all( + pathspecs, + Default::default(), + Some(&mut |_path, _matched_pathspec| 0), + ) + .unwrap(); + } } From ae77eced6f1621ad99f536b9d753f4a95f41ff81 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 9 May 2026 16:51:43 -0700 Subject: [PATCH 2/2] Don't crash if the matched pathspec is NULL In the index add_all callback, if the matched pathspec is NULL, this was crashing due to the panic in the C callback. The temporary solution here is to handle the panic inside the panic wrapper. A future version will change the signature of the callback to handle this situation. --- src/index.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/index.rs b/src/index.rs index 9ee698b22f..d4d98dbada 100644 --- a/src/index.rs +++ b/src/index.rs @@ -771,10 +771,10 @@ extern "C" fn index_matched_path_cb( payload: *mut c_void, ) -> c_int { unsafe { - let path = CStr::from_ptr(path).to_bytes(); - let matched_pathspec = CStr::from_ptr(matched_pathspec).to_bytes(); - panic::wrap(|| { + let path = crate::opt_bytes(&payload, path).unwrap(); + let matched_pathspec = + crate::opt_bytes(&payload, matched_pathspec).expect("no matched pathspec"); let payload = payload as *mut &mut IndexMatchedPath<'_>; (*payload)(util::bytes2path(path), matched_pathspec) as c_int }) @@ -1085,6 +1085,7 @@ mod tests { } #[test] + #[should_panic = "no matched pathspec"] fn empty_pathspec_with_cb() { let (td, repo) = crate::test::repo_init(); crate::test::commit(&repo);