{"record":{"id":"1ddd5f88354a2422","repo":"dotnet/wpf","slug":"invalid-isf-data","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/InkSerializer.cs","lineNumber":208,"sourceCode":"        #region Private Methods\n\n        /// <summary>\n        /// Loads the strokeIds from the stream, we need to do this to decrement the count of bytes\n        /// </summary>\n        internal uint LoadStrokeIds(Stream isfStream, uint cbSize)\n        {\n            if (0 == cbSize)\n                return 0;\n\n            uint cb;\n            uint cbTotal = cbSize;\n\n            // First decode the no of ids\n            uint count;\n\n            cb = SerializationHelper.Decode(isfStream, out count);\n            if (cb > cbTotal)\n                throw new ArgumentException(ISFDebugMessage(\"Invalid ISF data\"), nameof(isfStream));\n\n            cbTotal -= cb;\n            if (0 == count)\n                return (cbSize - cbTotal);\n\n            cb = cbTotal;\n\n            byte[] inputdata = new byte[cb];\n\n            // read the stream\n            uint bytesRead = StrokeCollectionSerializer.ReliableRead(isfStream, inputdata, cb);\n            if (cb != bytesRead)\n            {\n                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Read different size from stream then expected\"), nameof(isfStream));\n            }\n            cbTotal -= cb;\n\n            if (0 != cbTotal)","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/InkSerializer.cs#L190-L226","documentation":"LoadStrokeIds decodes the stroke-ID count from the raw ISF stream and throws ArgumentException(\"Invalid ISF data\") when the encoded count occupies more bytes than remain (cb > cbTotal). This is a structural validation: the ID-count field cannot exceed the remaining payload, so the data is malformed.","triggerScenarios":"DecodeRawISF on a stream whose stroke-ID block claims a byte length larger than the remaining data, typically via DecodeRawISF/DecodeISF triggered by new StrokeCollection(Stream).","commonSituations":"Truncated or corrupted ISF payloads, offsets computed incorrectly when embedding ISF in GIF, ink data produced by incompatible writers.","solutions":["Verify the ISF payload is complete and uncorrupted before loading","Re-save the ink data from the original application","Catch ArgumentException around StrokeCollection construction","Check that any ISF-in-GIF extraction logic reads the correct byte range"],"exampleFix":"// before\nvar strokes = new StrokeCollection(gifStream);\n// after\ntry { var strokes = new StrokeCollection(gifStream); }\ncatch (ArgumentException ex) { if (ex.Message.Contains(\"Invalid ISF\")) { /* handle corrupt ink */ } }","handlingStrategy":"validation","validationCode":"// verify the stream is a complete ISF/GIF payload before construction\nbool HasValidHeader(Stream s) {\n  var b = new byte[8]; int n = s.Read(b,0,8); s.Position = 0;\n  return n == 8 && (b[0]==0x89 && b[1]==(byte)'P' || b[0]==(byte)'G');\n}","typeGuard":null,"tryCatchPattern":"try { strokes = new StrokeCollection(stream); }\ncatch (ArgumentException ex) when (ex.ParamName == \"stream\") { HandleCorruptInk(); }","preventionTips":["Extract ISF from GIF containers using exact documented offsets","Validate payload integrity before decode","Re-save corrupted ink from the original application"],"tags":["ink","isf","validation","corrupt-data"],"backgroundTag":"schema-validation-failed","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"}