-
Notifications
You must be signed in to change notification settings - Fork 976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve the behaviour of ZipInputStream when reading zip entries with unsupported compression methods #333
Conversation
Actually, I labelled this as BZip2, but it's really an issue with any compression method that it doesnt understand (e.g. Deflate64). e.g., if you just do
Then it throws System.NotSupportedException, which doesn't seem ideal - this changes allows it to get the ZipEntry and get the details from that, while still giving errors if you try to actually decompress the data. |
Would it be better if I split this into two? |
Yes, the constructor switch is much more sane. The |
I'll look at breaking the constructor change out into its own PR. My original issue with the static IsCompressionMethodSupported things was that I changed things so that ZipFile supported reading BZip2 compressed entries but ZipInputStream still didn't, but as the same situation might occur with ZipOutputStream the area might benefit from another look (I suppose you could also have a situation where ZipFile can read more formats than it can write) |
About The changes are related in that they are making it easier to support additional formats, but they should probably be split into different PRs anyway. |
b02b844
to
766f1e2
Compare
Rebased and minimized to just use a local IsCompressionMethodSupported instead of the ZipEntry version. The IsCompressionMethodSupported method I added to ZipInputStream is private - not sure if there is any benedit to it being public given there is already a CanDecompressEntry function that can be used? |
With regards to:
Seems reasonable, api breaks aside ( a static function there doesn't make much sense i think), there's a couple other other attached things there:
|
|
Backwards compatibility with the entry members is what i was thinking about, and I did mean setting the CanDecompress flag via an internal property. The consumers/producers do make some attempts to do the validation, but it's a bit mixed: ZipInputStream has a CanDecompressEntry property and could have a means of querying supported algorithms (this PR adds a private member function to do that, could have a public version if that's useful). ZipOutputStream doesn't seem to validate things, but PutNextEntry could throw for unsupported methods. ZipFile looks a bit inconsistent, where some of the Add() overrides throw ArgumentOutOfRangeException if the compression method is unsupported and some don't (would that be considered a bug?). It does throw on stream access for unsupported methds though. |
I think we should just decide where this should be done and then be consistent with it. Perhaps interfaces, like IZipConsumer and IZipProducer could be used for querying supported methods? Something like public interface IZipConsumer
{
IEnumerable<CompressionMethod> GetSupportedDecompressMethods()
}
public static class ZipConsumerExtensions
{
public static bool CanDecompress(this IZipConsumer zc, ZipEntry ze)
=> zc.GetSupportedDecompressMethods().Contains(ze.CompressionMethod);
} Which ZipInfo then would implement both the interface and are free to respond differently to Compress and Decompress. |
766f1e2
to
8cc224a
Compare
PR updated to get ZipInputStream.CanDecompressEntry to return false for AES encrypted entries that it can't handle, though that seems to have caused the debug CI build of the InvalidPasswordNonSeekable test fail for some reason (it passes locally :-( ) (Is the CI build supposed to be listed as a pass if a test fails?). |
Some of the ZipFile.Add() overloads throw ArgumentOutOfRangeException, the ZipEntry property setter throws NotSupportedException, and ZipFile.GetOutputStream throws ZipException. Given that some of the Add() variants are documented as throwing ArgumentOutOfRangeException, could make them all consistent with that?
Could od something like that (I hadn't been thinking about querying lists of supportedmethods rather than just querying the state of a single one. |
8cc224a
to
fe6dd33
Compare
fe6dd33
to
b39bc8d
Compare
…d function rather than the one in ZipEntry.
…ncrypted entries.
b39bc8d
to
c7d21c5
Compare
When I was looking at BZip2 support in zip files, I had an issue where changing ZipEntry.IsCompressionMethodSupported to return true for BZip2 compression caused issues with ZipInputStream, where it went through its read logic and didn't read anything, but also didn't 'fail'.
When i went to make a change to do something about that, I found that calling GetNextEntry() to get an entry compressed with BZip2 compression (without any other changes) caused it to throw, when it attempted to set ZipEntry.CompressionMethod after construction.
This PR Makes 2 changes that might help with that:
Change ZipInputStream.GetNextEntry to use the ZipEntry constructor that takes the CompressionMethod as a parameter, rather than setting it afterwards.
Change it to use its own IsEntryCompressionMethodSupported function rather than relying on ZipEntry.IsCompressionMethodSupported (Given that the stream itself is in control of the supported methods, it seems reasonable to make that choice locally).
I wonder if it might be better here if ZipEntry.CanDecompress returned a value derived from the input source (ZipFile/ZipInputStream) rather than using a fixed algorithm list? something of a bigger change though.
I certify that I own, and have sufficient rights to contribute, all source code and related material intended to be compiled or integrated with the source code for the SharpZipLib open source product (the "Contribution"). My Contribution is licensed under the MIT License.