dotnet/wpf · error · FileFormatException
SR.CorruptStream
Error message
SR.CorruptStream
What it means
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.
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
Example fix
// before
transform.Decompress(source, sink);
// after
try {
transform.Decompress(source, sink);
} catch (FileFormatException) {
// stream is truncated/corrupt — recover or reject the document
throw new InvalidDataException("Compound file stream is corrupt or truncated.");
} Defensive patterns
Strategy: try-catch
Validate before calling
if (source.CanSeek && source.Length - source.Position < compressedSize) throw new InvalidDataException("Truncated compressed block."); Try / catch
try { transform.Decompress(source, sink); } catch (FileFormatException) { /* treat document as corrupt; salvage or reject */ } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Opening damaged .docx/.xps OLE containers; files truncated by failed downloads or interrupted saves; hand-edited or corrupted container bytes.
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- File contains corrupted data.
- Signature structures are corrupted in this package.
- SR.CFRCorrupt
- SR.CFRCorruptStgFollowStm
- SR.PackageSignatureCorruption
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f9a50fabbb8c8aa6.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileDeflateTransform.cs:92
try
{
// read all available data
// each block is preceded by a header that is 3 ulongs
int uncompressedSize, compressedSize;
long destStreamLength = 0; // keep track of decompressed size
while (ReadBlockHeader(source, out uncompressedSize, out compressedSize))
{
// ensure we have space
AllocOrRealloc(compressedSize, ref sourceBuf, ref gcSourceBuf);
AllocOrRealloc(uncompressedSize, ref sinkBuf, ref gcSinkBuf);
// read the data into the sourceBuf
int bytesRead = PackagingUtilities.ReliableRead(source, sourceBuf, 0, compressedSize);
if (bytesRead > 0)
{
if (compressedSize != bytesRead)
throw new FileFormatException(SR.CorruptStream);
// prepare structure
// The buffer pointers must be reset for every call
// because ZLibNative.Inflate modifies them
zStream.NextIn = gcSourceBuf.AddrOfPinnedObject();
zStream.NextOut = gcSinkBuf.AddrOfPinnedObject();
zStream.AvailIn = (uint)bytesRead; // this is number of bytes available for decompression at pInBuf and is updated by ums_deflate call
zStream.AvailOut = (uint)sinkBuf.Length; // this is the number of bytes free in pOutBuf and is updated by ums_deflate call
// InvokeZLib does the actual interop. It updates zStream, and sinkBuf (sourceBuf passed by ref to avoid copying)
// and leaves the decompressed data in sinkBuf.
// int decompressedSize = InvokeZLib(bytesRead, ref zStream, ref sourceBuf, ref sinkBuf, pSource, pSink, false);
retVal = zStream.Inflate(ZLibNative.FlushCode.SyncFlush);
ThrowIfZLibError(retVal);
checked
{View on GitHub (pinned to 81131a70a4)