Skip to content

Commit

Permalink
Provide multi-index checksum (#279)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 20, 2021
1 parent d0fab1e commit a363de9
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
25 changes: 21 additions & 4 deletions git-pack/src/multi_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,28 @@ pub struct File {
index_names: Vec<PathBuf>,
lookup: Range<git_chunk::file::Offset>,
offsets: Range<git_chunk::file::Offset>,
pub large_offsets: Option<Range<git_chunk::file::Offset>>,
large_offsets: Option<Range<git_chunk::file::Offset>>,
checksum_offset: usize,
}

///
pub mod access {
use crate::multi_index::File;
use std::convert::TryFrom;

impl File {
pub fn num_packs(&self) -> u32 {
self.num_packs
}
pub fn num_objects(&self) -> u32 {
self.num_objects
}
pub fn hash_kind(&self) -> git_hash::Kind {
self.hash_kind
}
pub fn checksum(&self) -> git_hash::ObjectId {
git_hash::ObjectId::try_from(&self.data[self.checksum_offset..]).expect("prior validation of checksum size")
}
}
}

Expand Down Expand Up @@ -170,7 +178,7 @@ pub mod init {
path: std::path::PathBuf,
},
#[error("{message}")]
Corrupt { message: String },
Corrupt { message: &'static str },
#[error("Unsupported multi-index version: {version})")]
UnsupportedVersion { version: u8 },
#[error("Unsupported hash kind: {kind})")]
Expand Down Expand Up @@ -219,15 +227,15 @@ pub mod init {
const TRAILER_LEN: usize = git_hash::Kind::longest().len_in_bytes(); /* trailing hash */
if data.len() < HEADER_LEN + git_chunk::file::Index::EMPTY_SIZE + TRAILER_LEN {
return Err(Error::Corrupt {
message: "multi-index file is truncated and too short".into(),
message: "multi-index file is truncated and too short",
});
}

let (version, hash_kind, num_chunks, num_packs) = {
let (signature, data) = data.split_at(4);
if signature != b"MIDX" {
return Err(Error::Corrupt {
message: "Invalid signature".into(),
message: "Invalid signature",
});
}
let (version, data) = data.split_at(1);
Expand Down Expand Up @@ -274,6 +282,14 @@ pub mod init {
return Err(Error::LargeOffsetsSize);
}

let checksum_offset = chunks.highest_offset() as usize;
let trailer = &data[checksum_offset..];
if trailer.len() != hash_kind.len_in_bytes() {
return Err(Error::Corrupt {
message: "Trailing checksum didn't have the expected size or there were unknown bytes after the checksum.",
});
}

Ok(File {
data,
path: path.to_owned(),
Expand All @@ -284,6 +300,7 @@ pub mod init {
lookup,
offsets,
large_offsets,
checksum_offset,
num_objects,
num_chunks,
num_packs,
Expand Down
4 changes: 4 additions & 0 deletions git-pack/tests/pack/multi_index.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use git_testtools::hex_to_id;

#[test]
fn access() {
let path = git_testtools::scripted_fixture_repo_read_only("make_pack_gen_repo_multi_index.sh")
Expand All @@ -7,4 +9,6 @@ fn access() {

assert_eq!(file.num_packs(), 1);
assert_eq!(file.hash_kind(), git_hash::Kind::Sha1);
assert_eq!(file.num_objects(), 868);
assert_eq!(file.checksum(), hex_to_id("39a3804d0a84de609e4fcb49e66dc1297c75ca11"));
}

0 comments on commit a363de9

Please sign in to comment.