jstedfast/MailKit · error · ArgumentOutOfRangeException
offset
Error message
offset
What it means
ComputeHash(buffer, offset, count) throws ArgumentOutOfRangeException named "offset" when offset is negative or greater than buffer.Length. MailKit's MD4 (its NTLM-supported MD4 hasher, since .NET dropped MD4) mirrors System.Security.Cryptography hash argument validation so callers get the same guards they'd expect from a HashAlgorithm. It fires before any hashing happens, so no partial state is produced.
Solutions
- Check the offset value at the call site and clamp/fix it to 0..buffer.Length before calling.
- Ensure the offset is into the same array instance actually passed as buffer (not a resized/copied array).
- If passing user-derived offsets, validate with a pre-check (offset >= 0 && offset <= buffer.Length) and reject bad input upstream.
- Wrap in try/catch (ArgumentOutOfRangeException) only at UI/API boundaries to report bad input cleanly.
Example fix
// before
hasher.ComputeHash(data, offset, count); // offset could be -1
// after
if (offset < 0 || offset > data.Length) throw new ArgumentException("bad offset");
hasher.ComputeHash(data, offset, count); Defensive patterns
Strategy: validation
Validate before calling
static void ValidateRange(byte[] buffer, int offset, int count) {
if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException(nameof(offset));
if (count < 0 || offset > buffer.Length - count) throw new ArgumentOutOfRangeException(nameof(count));
} Type guard
static bool IsValidWindow(byte[] buffer, int offset, int count) =>
buffer != null && offset >= 0 && count >= 0 && offset <= buffer.Length && offset <= buffer.Length - count; Try / catch
try { hash = md4.ComputeHash(data, offset, count); }
catch (ArgumentOutOfRangeException ex) { log.LogError(ex, "Bad hash window: {Param}", ex.ParamName); throw new ArgumentException("Invalid offset/count", ex); } Prevention
- Validate offset/count against the same array instance you pass
- Prefer span-style overloads or helper wrappers that clamp ranges
- Unit-test boundary cases: offset 0, offset == Length, empty buffers
When it happens
Trigger: Calling ComputeHash(buffer, offset, count) with offset < 0, or offset > buffer.Length; e.g. ComputeHash(data, -1, data.Length) or ComputeHash(data, data.Length + 1, 0). Also produced by arithmetic bugs where an offset variable underflows (e.g. baseIndex - amount going negative).
Common situations: Slice/copy logic that computes an offset into a padded or chunked buffer; off-by-one when hashing the tail of a message; porting NTLM/NTLMv2 code where a length prefix was mistakenly added to the offset.
Related errors
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/a4223bdba322457e.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Security/Ntlm/MD4.cs:293
HH (ref b, c, d, a, x[13], S34); /* 44 */
HH (ref a, b, c, d, x[ 3], S31); /* 45 */
HH (ref d, a, b, c, x[11], S32); /* 46 */
HH (ref c, d, a, b, x[ 7], S33); /* 47 */
HH (ref b, c, d, a, x[15], S34); /* 48 */
state [0] += a;
state [1] += b;
state [2] += c;
state [3] += d;
}
public byte[] ComputeHash (byte[] buffer, int offset, int count)
{
if (buffer == null)
throw new ArgumentNullException (nameof (buffer));
if (offset < 0 || offset > buffer.Length)
throw new ArgumentOutOfRangeException (nameof (offset));
if (count < 0 || offset > buffer.Length - count)
throw new ArgumentOutOfRangeException (nameof (count));
if (disposed)
throw new ObjectDisposedException (nameof (MD4));
HashCore (buffer, offset, count);
hashValue = HashFinal ();
Initialize ();
return hashValue;
}
public byte[] ComputeHash (byte[] buffer)
{
if (buffer == null)
throw new ArgumentNullException (nameof (buffer));View on GitHub (pinned to 9d3859a785)