{"record":{"id":"f78b17f812b9bbcb","repo":"Pumpkin-MC/Pumpkin","slug":"varlong-is-too-big-overflow","errorCode":null,"errorMessage":"VarLong is too big (overflow)","messagePattern":"VarLong is too big \\(overflow\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/pumpkin-protocol/src/codec/var_long.rs","lineNumber":123,"sourceCode":"    }\n}\n\nimpl PacketRead for VarLong {\n    fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {\n        let mut val: u64 = 0;\n        let mut shift = 0;\n\n        loop {\n            let byte = u8::read(reader)?;\n            val |= ((byte & 0x7F) as u64) << shift;\n\n            if (byte & 0x80) == 0 {\n                break;\n            }\n\n            shift += 7;\n            if shift >= 64 {\n                return Err(Error::new(\n                    std::io::ErrorKind::InvalidData,\n                    \"VarLong is too big (overflow)\",\n                ));\n            }\n        }\n\n        let decoded = ((val >> 1) as i64) ^ -((val & 1) as i64);\n\n        Ok(Self(decoded))\n    }\n}\n\nimpl PacketWrite for VarLong {\n    fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {\n        let mut val = ((self.0 << 1) ^ (self.0 >> 63)) as u64;\n\n        while val > 0x7F {\n            ((val as u8 & 0x7F) | 0x80).write(writer)?;","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/Pumpkin-MC/Pumpkin/blob/8d4639e25a57c15e47448ec327c780d41bbf2356/crates/pumpkin-protocol/src/codec/var_long.rs#L105-L141","documentation":"Thrown when decoding a VarLong whose value does not terminate within 10 bytes (shift reaches 64 bits before the continuation bit clears). The library treats this as data corruption/overflow and returns InvalidData rather than wrapping around.","triggerScenarios":"Reading a VarLong with the 0x80 continuation bit still set after 10 groups; stream desync or reading a signed field with an unsigned codec; corrupt/truncated input.","commonSituations":"Protocol version mismatch shifting field boundaries; malicious or fuzzed packets; a broken intermediary mangling the stream.","solutions":["Check for upstream decode desync — a mis-sized earlier field shifts all later reads.","Verify protocol versions match between client and server; update pumpkin if the protocol changed.","Capture and dump raw bytes near the failure to confirm the stream position is correct.","If intentionally decoding untrusted data, validate length before reading and close the connection cleanly."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match VarLong::read_decode(&mut reader) {\n    Ok(v) => Ok(v),\n    Err(e) if e.to_string().contains(\"too big\") => {\n        log::warn!(\"VarLong overflow; dropping connection\");\n        Err(DecodeError::Desync)\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["Close the session on the first malformed VarLong; desync never self-heals.","Keep client/server protocol versions aligned.","Rate-limit or kick sources that send repeated malformed frames."],"tags":["protocol","deserialization","varlong","overflow"],"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"}