{"record":{"id":"24c0c99619238345","repo":"Pumpkin-MC/Pumpkin","slug":"hit-count-exceeds-limit","errorCode":null,"errorMessage":"hit_count exceeds limit","messagePattern":"hit_count exceeds limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs","lineNumber":31,"sourceCode":"}\n\nimpl PacketRead for SClientCacheBlobStatus {\n    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {\n        let miss_count = VarUInt::read(reader)?.0 as usize;\n        if miss_count > 4096 {\n            return Err(Error::new(\n                std::io::ErrorKind::InvalidData,\n                \"miss_count exceeds limit\",\n            ));\n        }\n        let mut miss_hashes = Vec::with_capacity(miss_count.min(256));\n        for _ in 0..miss_count {\n            miss_hashes.push(u64::read(reader)?);\n        }\n\n        let hit_count = VarUInt::read(reader)?.0 as usize;\n        if hit_count > 4096 {\n            return Err(Error::new(\n                std::io::ErrorKind::InvalidData,\n                \"hit_count exceeds limit\",\n            ));\n        }\n        let mut hit_hashes = Vec::with_capacity(hit_count.min(256));\n        for _ in 0..hit_count {\n            hit_hashes.push(u64::read(reader)?);\n        }\n\n        Ok(Self {\n            miss_hashes,\n            hit_hashes,\n        })\n    }\n}\n","sourceCodeStart":13,"sourceCodeEnd":47,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/server/client_cache_blob_status.rs#L13-L47","documentation":"Guard in SClientCacheBlobStatus::read raising a generic std::io InvalidData error when the declared hit_count in the client cache blob status packet exceeds 4096, protecting against oversized allocation from hostile packets.","triggerScenarios":"Triggered by SClientCacheBlobStatus::read when the second VarUInt (hit_count, read after all miss hashes) is greater than 4096.","commonSituations":"Malicious packets, client bugs, or stream misalignment where the hash reads above consumed wrong offsets making hit_count parse garbage.","solutions":["Disconnect the client sending the oversized blob status","Keep the 4096 cap to bound memory allocation","Log the violation at debug level"],"exampleFix":"// client before\nlet hits = all_cached_blob_hashes();\n// after\nlet hits: Vec<_> = all_cached_blob_hashes().into_iter().take(4096).collect();","handlingStrategy":"validation","validationCode":"fn validate_hit_count(count: u32) -> Result<(), String> {\n    if count > 4096 {\n        return Err(format!(\"hit_count {count} exceeds 4096\"));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match SClientCacheBlobStatus::read(reader) {\n    Err(e) if e.to_string().contains(\"hit_count\") => {\n        log::warn!(\"invalid blob status packet: {e}; dropping client packet\");\n    }\n    other => other?,\n}","preventionTips":["Cap hit blob lists at 4096 entries on the client","Confirm the miss_hashes loop consumed exactly miss_count u64s before hit_count","Keep client/server protocol versions in sync"],"tags":["bedrock","protocol","packet-decoding","limits"],"backgroundTag":"value-out-of-range","analyzedSha":"8d4639e25a57c15e47448ec327c780d41bbf2356","analyzedAt":"2026-09-09T15:32:22.916Z","contentChangedAt":"2026-09-09T15:32:22.916Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}