GitoxideLabs/gitoxide · warning

enough data after previous check

Error message

enough data after previous check

What it means

A `expect()` panic converting a slice of pack data to a fixed-size header array in `gix_pack::data::File::from_data`. The preceding length check guarantees the data is at least `header::SIZE` plus hash length bytes, so the `try_into` to `[u8; header::SIZE]` cannot fail. Failure indicates the guard above was bypassed or altered.

Solutions

  1. Update gix-pack
  2. Validate pack files before opening (size and trailing hash)
  3. Report upstream with the input that triggered it
Defensive patterns

Strategy: validation

Validate before calling

let meta = std::fs::metadata(&pack_path)?;
if meta.len() < (gix_pack::data::header::SIZE + 20 /* hash len */) as u64 {
    return Err("pack file too small".into());
}

Try / catch

let r = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| gix_pack::data::File::at(&path, id)));
if r.is_err() { eprintln!("unexpected panic opening pack"); }

Prevention

When it happens

Trigger: Constructing a `gix_pack::data::File` via `from_data` with data shorter than the check threshold is impossible (it errors first); the panic only occurs if the size guard or `data::header::SIZE` constant changes inconsistently — i.e. a library bug.

Common situations: Opening packs smaller than the minimum size yields a normal error, not this panic; the panic is development/fuzzing-only territory.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of GitoxideLabs/gitoxide@e73179060b (2026-09-08). Data as JSON: /api/errors/7aae5e56d82be54b. Report an issue: GitHub.

Appendix: source

Thrown at gix-pack/src/data/file/init.rs:48

    T: crate::FileData,
{
    /// Instantiate a data file from `data` as assumed to be read or memory-mapped from `path`.
    ///
    /// This constructor leaves allocation limiting disabled, allowing allocations of any size dictated by pack data.
    /// Call [`File::with_alloc_limit_bytes()`][crate::data::File::with_alloc_limit_bytes()] before decoding entries from untrusted input.
    pub fn from_data(data: T, path: PathBuf, object_hash: gix_hash::Kind) -> Result<Self, data::header::decode::Error> {
        let hash_len = object_hash.len_in_bytes();
        let pack_len = data.len();
        let id = gix_features::hash::crc32(path.as_os_str().to_string_lossy().as_bytes());
        if pack_len < data::header::SIZE + hash_len {
            return Err(data::header::decode::Error::Corrupt(format!(
                "Pack data of size {pack_len} is too small for even an empty pack with shortest hash"
            )));
        }
        let (kind, num_objects) = data::header::decode(
            &data[..data::header::SIZE]
                .try_into()
                .expect("enough data after previous check"),
        )?;
        Ok(Self {
            data,
            path,
            id,
            version: kind,
            num_objects,
            object_hash,
            alloc_limit_bytes: None,
        })
    }

    /// Configure the maximum size of a single allocation caused by user-controlled on-disk pack data.
    ///
    /// Use `None` to disable the limit, which is also the default.
    ///
    /// This is currently enforced when decoding pack entries and resolving delta chains.
    /// Callers that allocate from pack metadata directly should consult [`File::alloc_limit_bytes()`][crate::data::File::alloc_limit_bytes]

View on GitHub (pinned to e73179060b)