{"record":{"id":"94894ed81e2f9e17","repo":"Pumpkin-MC/Pumpkin","slug":"item-string-array-length-out-of-bounds","errorCode":null,"errorMessage":"item string array length out of bounds","messagePattern":"item string array length out of bounds","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/bedrock/network_item.rs","lineNumber":569,"sourceCode":"    }\n}\n\nfn write_user_data_strings<W: Write>(writer: &mut W, values: &[String]) -> Result<(), Error> {\n    (values.len() as i32).write(writer)?;\n    for value in values {\n        let bytes = value.as_bytes();\n        let len = u16::try_from(bytes.len())\n            .map_err(|_| Error::new(std::io::ErrorKind::InvalidInput, \"item string too long\"))?;\n        writer.write_all(&len.to_be_bytes())?;\n        writer.write_all(bytes)?;\n    }\n    Ok(())\n}\n\nfn read_user_data_strings<R: Read>(reader: &mut R) -> Result<Vec<String>, Error> {\n    let len = i32::read(reader)?;\n    if !(0..=1024).contains(&len) {\n        return Err(Error::new(\n            std::io::ErrorKind::InvalidData,\n            \"item string array length out of bounds\",\n        ));\n    }\n    let mut values = Vec::with_capacity((len as usize).min(32));\n    for _ in 0..len {\n        let mut length = [0; 2];\n        reader.read_exact(&mut length)?;\n        let str_len = usize::from(u16::from_be_bytes(length));\n        if str_len > 32767 {\n            return Err(Error::new(\n                std::io::ErrorKind::InvalidData,\n                \"item string too long\",\n            ));\n        }\n        let mut bytes = vec![0; str_len];\n        reader.read_exact(&mut bytes)?;\n        values.push(","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/bedrock/network_item.rs#L551-L587","documentation":"This error is thrown while decoding an ItemComponentPacket's user data from a Bedrock client. The packet contains two string arrays (place_on_blocks and destroy_blocks), each prefixed with an i32 count. The library rejects any declared count below 0 or above 1024 because a hostile or malformed count would otherwise cause enormous allocations or long decode loops.","triggerScenarios":"Triggered by ItemComponentPacket::read -> read_user_data when the i32 array length field for place_on_blocks or destroy_blocks parses to a negative value or a value greater than 1024.","commonSituations":"Malicious or corrupted packets from untrusted clients, protocol version mismatches where the client serializes the array differently, desynchronized stream parsing that reads garbage bytes as the length field.","solutions":["Verify the client and server protocol versions match; a desync shifts field boundaries and corrupts the length field.","Check the sending mod/client code that builds the item user data to ensure it writes correct array counts.","Capture and inspect the raw packet payload to confirm whether the bytes are misaligned or genuinely out of range.","If the value is genuinely large, reduce the number of place_on_blocks/destroy_blocks entries sent (limit is 1024)."],"exampleFix":"// before: sending arbitrary-length arrays\nlet place_on: Vec<String> = load_all_blocks(); // may exceed 1024\n// after\nlet place_on: Vec<String> = load_all_blocks().into_iter().take(1024).collect();","handlingStrategy":"validation","validationCode":"fn validate_string_array_len(len: i32) -> Result<(), String> {\n    if !(0..=1024).contains(&len) {\n        return Err(format!(\"array length {len} out of range 0..=1024\"));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match packet_result {\n    Err(e) if e.to_string().contains(\"out of bounds\") => {\n        log::warn!(\"dropping malformed item packet: {e}\");\n        // disconnect or ignore peer\n    }\n    other => other?,\n}","preventionTips":["Cap array sizes on the sender side before serialization","Validate protocol versions between client and server","Log raw packet bytes for any decode failure to detect desync early"],"tags":["bedrock","protocol","deserialization","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-16T04:17:20.429Z"}