dotnet/wpf · error · ArgumentException

Buffer range is smaller than expected expected size

Error message

Buffer range is smaller than expected expected size

What it means

Thrown by StrokeSerializer.LoadPackets when the button data section of an ISF packet stream claims more bytes than remain in the decoded buffer. The library computes the expected button-byte count from buttonCount*pointCount and validates it against the remaining range before allocating.

Solutions

  1. Re-save the ink from the original application to produce valid ISF
  2. Validate that the ISF stream length matches its internal size fields before decoding
  3. Check that producer/consumer ink serialization versions match
  4. Wrap decode in try-catch and degrade gracefully (drop the stroke)

Example fix

// before
var strokes = DecodeISFIntoStroke(rawBytes); // throws on truncated buffer
// after
try { var strokes = DecodeISFIntoStroke(rawBytes); }
catch (ArgumentException) { Log.Warn("Invalid ISF: button data truncated"); strokes = new StrokeCollection(); }
Defensive patterns

Strategy: validation

Validate before calling

// Check ISF byte stream is complete before decoding
if (isfBytes == null || isfBytes.Length < 8) throw new InvalidDataException("ISF too short");

Type guard

bool IsPlausibleIsfBuffer(byte[] b) => b is { Length: > 8 };

Try / catch

try { DecodeISFIntoStroke(buffer); }
catch (ArgumentException) { DiscardStroke(); }

Prevention

When it happens

Trigger: DecodeISFIntoStroke encounters an ISF stream where buttonCount and pointCount decoded from the packet description imply a byte count larger than the bytes actually available.

Common situations: Corrupt or truncated ISF clipboard payloads, ISF written by non-WPF tools with inconsistent button descriptors, manual editing of persisted ink streams.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs:486

            // Now that we've read packet data, we must read button data if it is there
            byte[] buttonData = null;
            // since the button state is a simple bit value (either down or up), the button state
            // for a series of packets is packed into an array of bits rather than integers
            // For example, if there are 16 packets, and 2 buttons, then 32 bits can be used (e.g. 1 32-bit integer)
            if (0 != locallyDecodedBytesRemaining && buttonCount > 0)
            {
                    // calculate the number of full bytes used for buttons per packet
                    //   Example: 10 buttons would require 1 full byte
                int fullBytesForButtonsPerPacket = buttonCount / Native.BitsPerByte;
                    // calculate the number of bits that spill beyond the full byte boundary
                    //   Example: 10 buttons would require 2 extra bits (8 fit in a full byte)
                int partialBitsForButtonsPerPacket = buttonCount % Native.BitsPerByte;

                // Now figure out how many bytes we need to read for the button data
                localBytesRead = (uint)((buttonCount * pointCount + 7) / Native.BitsPerByte);
                if (localBytesRead > locallyDecodedBytesRemaining)
                {
                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Buffer range is smaller than expected expected size"));
                }
                locallyDecodedBytesRemaining -= localBytesRead;

                int buttonSizeInBytes = (buttonCount + 7)/Native.BitsPerByte;
                buttonData = new byte[pointCount * buttonSizeInBytes];

                // Create a bit reader to unpack the bits from the ISF stream into
                //    loosely packed byte buffer (e.g. button data aligned on full byte
                //    boundaries only)
                BitStreamReader bitReader =
                    new BitStreamReader(inputBuffer, (uint)buttonCount * pointCount);

                // unpack the button data into each packet
                int byteCounter = 0;
                while (!bitReader.EndOfStream)
                {
                    // unpack the fully bytes first
                    for (int fullBytes = 0; fullBytes < fullBytesForButtonsPerPacket; fullBytes++)

View on GitHub (pinned to 81131a70a4)