{"record":{"id":"a7fae552fcf8a1d6","repo":"jstedfast/MailKit","slug":"inputbuffer-md4","errorCode":null,"errorMessage":"inputBuffer","messagePattern":"inputBuffer","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"MailKit/Security/Ntlm/MD4.cs","lineNumber":342,"sourceCode":"\n\t\t\tvar buffer = new byte[4096];\n\t\t\tint nread;\n\n\t\t\tdo {\n\t\t\t\tif ((nread = inputStream.Read (buffer, 0, buffer.Length)) > 0)\n\t\t\t\t\tHashCore (buffer, 0, nread);\n\t\t\t} while (nread > 0);\n\n\t\t\thashValue = HashFinal ();\n\t\t\tInitialize ();\n\n\t\t\treturn hashValue;\n\t\t}\n\n\t\tpublic int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)\n\t\t{\n\t\t\tif (inputBuffer == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (inputBuffer));\n\n\t\t\tif (inputOffset < 0 || inputOffset > inputBuffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (inputOffset));\n\n\t\t\tif (inputCount < 0 || inputOffset > inputBuffer.Length - inputCount)\n\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (inputCount));\n\n\t\t\tif (outputBuffer != null) {\n\t\t\t\tif (outputOffset < 0 || outputOffset > outputBuffer.Length - inputCount)\n\t\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (outputOffset));\n\t\t\t}\n\n\t\t\tHashCore (inputBuffer, inputOffset, inputCount);\n\n\t\t\tif (outputBuffer != null)\n\t\t\t\tBuffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);\n\n\t\t\treturn inputCount;","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Security/Ntlm/MD4.cs#L324-L360","documentation":"TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) throws ArgumentNullException named \"inputBuffer\" when the input array is null. TransformBlock implements the ICryptoTransform pattern, so MD4 validates parameters exactly like the framework's crypto transforms do before touching hash state.","triggerScenarios":"Calling TransformBlock(null, 0, len, null, 0) — typical when feeding a null buffer from a streaming loop whose read buffer wasn't allocated, or passing null intentionally assuming an empty update.","commonSituations":"Hand-rolled incremental hashing in NTLM code (hashing key/message in pieces) where a buffer variable stays null on first iteration; refactored code that replaced a real buffer with null to \"skip\" a block.","solutions":["Pass a real (possibly empty) array: TransformBlock(Array.Empty<byte>(), 0, 0, null, 0) for a no-op block.","Fix the buffer allocation that yielded null (allocate before the loop, not conditionally inside it).","Guard incremental loops: only call TransformBlock when buffer != null.","Catch ArgumentNullException at the boundary to identify the null input clearly."],"exampleFix":"// before\ntransform.TransformBlock(chunk, 0, chunk.Length, null, 0); // chunk may be null\n// after\nif (chunk != null && chunk.Length > 0)\n    transform.TransformBlock(chunk, 0, chunk.Length, null, 0);","handlingStrategy":"validation","validationCode":"if (inputBuffer == null)\n    throw new ArgumentNullException(nameof(inputBuffer), \"Provide a buffer (use Array.Empty<byte>() for no-op blocks)\");\ntransform.TransformBlock(inputBuffer, inputOffset, inputCount, outputBuffer, outputOffset);","typeGuard":"static bool CanTransform(byte[] input) => input != null;","tryCatchPattern":"try { transform.TransformBlock(input, 0, input.Length, null, 0); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"inputBuffer\") { log.LogError(ex, \"Null input block\"); throw; }","preventionTips":["Allocate the chunk buffer before the incremental loop","Never pass null where an empty array is meant","Skip the call entirely for null/empty chunks"],"tags":["argument-exception","null","crypto","transformblock"],"backgroundTag":"null-argument","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}