From 22bfb75cd9c1f0466bef234a2650652f7754dad2 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Tue, 4 Jul 2023 20:10:22 +0100 Subject: [PATCH] Fix bug when packing files smaller than 16 bytes Git's packfile format, requires an extra empty byte to be written, even if the full file size can be packed into what is left of the previous 8 bits. --- src/low_level.rs | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/low_level.rs b/src/low_level.rs index 1e91487..cdfe3d5 100644 --- a/src/low_level.rs +++ b/src/low_level.rs @@ -251,7 +251,7 @@ impl PackFileEntry { } // write size bytes - while size != 0 { + loop { // read 7 LSBs from the `size` and push them off for the next iteration #[allow(clippy::cast_possible_truncation)] // value is masked let mut val = (size & 0b111_1111) as u8; @@ -264,6 +264,10 @@ impl PackFileEntry { } buf.put_u8(val); + + if size == 0 { + break; + } } } @@ -349,3 +353,31 @@ impl PackFileEntry { Ok(sha1::Sha1::digest(&out).into()) } } + +#[cfg(test)] +mod test { + mod packfile_entry { + use bytes::{Bytes, BytesMut}; + use crate::low_level::PackFileEntry; + + #[test] + fn header_size_bytes_large() { + let entry = PackFileEntry::Blob(Bytes::from(vec![0u8; 16])); + + let mut header = BytesMut::new(); + entry.write_header(&mut header); + + assert_eq!(header.to_vec(), &[0xb0, 0x01]); + } + + #[test] + fn header_size_bytes_small() { + let entry = PackFileEntry::Blob(Bytes::from(vec![0u8; 15])); + + let mut header = BytesMut::new(); + entry.write_header(&mut header); + + assert_eq!(header.to_vec(), &[0xbf, 0x00]); + } + } +} -- libgit2 1.7.2