{"record":{"id":"5173f9231563b22d","repo":"Pumpkin-MC/Pumpkin","slug":"extra-data-len-exceeds-1mb-limit","errorCode":null,"errorMessage":"extra_data_len exceeds 1MB limit","messagePattern":"extra_data_len exceeds 1MB limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/network_item.rs","lineNumber":302,"sourceCode":"    fn read<R: Read>(buf: &mut R) -> Result<Self, Error> {\n        let id = i16::read(buf)?;\n\n        let stack_size = u16::read(buf)?;\n        let aux_value = VarUInt::read(buf)?;\n\n        let has_net_id = bool::read(buf)?;\n        let net_id = if has_net_id {\n            let stack_id = VarInt::read(buf)?;\n            NonZero::new(stack_id.0)\n        } else {\n            None\n        };\n\n        let block_runtime_id = VarUInt::read(buf)?;\n\n        let extra_data_len = VarUInt::read(buf)?.0 as usize;\n        if extra_data_len > 1_048_576 {\n            return Err(Error::new(\n                ErrorKind::InvalidData,\n                \"extra_data_len exceeds 1MB limit\",\n            ));\n        }\n        let mut extra_data = vec![0u8; extra_data_len];\n        buf.read_exact(&mut extra_data)?;\n\n        Ok(Self {\n            id,\n            stack_size,\n            aux_value,\n            block_runtime_id,\n            extra_data,\n            net_id,\n        })\n    }\n}\n","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/network_item.rs#L284-L320","documentation":"Raised when reading an item's extra data block: the VarUInt length prefix exceeds 1,048,576 bytes (1MB). Like the user_data guard, this prevents unbounded allocation from corrupt or malicious input and fails with ErrorKind::InvalidData before the vec! allocation.","triggerScenarios":"Deserializing a network item (network_item.rs:302 read path) where extra_data_len > 1MB — stream desync, corrupted buffer, or crafted packet.","commonSituations":"Malicious client inflating the length field; parser reading the wrong field as the length after a version mismatch; truncated/mixed-up packet stream.","solutions":["Audit preceding field reads for desync — a misread varint is the usual cause.","Verify protocol versions align between reader and writer.","Reject the packet (drop or disconnect) instead of retrying the same bytes.","Writers must clamp extra data to <=1MB before serialization."],"exampleFix":"// before\nlet extra = vec![0u8; extra_data_len];\nbuf.read_exact(&mut extra)?;\n// after\nif extra_data_len > 1_048_576 {\n    return Err(Error::new(ErrorKind::InvalidData, \"extra_data_len exceeds 1MB limit\"));\n}","handlingStrategy":"try-catch","validationCode":"// caller-side pre-check when parsing manually\nif extra_data_len > 1_048_576 { return Err(malformed_packet()); }","typeGuard":null,"tryCatchPattern":"match read_item_with_extra_data(buf) {\n    Ok(v) => v,\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        disconnect_peer(\"oversized extra data\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Cap extra data at 1MB on the write side.","Treat repeated occurrences as a malicious-client signal and disconnect.","Check packet alignment before blaming the length value."],"tags":["protocol","bedrock","deserialization","malformed-packet"],"backgroundTag":"payload-too-large","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"}