{"record":{"id":"cddc9310c883e501","repo":"GitoxideLabs/gitoxide","slug":"pack-entry-header-overflowed","errorCode":null,"errorMessage":"pack entry header overflowed","messagePattern":"pack entry header overflowed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gix-pack/src/data/entry/decode.rs","lineNumber":127,"sourceCode":"    })\n}\n\n#[inline]\nfn streaming_parse_header_info(read: &mut dyn io::Read) -> Result<(u8, u64, usize), io::Error> {\n    let mut byte = [0u8; 1];\n    read.read_exact(&mut byte)?;\n    let mut c = byte[0];\n    let mut i = 1;\n    let type_id = (c >> 4) & 0b0000_0111;\n    let mut size = u64::from(c) & 0b0000_1111;\n    let mut shift = 4u32;\n    while c & 0b1000_0000 != 0 {\n        read.read_exact(&mut byte)?;\n        c = byte[0];\n        i += 1;\n        let component = u64::from(c & 0b0111_1111)\n            .checked_shl(shift)\n            .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"pack entry header overflowed\"))?;\n        size = size\n            .checked_add(component)\n            .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, \"pack entry header overflowed\"))?;\n        shift += 7;\n    }\n    Ok((type_id, size, i))\n}\n\n/// Parses the header of a pack-entry, yielding object type id, decompressed object size, and consumed bytes\n#[inline]\nfn parse_header_info(data: &[u8]) -> Result<(u8, u64, usize), Error> {\n    let mut c = *data.first().ok_or(Error::Corrupt {\n        message: \"need a pack entry header, got empty input\",\n    })?;\n    let mut i = 1;\n    let type_id = (c >> 4) & 0b0000_0111;\n    let mut size = u64::from(c) & 0b0000_1111;\n    let mut shift = 4u32;","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/GitoxideLabs/gitoxide/blob/e73179060badf27222d790981fac3f84c1830a7e/gix-pack/src/data/entry/decode.rs#L109-L145","documentation":"While streaming-parsing a pack entry header, each continuation byte contributes 7 bits shifted left; if the shift exceeds 63 bits the `checked_shl` overflows and an InvalidData io::Error 'pack entry header overflowed' is returned. It means the multi-byte size header is implausibly long for a valid pack.","triggerScenarios":"Calling `data::Entry::from_read` (via streaming_parse_header_info) on a stream whose header has so many continuation bytes that the u64 shift would overflow — i.e. a corrupt or malicious header.","commonSituations":"Corrupted pack downloads, adversarial pack files, fuzzing inputs.","solutions":["Verify the pack file integrity (`gix pack verify` / `git fsck`)","Re-download or re-clone to replace the corrupt pack","Confirm the source stream is an authentic git pack file","During fuzzing/tests, treat this as correct rejection of invalid input"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// checksum the pack before parsing\nassert_eq!(pack.trailer(), expected_sha);","typeGuard":null,"tryCatchPattern":"match parse_result {\n    Err(e) if e.to_string().contains(\"pack entry header overflowed\") => {\n        // reject pack as corrupt, re-fetch\n    }\n    other => other?,\n}","preventionTips":["Verify pack SHA-1 trailer before decoding entries","Avoid parsing partial pack downloads","Fuzz-test parsers expecting clean rejection"],"tags":["pack","overflow","decode","git"],"backgroundTag":"value-out-of-range","analyzedSha":"e73179060badf27222d790981fac3f84c1830a7e","analyzedAt":"2026-09-08T11:26:50.865Z","contentChangedAt":"2026-09-08T11:26:50.865Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}