dotnet/wpf · error · ArgumentException

Invalid ISF data

Error message

Invalid ISF data

What it means

Thrown by StrokeSerializer.DecodeISFIntoStroke when a stroke's decoded property data size (propsize) exceeds the remaining bytes in the stroke block of the ISF stream. The decoder would otherwise read past the block boundary, so it rejects the input as corrupt.

Solutions

  1. Validate the ISF file integrity (complete header, sizes) before calling Deserialize
  2. Re-export the ink from the source application rather than deserializing the damaged file
  3. Ensure the stream is seekable and positioned at the ISF payload start
  4. Catch ArgumentException from Deserialize and degrade gracefully (drop the corrupt stroke)
  5. If writing ISF, ensure each property-block size field equals the exact compressed byte count

Example fix

// before
try { scs.Deserialize(suspectStream); }
// after
try { scs.Deserialize(suspectStream); }
catch (ArgumentException ex) {
    log.Warn("Corrupt ISF stroke data discarded", ex);
    strokeCollection = new StrokeCollection(); // degrade gracefully
}
Defensive patterns

Strategy: try-catch

Validate before calling

// sanity check: ISF must be complete; verify declared block sizes fit in stream
static bool IsCompleteIsf(Stream s) => s.CanSeek && s.Length >= 8;

Try / catch

try { scs.Deserialize(stream); }
catch (ArgumentException ex) {
    log.Warn("ISF stroke property size exceeds block", ex);
    strokeCollection = LoadBackupInk() ?? new StrokeCollection();
}

Prevention

When it happens

Trigger: Deserializing an ISF stream where an embedded stroke attribute/property block claims a compressed payload larger than the declared stroke-block remainder — truncated files, corrupted streams, or malformed hand-built ISF.

Common situations: Loading ink files damaged in storage/transfer; ISF produced by non-Windows or third-party ink tools with inconsistent size headers; passing a mispositioned stream so size headers are misread.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                                uint propsize;

                                locallyDecodedBytes = SerializationHelper.Decode(stream, out propsize);
                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                remainingBytesInStrokeBlock -= locallyDecodedBytes;

                                // Compressed data totalBytesInStrokeBlockOfIsfStream
                                propsize += 1;

                                // Make sure we have enough data to read
                                if (propsize > remainingBytesInStrokeBlock)
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Invalid ISF data"));

                                byte[] in_buffer = new byte[propsize];

                                uint bytesRead = StrokeCollectionSerializer.ReliableRead(stream, in_buffer, propsize);
                                if (propsize != bytesRead)
                                {
                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage("Read different size from stream then expected"));
                                }

                                byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);

                                System.Diagnostics.Debug.Fail("ExtendedProperties for points are not supported");

                                // skip the bytes in both success & failure cases
                                // Note: Point ExtendedProperties are discarded
                                remainingBytesInStrokeBlock -= propsize;
                            }
                        }

View on GitHub (pinned to 81131a70a4)