{"record":{"id":"301ce6b2c473d2bd","repo":"dotnet/wpf","slug":"read-different-size-from-stream-then-expected-301ce6","errorCode":null,"errorMessage":"Read different size from stream then expected","messagePattern":"Read different size from stream then expected","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/DrawingAttributeSerializer.cs","lineNumber":225,"sourceCode":"                        if (KnownTagCache.KnownTagIndex.Mantissa == (KnownTagCache.KnownTagIndex)dw)\n                        {\n                            uint cbInSize;\n                            // First thing that is in there is maximumStreamSize of the data\n                            cb = SerializationHelper.Decode (stream, out cbInSize);\n                            maximumStreamSize -= cb;\n\n                            // in maximumStreamSize is one more than the decoded no\n                            cbInSize++;\n                            if (cbInSize > maximumStreamSize)\n                            {\n                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"ISF size if greater then maximum stream size\"));\n                            }\n                            byte[] in_data = new byte[cbInSize];\n\t\t\t\t\t\t\t\n                            uint bytesRead = (uint) stream.Read (in_data, 0, (int)cbInSize);\n                            if (cbInSize != bytesRead)\n                            {\n                                throw new ArgumentException(StrokeCollectionSerializer.ISFDebugMessage(\"Read different size from stream then expected\"));\n                            }\n\n                            byte[] out_buffer = Compressor.DecompressPropertyData (in_data);\n                            using (MemoryStream localStream = new MemoryStream(out_buffer))\n                            using (BinaryReader rdr = new BinaryReader(localStream))\n                            {\n                                short sFraction = rdr.ReadInt16();\n                                _size += (double)(sFraction / DrawingAttributes.StylusPrecision);\n\n                                maximumStreamSize -= cbInSize;\n\t\t\t                }\n                        }\n                        else\n                        {\n                            // Seek it back by cb\n                            stream.Seek (-cb, SeekOrigin.Current);\n                            maximumStreamSize += cb;\n                        }","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/DrawingAttributeSerializer.cs#L207-L243","documentation":"Thrown by DrawingAttributeSerializer.DecodeAsISF when reading compressed drawing-attribute payload bytes from the source stream: the stream.Read call returned fewer bytes than cbInSize, meaning the ISF payload is truncated or the stream position is wrong. The serializer cannot decompress a partial buffer, so it aborts decoding. It signals corrupt, truncated, or incorrectly formatted ISF (Ink Serialized Format) data rather than an application bug per se.","triggerScenarios":"DecodeAsISF is given a stream whose remaining length is less than the cbInSize declared in the ISF property header — e.g. a truncated ISF byte array, a stream not rewound to the correct position, or an ISF blob written by a producer with a wrong size field.","commonSituations":"Loading saved ink (StrokeCollection) from a file or database blob that was truncated by a partial write; passing a stream that another consumer already partially read; hand-crafted or corrupted ISF payloads; cross-version ISF round-trips where sizes were written incorrectly.","solutions":["Verify the stream is positioned at the start of the ISF payload (rewind with stream.Position = 0 or Seek) before decoding.","Check that the ISF data source is complete — re-serialize the StrokeCollection or re-download/re-copy the blob.","Validate the byte count of the source against the expected ISF size before calling the decoder.","Wrap decode in try/catch for ArgumentException and surface a clear 'corrupt ink data' message to users instead of crashing."],"exampleFix":"// before: stream may be mid-consumed\nvar strokes = StrokeCollectionSerializer.DecodeInkStream(stream);\n// after: ensure position and full data\nstream.Seek(0, SeekOrigin.Begin);\nif (stream.Length - stream.Position < declaredSize)\n    throw new InvalidDataException(\"ISF payload truncated\");\nvar strokes = StrokeCollectionSerializer.DecodeInkStream(stream);","handlingStrategy":"validation","validationCode":"if (stream == null) throw new ArgumentNullException(nameof(stream));\nif (stream.Length - stream.Position < declaredSize)\n    throw new InvalidDataException($\"ISF payload truncated: need {declaredSize} bytes, have {stream.Length - stream.Position}\");","typeGuard":"bool IsReadable(Stream s, int count) => s != null && s.CanRead && (s.Length - s.Position) >= count;","tryCatchPattern":"try { strokes = StrokeCollectionSerializer.DecodeInkStream(stream); }\ncatch (ArgumentException ex) { log.Warn(\"Truncated/corrupt ISF data\", ex); strokes = new StrokeCollection(); }","preventionTips":["Always rewind the stream (Seek(0, SeekOrigin.Begin)) before decoding stored ISF.","Persist ISF blobs atomically so partial writes cannot produce truncated data.","Validate blob length against a stored size before loading saved ink."],"tags":["ink","isf","serialization","stream","truncated-data"],"backgroundTag":"file-read-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"}