dotnet/wpf · error · ArgumentException

SR.StartIndexExceedsBufferSize (startIndex…

Error message

SR.StartIndexExceedsBufferSize (startIndex, textBuffer.Length)

What it means

The same GetTextInRun validation checks that startIndex does not exceed the textBuffer's length; startIndex > textBuffer.Length throws ArgumentException(SR.StartIndexExceedsBufferSize) with startIndex and buffer length. The write position must fall within the destination array for the run text to be copied.

Solutions

  1. Validate startIndex <= textBuffer.Length before calling, and size the buffer to at least startIndex + count.
  2. Reallocate or enlarge the destination buffer when the requested range exceeds its length.
  3. Track remaining capacity (textBuffer.Length - startIndex) and clamp count to it.

Example fix

// before
tp.GetTextInRunLogicalDirection(direction, buffer, startIndex, count);
// after
count = Math.Min(count, buffer.Length - startIndex);
if (count > 0)
    tp.GetTextInRunLogicalDirection(direction, buffer, startIndex, count);
Defensive patterns

Strategy: validation

Validate before calling

if (startIndex > buffer.Length) throw new InvalidOperationException("buffer too small");
count = Math.Min(count, buffer.Length - startIndex);

Try / catch

try { tp.GetTextInRunLogicalDirection(direction, buffer, startIndex, count); }
catch (ArgumentException ex) when (ex.Message.Contains("buffer")) { buffer = new char[startIndex + count]; }

Prevention

When it happens

Trigger: Calling GetTextInRun with startIndex greater than textBuffer.Length — e.g. a startIndex equal to a larger buffer's length after the buffer was reallocated smaller, or passing document offsets as buffer indices by mistake.

Common situations: Reusing a buffer sized for an earlier, longer run; confusing document position offsets with char[] indices; computing startIndex from a previous call's return count without checking remaining capacity.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/fd2813699639fcfe. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs:1756

                ancestor = ancestor.Parent as TextElement;
            }

            return ancestor as ListItem;
        }

        internal static int GetTextInRun(TextContainer textContainer, int symbolOffset, TextTreeTextNode textNode, int nodeOffset, LogicalDirection direction, char[] textBuffer, int startIndex, int count)
        {
            int skipCount;
            int finalCount;

            ArgumentNullException.ThrowIfNull(textBuffer);
            if (startIndex < 0)
            {
                throw new ArgumentException(SR.Format(SR.NegativeValue, "startIndex"));
            }
            if (startIndex > textBuffer.Length)
            {
                throw new ArgumentException(SR.Format(SR.StartIndexExceedsBufferSize, startIndex, textBuffer.Length));
            }
            if (count < 0)
            {
                throw new ArgumentException(SR.Format(SR.NegativeValue, "count"));
            }
            if (count > textBuffer.Length - startIndex)
            {
                throw new ArgumentException(SR.Format(SR.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex));
            }
            Invariant.Assert(textNode != null, "textNode is expected to be non-null");

            textContainer.EmptyDeadPositionList();

            if (nodeOffset < 0)
            {
                skipCount = 0;
            }
            else

View on GitHub (pinned to 81131a70a4)