runtime: ZipPackagePart.GetStreamCore crashes with NotSupportedException
This spawned off investigations done in https://github.com/dotnet/wpf/issues/1363.
A simple reproduction in a console application can be obtained by doing:
var zp = ZipPackage.Open("test.zip", System.IO.FileMode.Create, System.IO.FileAccess.Write);
var part = zp.CreatePart(new System.Uri("/test.txt", UriKind.Relative), "");
var stream = part.GetStream(System.IO.FileMode.Create);
A NotSupportedException will arise due to this code:
The call to SetLength fails since the underlying stream does not support this.
The flow here is:
- https://github.com/dotnet/corefx/blob/78589e4d2c98bf71cefa4dbc94cde3783b60a934/src/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs#L290
ZipArchiveEntry.GetDataCompressorcreates a newDeflateStreamwhich is then wrapped, along with the original stream, byCheckSumAndSizeWriteStream. https://github.com/dotnet/corefx/blob/78589e4d2c98bf71cefa4dbc94cde3783b60a934/src/System.IO.Compression/src/System/IO/Compression/ZipArchiveEntry.cs#L600CheckSumAndSizeWriteStreamis never seekable and doesn’t supportSetPosition: https://github.com/dotnet/corefx/blob/a10890f4ffe0fadf090c922578ba0e606ebdd16c/src/System.IO.Compression/src/System/IO/Compression/ZipCustomStreams.cs#L364
It seems that the assumption about the underlying stream is incorrect or the underlying stream should be allowing for this functionality.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 2
- Comments: 15 (15 by maintainers)
Thanks @stevenbrix for the fix!
We still have time. @stevenbrix was this something you wanted to do or should we assign to someone else?
Sorry if I sent any wrong vibes, I want to be clear that I’m not advocating we don’t fix this bug. As @ericstj mentioned earlier, the call to
SetLengthisn’t necessary here. I just wanted to make sure it was documented on this issue that there is a workaround.I totally agree, and it would be really nice if there was some sort of matrix that helped us understand what combination of requests are valid, and in which scenario the stream returned supports streaming and when it doesn’t. It isn’t exactly intuitive that passing
FileAccess.ReadWritereturns a seekable stream whereas just passingFileAccess.Writedoesn’t. If the expected behavior was documented (hopefully with some explanation) then we could better understand whether or not the implementation matches those.