{"record":{"id":"08b2af6015919cf0","repo":"dotnet/wpf","slug":"sr-format-sr-startindexexceedsbuffersize-startindex","errorCode":null,"errorMessage":"SR.Format(SR.StartIndexExceedsBufferSize, startIndex, textBuffer.Length)","messagePattern":"SR\\.Format\\(SR\\.StartIndexExceedsBufferSize, startIndex, textBuffer\\.Length\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentSequenceTextPointer.cs","lineNumber":662,"sourceCode":"            return thisTp.ChildPointer.GetTextRunLength(direction);\n        }\n\n        /// <summary>\n        /// <see cref=\"ITextPointer.GetTextInRun(LogicalDirection,char[],int,int)\"/>\n        /// </summary>\n        /// <remarks>Only reutrn uninterrupted runs of text</remarks>\n        public static int GetTextInRun(DocumentSequenceTextPointer thisTp, LogicalDirection direction, char[] textBuffer, int startIndex, int count)\n        {\n            ValidationHelper.VerifyDirection(direction, \"direction\");\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\n            return thisTp.ChildPointer.GetTextInRun(direction, textBuffer, startIndex, count);\n        }\n\n        /// <summary>\n        /// <see cref=\"ITextPointer.GetAdjacentElement\"/>\n        /// </summary>\n        /// <remarks>Return null if the embedded object does not exist</remarks>\n        public static object GetAdjacentElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentSequenceTextPointer.cs#L644-L680","documentation":"GetTextInRun throws ArgumentException when startIndex exceeds textBuffer.Length, because the caller asked to begin copying text past the end of the destination buffer. The resource StartIndexExceedsBufferSize includes the supplied index and buffer length to help diagnose the mismatch.","triggerScenarios":"Calling GetTextInRun(direction, textBuffer, startIndex, count) where startIndex > textBuffer.Length — typically a stale index after the buffer shrank or an index from a different buffer.","commonSituations":"Reusing an index computed for a previous (longer) buffer; off-by-one passing buffer.Length + 1; passing an index belonging to a sibling text container.","solutions":["Validate startIndex <= textBuffer.Length before the call and pass a correctly sized buffer.","Recompute the index against the current buffer instead of caching it.","Clamp startIndex to textBuffer.Length if appending semantics are intended."],"exampleFix":"// before\npointer.GetTextInRun(dir, buffer, buffer.Length + 1, 0);\n// after\nvar start = Math.Min(startIndex, buffer.Length);\npointer.GetTextInRun(dir, buffer, start, buffer.Length - start);","handlingStrategy":"validation","validationCode":"if (startIndex > buffer.Length) throw new ArgumentOutOfRangeException(nameof(startIndex), startIndex, $\"Exceeds buffer length {buffer.Length}.\");","typeGuard":null,"tryCatchPattern":"try { pointer.GetTextInRun(dir, buffer, start, count); } catch (ArgumentException) { start = Math.Min(start, buffer.Length); }","preventionTips":["Recompute indices against the current buffer, never cache across resizes.","Pass buffer.Length as an explicit size and derive start from it.","Use bounds-checked helpers (string.Substring-style clamping) before calling."],"tags":["argument-validation","textpointer","wpf"],"backgroundTag":"argument-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"}