{"record":{"id":"f9a50fabbb8c8aa6","repo":"dotnet/wpf","slug":"sr-corruptstream","errorCode":null,"errorMessage":"SR.CorruptStream","messagePattern":"SR\\.CorruptStream","errorType":"exception","errorClass":"FileFormatException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileDeflateTransform.cs","lineNumber":92,"sourceCode":"\n                try\n                {\n                    // read all available data\n                    // each block is preceded by a header that is 3 ulongs\n                    int uncompressedSize, compressedSize;\n                    long destStreamLength = 0;      // keep track of decompressed size\n                    while (ReadBlockHeader(source, out uncompressedSize, out compressedSize))\n                    {\n                        // ensure we have space\n                        AllocOrRealloc(compressedSize, ref sourceBuf, ref gcSourceBuf);\n                        AllocOrRealloc(uncompressedSize, ref sinkBuf, ref gcSinkBuf);\n\n                        // read the data into the sourceBuf\n                        int bytesRead = PackagingUtilities.ReliableRead(source, sourceBuf, 0, compressedSize);\n                        if (bytesRead > 0)\n                        {\n                            if (compressedSize != bytesRead)\n                                throw new FileFormatException(SR.CorruptStream);\n\n                            // prepare structure\n                            // The buffer pointers must be reset for every call\n                            // because ZLibNative.Inflate modifies them\n                            zStream.NextIn = gcSourceBuf.AddrOfPinnedObject();\n                            zStream.NextOut = gcSinkBuf.AddrOfPinnedObject();\n                            zStream.AvailIn = (uint)bytesRead;     // this is number of bytes available for decompression at pInBuf and is updated by ums_deflate call\n                            zStream.AvailOut = (uint)sinkBuf.Length;   // this is the number of bytes free in pOutBuf and is updated by ums_deflate call\n\n                            // InvokeZLib does the actual interop.  It updates zStream, and sinkBuf (sourceBuf passed by ref to avoid copying)\n                            // and leaves the decompressed data in sinkBuf.\n                            //                        int decompressedSize = InvokeZLib(bytesRead, ref zStream, ref sourceBuf, ref sinkBuf, pSource, pSink, false);\n                            retVal = zStream.Inflate(ZLibNative.FlushCode.SyncFlush);\n\n                            ThrowIfZLibError(retVal);\n\n                            checked\n                            {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileDeflateTransform.cs#L74-L110","documentation":"CompoundFileDeflateTransform.Decompress throws FileFormatException with SR.CorruptStream when ReliableRead returns fewer bytes than the compressed block size declared in the block header. The compressed data is truncated relative to its own header, so the deflate payload cannot be trusted. This guards the zlib inflate step from reading garbage or uninitialized buffer regions.","triggerScenarios":"Reading a compound-file deflate-compressed stream whose block data is truncated — the file was cut short, partially written, or the header's compressedSize field doesn't match the actual bytes present.","commonSituations":"Opening damaged .docx/.xps OLE containers; files truncated by failed downloads or interrupted saves; hand-edited or corrupted container bytes.","solutions":["Verify/repair the document source; re-download or restore from backup","Catch FileFormatException and treat the document as corrupt, surfacing a user-friendly error","Validate file integrity (size, checksum) before opening if the source is untrusted","Open the file with the application's repair/recovery path if available"],"exampleFix":"// before\ntransform.Decompress(source, sink);\n// after\ntry {\n    transform.Decompress(source, sink);\n} catch (FileFormatException) {\n    // stream is truncated/corrupt — recover or reject the document\n    throw new InvalidDataException(\"Compound file stream is corrupt or truncated.\");\n}","handlingStrategy":"try-catch","validationCode":"if (source.CanSeek && source.Length - source.Position < compressedSize) throw new InvalidDataException(\"Truncated compressed block.\");","typeGuard":null,"tryCatchPattern":"try { transform.Decompress(source, sink); } catch (FileFormatException) { /* treat document as corrupt; salvage or reject */ }","preventionTips":["Validate file size/checksum before opening untrusted files","Detect truncation: CanSeek streams can compare remaining length to declared sizes","Keep backups of compound-file documents","Never hand-edit container bytes"],"tags":["file-format","corruption","deflate","compound-file","wpf"],"backgroundTag":"checksum-mismatch","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"}