jstedfast/MailKit · error · ArgumentOutOfRangeException
inputOffset
Error message
inputOffset
What it means
TransformBlock throws ArgumentOutOfRangeException named "inputOffset" when inputOffset is negative or greater than inputBuffer.Length. This keeps the transform's read window within the input array, mirroring ICryptoTransform argument contracts. It is thrown before HashCore mutates state, so incremental hashing remains consistent.
Solutions
- Recompute/validate inputOffset per call: it must satisfy 0 <= inputOffset <= inputBuffer.Length.
- Track the running offset from the same buffer being transformed; reset it when switching buffers.
- Use safe chunking (offset advances by chunk.Length from 0) instead of manual arithmetic.
- Validate externally supplied offsets before the call and reject with a clear message.
Example fix
// before
transform.TransformBlock(buf, pos, buf.Length - pos, null, 0); // pos may exceed buf.Length
// after
int pos = 0;
while (pos < buf.Length) {
int n = Math.Min(4096, buf.Length - pos);
transform.TransformBlock(buf, pos, n, null, 0);
pos += n;
} Defensive patterns
Strategy: validation
Validate before calling
if (inputOffset < 0 || inputOffset > inputBuffer.Length)
throw new ArgumentOutOfRangeException(nameof(inputOffset)); Type guard
static bool IsValidOffset(byte[] buf, int offset) => offset >= 0 && offset <= buf.Length;
Try / catch
try { transform.TransformBlock(buf, offset, count, null, 0); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "inputOffset") { log.LogError(ex, "inputOffset {Offset} invalid for len {Len}", offset, buf.Length); throw; } Prevention
- Advance running offsets from the same buffer being transformed
- Reset offsets when switching buffers
- Favor simple chunk loops (offset += chunkSize from 0) over manual arithmetic
When it happens
Trigger: Calling TransformBlock(buf, -1, len, null, 0) or TransformBlock(buf, buf.Length + 1, 0, null, 0); incremental loops where a running offset accumulates past the buffer end due to a wrong increment or stale offset variable.
Common situations: Chunked hashing where chunk offsets are computed from previous chunk sizes with an off-by-one; NTLM message assembly code reusing an offset across differently sized buffers.
Related errors
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/20fc3a7496aa903e.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Security/Ntlm/MD4.cs:345
do {
if ((nread = inputStream.Read (buffer, 0, buffer.Length)) > 0)
HashCore (buffer, 0, nread);
} while (nread > 0);
hashValue = HashFinal ();
Initialize ();
return hashValue;
}
public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
if (inputBuffer == null)
throw new ArgumentNullException (nameof (inputBuffer));
if (inputOffset < 0 || inputOffset > inputBuffer.Length)
throw new ArgumentOutOfRangeException (nameof (inputOffset));
if (inputCount < 0 || inputOffset > inputBuffer.Length - inputCount)
throw new ArgumentOutOfRangeException (nameof (inputCount));
if (outputBuffer != null) {
if (outputOffset < 0 || outputOffset > outputBuffer.Length - inputCount)
throw new ArgumentOutOfRangeException (nameof (outputOffset));
}
HashCore (inputBuffer, inputOffset, inputCount);
if (outputBuffer != null)
Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
return inputCount;
}
public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)View on GitHub (pinned to 9d3859a785)