{"record":{"id":"42c0a68874128235","repo":"dotnet/wpf","slug":"sr-maxlengthexceedsbuffersize-count-textbuffer-length","errorCode":null,"errorMessage":"SR.MaxLengthExceedsBufferSize (count, textBuffer.Length, startIndex)","messagePattern":"SR\\.MaxLengthExceedsBufferSize \\(count, textBuffer\\.Length, startIndex\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs","lineNumber":1764,"sourceCode":"            int skipCount;\n            int finalCount;\n\n            ArgumentNullException.ThrowIfNull(textBuffer);\n            if (startIndex < 0)\n            {\n                throw new ArgumentException(SR.Format(SR.NegativeValue, \"startIndex\"));\n            }\n            if (startIndex > textBuffer.Length)\n            {\n                throw new ArgumentException(SR.Format(SR.StartIndexExceedsBufferSize, startIndex, textBuffer.Length));\n            }\n            if (count < 0)\n            {\n                throw new ArgumentException(SR.Format(SR.NegativeValue, \"count\"));\n            }\n            if (count > textBuffer.Length - startIndex)\n            {\n                throw new ArgumentException(SR.Format(SR.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex));\n            }\n            Invariant.Assert(textNode != null, \"textNode is expected to be non-null\");\n\n            textContainer.EmptyDeadPositionList();\n\n            if (nodeOffset < 0)\n            {\n                skipCount = 0;\n            }\n            else\n            {\n                skipCount = (direction == LogicalDirection.Forward) ? nodeOffset : textNode.SymbolCount - nodeOffset;\n                symbolOffset += nodeOffset;\n            }\n            finalCount = 0;\n\n            // Loop and combine adjacent text nodes into a single run.\n            // This isn't just a perf optimization.  Because text positions","sourceCodeStart":1746,"sourceCodeEnd":1782,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs#L1746-L1782","documentation":"TextPointer.GetTextInRun also checks that count does not exceed the space available in the destination buffer: count must be <= textBuffer.Length - startIndex. When it is larger, the copy would overflow the buffer, so it throws ArgumentException(SR.MaxLengthExceedsBufferSize) reporting count, buffer length, and start index.","triggerScenarios":"Calling TextPointer.GetTextInRun(direction, textBuffer, startIndex, count) where count > textBuffer.Length - startIndex, e.g. buffer length 10, startIndex 5, count 10 (only 5 slots remain).","commonSituations":"Allocating a buffer for the full run length but passing a startIndex that shrinks the usable space; reusing a stale buffer size after the document text grew; off-by-one in start/end index arithmetic.","solutions":["Clamp the count: count = Math.Min(count, textBuffer.Length - startIndex) before the call.","Ensure startIndex + count <= textBuffer.Length whenever sizing buffers.","If the run may be longer than the buffer, loop: call GetTextInRun repeatedly with the remaining buffer space and advance the pointer."],"exampleFix":"// before\npointer.GetTextInRun(dir, buffer, start, runLength);\n// after\nint count = Math.Min(runLength, buffer.Length - start);\npointer.GetTextInRun(dir, buffer, start, count);","handlingStrategy":"validation","validationCode":"if (count > buffer.Length - startIndex)\n    count = buffer.Length - startIndex;","typeGuard":"static bool FitsBuffer(char[] buf, int start, int count) => start >= 0 && count >= 0 && start + count <= buf.Length;","tryCatchPattern":"try { pointer.GetTextInRun(dir, buffer, start, count); }\ncatch (ArgumentException) { count = buffer.Length - start; pointer.GetTextInRun(dir, buffer, start, count); }","preventionTips":["Always derive count from buffer.Length - startIndex","Re-size buffers when document content changes","Loop for long runs instead of sizing one big buffer"],"tags":["wpf","argument-validation","buffer-overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}