diff --git a/CHANGELOG.md b/CHANGELOG.md index 8770482b8f..3606f4027a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.20.4 - 2026-02-02 +[0.20.3...0.20.4](https://github.com/rust-lang/git2-rs/compare/git2-0.20.3...git2-0.20.4) + +### Fixed + +- Fix undefined behavior when dereferencing empty `Buf`. + [#1213](https://github.com/rust-lang/git2-rs/pull/1213) + ## 0.20.3 - 2025-12-06 [0.20.2...0.20.3](https://github.com/rust-lang/git2-rs/compare/git2-0.20.2...git2-0.20.3) diff --git a/Cargo.lock b/Cargo.lock index 0699b3fd3a..0aae751aef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,7 +357,7 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.3" +version = "0.20.4" dependencies = [ "bitflags 2.6.0", "clap", diff --git a/Cargo.toml b/Cargo.toml index 8e6e4cafbe..d9914c4336 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git2" -version = "0.20.3" +version = "0.20.4" authors = ["Josh Triplett ", "Alex Crichton "] license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/src/buf.rs b/src/buf.rs index fd2bcbf96f..7b714dfe9c 100644 --- a/src/buf.rs +++ b/src/buf.rs @@ -44,12 +44,18 @@ impl Buf { impl Deref for Buf { type Target = [u8]; fn deref(&self) -> &[u8] { + if self.raw.ptr.is_null() { + return &[]; + } unsafe { slice::from_raw_parts(self.raw.ptr as *const u8, self.raw.size as usize) } } } impl DerefMut for Buf { fn deref_mut(&mut self) -> &mut [u8] { + if self.raw.ptr.is_null() { + return &mut []; + } unsafe { slice::from_raw_parts_mut(self.raw.ptr as *mut u8, self.raw.size as usize) } } } @@ -69,3 +75,12 @@ impl Drop for Buf { unsafe { raw::git_buf_dispose(&mut self.raw) } } } + +#[test] +fn empty_buf() { + let mut buf = Buf::new(); + let x: &[u8] = &*buf; + assert_eq!(x.len(), 0); + let x: &mut [u8] = &mut *buf; + assert_eq!(x.len(), 0); +}