-
Notifications
You must be signed in to change notification settings - Fork 436
Open
Description
Hello,
I'm pretty sure I encountered undefined behavior with Remote::list while writing tests for my application.
I managed to reproduce the problem with a minimal exemple. You can run cargo test with the following setup:
[package]
name = "git-ub-investigation"
version = "0.1.0"
edition = "2024"
[dependencies]
git2 = "0.20.3"
tempfile = "3.24.0"fn main() {
let repo_dir = tempfile::tempdir().unwrap();
let repo = git2::Repository::init(repo_dir.path()).unwrap();
let remote_dir = tempfile::tempdir().unwrap();
let _remote_repo = git2::Repository::init_bare(remote_dir.path()).unwrap();
let remote_url = format!("file://{}", remote_dir.path().display());
let mut remote = repo.remote("origin", &remote_url).unwrap();
remote.connect(git2::Direction::Fetch).unwrap();
remote.list().unwrap().iter().for_each(|remote| {
println!("remote: {}", remote.name());
});
}
#[test]
fn test_main() {
main();
}It shows the following output:
Compiling git-ub-investigation v0.1.0 (/home/foo/dev/git-ub-investigation)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.16s
Running unittests src/main.rs (target/debug/deps/git_ub_investigation-aef9ec97e4f87283)
running 1 test
thread 'test_main' (2250680) panicked at /home/foo/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/git2-0.20.4/src/remote.rs:387:25:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
error: test failed, to rerun pass `--bin git-ub-investigation`
Caused by:
process didn't exit successfully: `/home/foo/dev/git-ub-investigation/target/debug/deps/git_ub_investigation-aef9ec97e4f87283` (signal: 6, SIGABRT: process abort signal)
I'm not used to low-level code, but from what I gathered looking at the sources and print-debugging:
- the call to
git_remote_lsinRemote::listdoes not set thebasevariable, which remains null. - the null-pointer is the sent to
slice::from_raw_partswhich triggers undefined behavior as per the docs stating "datamust be non-null". - It only affects cases where no branches or tags have been pushed to the remote.
- I don't know if using local directories is relevant or not.
I understand there might be something wrong with my setup, or that the root issue might lie in the underlying libgit2-sys, but I don't think a call to a safe method should be able to trigger undefined behavior.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels