{"record":{"id":"a4223bdba322457e","repo":"jstedfast/MailKit","slug":"offset-md4","errorCode":null,"errorMessage":"offset","messagePattern":"offset","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"MailKit/Security/Ntlm/MD4.cs","lineNumber":293,"sourceCode":"\t\t\tHH (ref b, c, d, a, x[13], S34); /* 44 */\n\t\t\tHH (ref a, b, c, d, x[ 3], S31); /* 45 */\n\t\t\tHH (ref d, a, b, c, x[11], S32); /* 46 */\n\t\t\tHH (ref c, d, a, b, x[ 7], S33); /* 47 */\n\t\t\tHH (ref b, c, d, a, x[15], S34); /* 48 */\n\n\t\t\tstate [0] += a;\n\t\t\tstate [1] += b;\n\t\t\tstate [2] += c;\n\t\t\tstate [3] += d;\n\t\t}\n\n\t\tpublic byte[] ComputeHash (byte[] buffer, int offset, int count)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (buffer));\n\n\t\t\tif (offset < 0 || offset > buffer.Length)\n\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (offset));\n\n\t\t\tif (count < 0 || offset > buffer.Length - count)\n\t\t\t\tthrow new ArgumentOutOfRangeException (nameof (count));\n\n\t\t\tif (disposed)\n\t\t\t\tthrow new ObjectDisposedException (nameof (MD4));\n\n\t\t\tHashCore (buffer, offset, count);\n\t\t\thashValue = HashFinal ();\n\t\t\tInitialize ();\n\n\t\t\treturn hashValue;\n\t\t}\n\n\t\tpublic byte[] ComputeHash (byte[] buffer)\n\t\t{\n\t\t\tif (buffer == null)\n\t\t\t\tthrow new ArgumentNullException (nameof (buffer));","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Security/Ntlm/MD4.cs#L275-L311","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nhasher.ComputeHash(data, offset, count); // offset could be -1\n// after\nif (offset < 0 || offset > data.Length) throw new ArgumentException(\"bad offset\");\nhasher.ComputeHash(data, offset, count);","handlingStrategy":"validation","validationCode":"static void ValidateRange(byte[] buffer, int offset, int count) {\n    if (offset < 0 || offset > buffer.Length) throw new ArgumentOutOfRangeException(nameof(offset));\n    if (count < 0 || offset > buffer.Length - count) throw new ArgumentOutOfRangeException(nameof(count));\n}","typeGuard":"static bool IsValidWindow(byte[] buffer, int offset, int count) =>\n    buffer != null && offset >= 0 && count >= 0 && offset <= buffer.Length && offset <= buffer.Length - count;","tryCatchPattern":"try { hash = md4.ComputeHash(data, offset, count); }\ncatch (ArgumentOutOfRangeException ex) { log.LogError(ex, \"Bad hash window: {Param}\", ex.ParamName); throw new ArgumentException(\"Invalid offset/count\", ex); }","preventionTips":["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"],"tags":["argument-exception","hash","out-of-range","md4"],"backgroundTag":"argument-out-of-range","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"}