{"record":{"id":"73948074771cb0e3","repo":"peass-ng/PEASS-ng","slug":"output-buffer-too-short","errorCode":null,"errorMessage":"Output buffer too short","messagePattern":"Output buffer too short","errorType":"exception","errorClass":"DataLengthException","httpStatus":null,"severity":"error","filePath":"winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/engines/ThreefishEngine.cs","lineNumber":290,"sourceCode":"\t\tpublic virtual bool IsPartialBlockOkay\n\t\t{\n\t\t\tget { return false; }\n\t\t}\n\n\t\tpublic virtual int GetBlockSize()\n\t\t{\n\t\t\treturn blocksizeBytes;\n\t\t}\n\n\t\tpublic virtual void Reset()\n\t\t{\n\t\t}\n\n\t\tpublic virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)\n\t\t{\n\t\t\tif ((outOff + blocksizeBytes) > outBytes.Length)\n\t\t\t{\n\t\t\t\tthrow new DataLengthException(\"Output buffer too short\");\n\t\t\t}\n\n\t\t\tif ((inOff + blocksizeBytes) > inBytes.Length)\n\t\t\t{\n\t\t\t\tthrow new DataLengthException(\"Input buffer too short\");\n\t\t\t}\n\n\t\t\tfor (int i = 0; i < blocksizeBytes; i += 8)\n\t\t\t{\n\t\t\t\tcurrentBlock[i >> 3] = BytesToWord(inBytes, inOff + i);\n\t\t\t}\n\t\t\tProcessBlock(this.currentBlock, this.currentBlock);\n\t\t\tfor (int i = 0; i < blocksizeBytes; i += 8)\n\t\t\t{\n\t\t\t\tWordToBytes(this.currentBlock[i >> 3], outBytes, outOff + i);\n\t\t\t}\n\n\t\t\treturn blocksizeBytes;","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/peass-ng/PEASS-ng/blob/53fb989abc2219826385683a6fee826bd6cd38d6/winPEAS/winPEASexe/winPEAS/3rdParty/BouncyCastle/crypto/engines/ThreefishEngine.cs#L272-L308","documentation":"ProcessBlock verifies that the output buffer has room for one full block (blocksizeBytes) starting at outOff, throwing DataLengthException if not. The input buffer is checked immediately afterwards for the same condition.","triggerScenarios":"Calling ProcessBlock(in, inOff, out, outOff) where outBytes.Length - outOff < blocksizeBytes (e.g. writing a 64-byte Threefish-512 block into a 32-byte buffer or near the end of a shared buffer).","commonSituations":"Allocating output buffer sized for a smaller Threefish variant; outOff placed too close to the end of a reusable buffer; forgetting that Threefish is unbuffered and processes exactly one block per call.","solutions":["Allocate outBytes with at least outOff + blocksizeBytes bytes (block size of the engine variant)","Set outOff so a full block fits within the buffer","Check GetBlockSize() at runtime to size buffers dynamically"],"exampleFix":"// before\nbyte[] output = new byte[32];\nengine.ProcessBlock(input, 0, output, 0); // engine is Threefish-512\n// after\nbyte[] output = new byte[engine.GetBlockSize()];\nengine.ProcessBlock(input, 0, output, 0);","handlingStrategy":"validation","validationCode":"int bs = engine.GetBlockSize();\nif (outBytes == null || outBytes.Length - outOff < bs)\n    throw new ArgumentException(\"Output buffer must hold at least one block (\" + bs + \" bytes)\");\nif (inBytes == null || inBytes.Length - inOff < bs)\n    throw new ArgumentException(\"Input buffer must hold at least one block (\" + bs + \" bytes)\");\nengine.ProcessBlock(inBytes, inOff, outBytes, outOff);","typeGuard":"bool CanProcessBlock(ThreefishEngine e, byte[] inB, int inOff, byte[] outB, int outOff) => inB != null && outB != null && inOff + e.GetBlockSize() <= inB.Length && outOff + e.GetBlockSize() <= outB.Length;","tryCatchPattern":"try { int n = engine.ProcessBlock(in, inOff, out, outOff); }\ncatch (DataLengthException ex) { /* grow buffer and retry */ }","preventionTips":["Size output buffers with engine.GetBlockSize(), not hardcoded constants","Leave room for a full block when reusing shared buffers","Remember ProcessBlock handles exactly one block with no internal buffering"],"tags":["csharp","cryptography","threefish","buffer"],"backgroundTag":"output-buffer-too-short","analyzedSha":"53fb989abc2219826385683a6fee826bd6cd38d6","analyzedAt":"2026-09-02T04:25:09.259Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T11:17:12.671Z"}