{"record":{"id":"8366a1f6363be162","repo":"dotnet/wpf","slug":"invalid-isf-data-strokeserializer","errorCode":null,"errorMessage":"Invalid ISF data","messagePattern":"Invalid ISF data","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs","lineNumber":279,"sourceCode":"                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)\n                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Invalid ISF data\"));\n\n                                remainingBytesInStrokeBlock -= locallyDecodedBytes;\n\n                                uint propsize;\n\n                                locallyDecodedBytes = SerializationHelper.Decode(stream, out propsize);\n                                if (locallyDecodedBytes > remainingBytesInStrokeBlock)\n                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Invalid ISF data\"));\n\n                                remainingBytesInStrokeBlock -= locallyDecodedBytes;\n\n                                // Compressed data totalBytesInStrokeBlockOfIsfStream\n                                propsize += 1;\n\n                                // Make sure we have enough data to read\n                                if (propsize > remainingBytesInStrokeBlock)\n                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Invalid ISF data\"));\n\n                                byte[] in_buffer = new byte[propsize];\n\n                                uint bytesRead = StrokeCollectionSerializer.ReliableRead(stream, in_buffer, propsize);\n                                if (propsize != bytesRead)\n                                {\n                                    throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Read different size from stream then expected\"));\n                                }\n\n                                byte[] out_buffer = Compressor.DecompressPropertyData(in_buffer);\n\n                                System.Diagnostics.Debug.Fail(\"ExtendedProperties for points are not supported\");\n\n                                // skip the bytes in both success & failure cases\n                                // Note: Point ExtendedProperties are discarded\n                                remainingBytesInStrokeBlock -= propsize;\n                            }\n                        }","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/StrokeSerializer.cs#L261-L297","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate the ISF file integrity (complete header, sizes) before calling Deserialize","Re-export the ink from the source application rather than deserializing the damaged file","Ensure the stream is seekable and positioned at the ISF payload start","Catch ArgumentException from Deserialize and degrade gracefully (drop the corrupt stroke)","If writing ISF, ensure each property-block size field equals the exact compressed byte count"],"exampleFix":"// before\ntry { scs.Deserialize(suspectStream); }\n// after\ntry { scs.Deserialize(suspectStream); }\ncatch (ArgumentException ex) {\n    log.Warn(\"Corrupt ISF stroke data discarded\", ex);\n    strokeCollection = new StrokeCollection(); // degrade gracefully\n}","handlingStrategy":"try-catch","validationCode":"// sanity check: ISF must be complete; verify declared block sizes fit in stream\nstatic bool IsCompleteIsf(Stream s) => s.CanSeek && s.Length >= 8;","typeGuard":null,"tryCatchPattern":"try { scs.Deserialize(stream); }\ncatch (ArgumentException ex) {\n    log.Warn(\"ISF stroke property size exceeds block\", ex);\n    strokeCollection = LoadBackupInk() ?? new StrokeCollection();\n}","preventionTips":["Verify file integrity (checksum/length) before deserializing ink","Never hand-build ISF block size fields; use the serializer for writing","Handle per-stroke failures gracefully instead of failing the whole collection"],"tags":["ink","isf","deserialization","corrupt-input","wpf"],"backgroundTag":"invalid-argument-format","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}