[commitgraph] Validate trailer section when parsing files.
@@ -39,6 +39,8 @@ pub enum Error {
},
#[error("Missing required chunk {:?}", .0.as_bstr())]
MissingChunk(ChunkId),
+ #[error("{0}")]
+ Trailer(String),
#[error("Commit-graph file uses unsupported hash version: {0}")]
UnsupportedHashVersion(u8),
#[error("Unsupported commit-graph file version: {0}")]
@@ -47,7 +49,8 @@ pub enum Error {
const CHUNK_LOOKUP_SIZE: usize = 12;
const HEADER_LEN: usize = 8;
-const MIN_FILE_SIZE: usize = HEADER_LEN + ((MIN_CHUNKS + 1) * CHUNK_LOOKUP_SIZE);
+const TRAILER_LEN: usize = SHA1_SIZE;
+const MIN_FILE_SIZE: usize = HEADER_LEN + ((MIN_CHUNKS + 1) * CHUNK_LOOKUP_SIZE) + TRAILER_LEN;
const OID_LOOKUP_ENTRY_SIZE: usize = SHA1_SIZE;
// Required chunks: OIDF, OIDL, CDAT
@@ -262,6 +265,14 @@ impl TryFrom<&Path> for File {
)));
}
+ let actual_trailer_len = data_size.saturating_sub(chunk_offset);
+ if actual_trailer_len != TRAILER_LEN {
+ return Err(Error::Trailer(format!(
+ "Expected commit-graph trailer to contain {} bytes, got {}",
+ TRAILER_LEN, actual_trailer_len
+ )));
+ }
+
let fan_offset = fan_offset.ok_or_else(|| Error::MissingChunk(OID_FAN_CHUNK_ID))?;
let oid_lookup_offset = oid_lookup_offset.ok_or_else(|| Error::MissingChunk(OID_LOOKUP_CHUNK_ID))?;
let commit_data_offset = commit_data_offset.ok_or_else(|| Error::MissingChunk(COMMIT_DATA_CHUNK_ID))?;
