diff options
Diffstat (limited to 'vendor/gix-index/src/decode/header.rs')
-rw-r--r-- | vendor/gix-index/src/decode/header.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/vendor/gix-index/src/decode/header.rs b/vendor/gix-index/src/decode/header.rs new file mode 100644 index 000000000..04c3bfd98 --- /dev/null +++ b/vendor/gix-index/src/decode/header.rs @@ -0,0 +1,46 @@ +pub(crate) const SIZE: usize = 4 /*signature*/ + 4 /*version*/ + 4 /* num entries */; + +use crate::{util::from_be_u32, Version}; + +pub(crate) const SIGNATURE: &[u8] = b"DIRC"; + +mod error { + + /// The error produced when failing to decode an index header. + #[derive(Debug, thiserror::Error)] + #[allow(missing_docs)] + pub enum Error { + #[error("{0}")] + Corrupt(&'static str), + #[error("Index version {0} is not supported")] + UnsupportedVersion(u32), + } +} +pub use error::Error; + +pub(crate) fn decode(data: &[u8], object_hash: gix_hash::Kind) -> Result<(Version, u32, &[u8]), Error> { + if data.len() < (3 * 4) + object_hash.len_in_bytes() { + return Err(Error::Corrupt( + "File is too small even for header with zero entries and smallest hash", + )); + } + + let (signature, data) = data.split_at(4); + if signature != SIGNATURE { + return Err(Error::Corrupt( + "Signature mismatch - this doesn't claim to be a header file", + )); + } + + let (version, data) = data.split_at(4); + let version = match from_be_u32(version) { + 2 => Version::V2, + 3 => Version::V3, + 4 => Version::V4, + unknown => return Err(Error::UnsupportedVersion(unknown)), + }; + let (entries, data) = data.split_at(4); + let entries = from_be_u32(entries); + + Ok((version, entries, data)) +} |