diff --git a/src/remote.rs b/src/remote.rs index 0c13a53fcf..ebc41c5adb 100644 --- a/src/remote.rs +++ b/src/remote.rs @@ -384,6 +384,18 @@ impl<'repo> Remote<'repo> { mem::size_of::>(), mem::size_of::<*const raw::git_remote_head>() ); + if base.is_null() { + // We cannot use slice::from_raw_parts() since that requires + // that the pointer be non-null, but that is fine since the size + // should be zero + if size != 0 { + return Err(Error::from_str(&format!( + "git_remote_ls() set a null pointer for a list of size {}", + size + ))); + } + return Ok(&[]); + } let slice = slice::from_raw_parts(base as *const _, size as usize); Ok(mem::transmute::< &[*const raw::git_remote_head], @@ -921,6 +933,27 @@ mod tests { drop(origin.clone()); } + #[test] + fn empty_remote_list() { + // Regression tests for issue #1217 + let td = TempDir::new().unwrap(); + let repo = Repository::init(td.path()).unwrap(); + + let remote_dir = TempDir::new().unwrap(); + let _remote_repo = Repository::init_bare(remote_dir.path()).unwrap(); + let remote_url = if cfg!(unix) { + format!("file://{}", remote_dir.path().display()) + } else { + format!( + "file:///{}", + remote_dir.path().display().to_string().replace("\\", "/") + ) + }; + let mut remote = repo.remote("origin", &remote_url).unwrap(); + remote.connect(Direction::Fetch).unwrap(); + assert_eq!(0, remote.list().unwrap().len()); + } + #[test] fn is_valid_name() { assert!(Remote::is_valid_name("foobar"));