🏡 index : ~doyle/packfile.git

author Jordan Doyle <jordan@doyle.la> 2023-07-04 19:10:22.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2023-07-04 19:10:22.0 +00:00:00
commit
22bfb75cd9c1f0466bef234a2650652f7754dad2 [patch]
tree
0be6fd2e6394b8fd833579de78276fbe4d2adb76
parent
c6fd6315304febb235ebd755751b63487c82af0b
download
22bfb75cd9c1f0466bef234a2650652f7754dad2.tar.gz

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.

Diff

 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]);
        }
    }
}