{"record":{"id":"34189d2773a00868","repo":"Pumpkin-MC/Pumpkin","slug":"block-actions-count-exceeds-limit","errorCode":null,"errorMessage":"block_actions count exceeds limit","messagePattern":"block_actions count exceeds limit","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/server/player_auth_input.rs","lineNumber":98,"sourceCode":"        // 1. Perform Item Interaction\n        let item_interaction = if bool::read(reader)? && bool::read(reader)? {\n            Some(PlayerInventoryAction::read(reader)?)\n        } else {\n            None\n        };\n\n        // 2. Item Stack Request\n        let item_stack_request = if bool::read(reader)? && bool::read(reader)? {\n            Some(crate::bedrock::server::item_stack_request::ItemStackRequest::read(reader)?)\n        } else {\n            None\n        };\n\n        // 3. Block Actions\n        let block_actions = if bool::read(reader)? && bool::read(reader)? {\n            let count = VarUInt::read(reader)?.0 as usize;\n            if count > 1024 {\n                return Err(Error::new(\n                    ErrorKind::InvalidData,\n                    \"block_actions count exceeds limit\",\n                ));\n            }\n            let mut actions = Vec::with_capacity(count.min(64));\n            for _ in 0..count {\n                actions.push(PlayerBlockAction::read(reader)?);\n            }\n            Some(actions)\n        } else {\n            None\n        };\n\n        // 4. Vehicle Info (Matches Go logic)\n        let vehicle_rotation = (bool::read(reader)? && bool::read(reader)?)\n            .then(|| Vector2::<f32>::read(reader))\n            .transpose()?;\n        let vehicle_unique_id = (bool::read(reader)? && bool::read(reader)?)","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/server/player_auth_input.rs#L80-L116","documentation":"Thrown when decoding the BlockActions section of a Bedrock PlayerAuthInput packet whose declared action count exceeds the hard limit of 1024. This prevents a client from making the server allocate/parse an unbounded number of block actions in a single packet.","triggerScenarios":"PlayerAuthInput packet where both leading bools are true and the following VarUInt count is > 1024.","commonSituations":"Malicious or buggy clients sending inflated block-action counts to stress the server (DoS vector), or a protocol mismatch causing garbage to be read as the count.","solutions":["Ensure the client uses the correct Bedrock protocol version matching the server","Check for packet corruption or desync earlier in the stream","If a legit client needs more than 1024 actions per packet, raise the limit in player_auth_input.rs with care","Reject/ban clients that repeatedly send oversized counts"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"let count = VarUInt::read(reader)?.0 as usize;\nif count > 1024 { return Err(...); } // caller-side: reject before iterating","typeGuard":null,"tryCatchPattern":"match read_packet(&mut stream) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => warn!(\"oversized block_actions, dropping packet\"),\n    other => other,\n}","preventionTips":["Cap all VarUInt-derived vector lengths before allocating","Use Vec::with_capacity(count.min(N)) to avoid count-based OOM","Rate-limit or ban clients repeatedly sending oversized counts","Add decoder unit tests for boundary counts (1024, 1025)"],"tags":["bedrock","protocol","dos-protection","packet-decoding"],"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-17T15:17:12.973Z"}