Skip to content
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

Throw exception on Store+Descriptor entries #517

Merged
merged 7 commits into from Feb 21, 2021
Merged

Throw exception on Store+Descriptor entries #517

merged 7 commits into from Feb 21, 2021

Conversation

piksel
Copy link
Member

@piksel piksel commented Oct 3, 2020

Due to the way that ZipInputStream is designed, reading entries that are using Store compression method and Descriptor flag is not possible. This change will throw a StreamUnsupportedException instead of failing on incorrect CRC.

Fixes #15 (as much as a fix as is possible for this).

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.

@Numpsy
Copy link
Contributor

Numpsy commented Oct 4, 2020

Should ZipInputStream.CanDecompressEntry return false for these entries?

@piksel
Copy link
Member Author

piksel commented Oct 4, 2020

Should ZipInputStream.CanDecompressEntry return false for these entries?

Good point! It should. That is the most elegant way to handle it for the consumer.

@@ -861,42 +722,29 @@ public long Crc
}

/// <summary>
/// Gets/Sets the compression method. Only Deflated and Stored are supported.
/// Gets/Sets the compression method. Only <see cref="CompressionMethod.Deflated">Deflated</see>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not related to this actual issue, but that's out of date - BZip2 is supported in the ZipFile case now

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's the problem with having this logic in ZipEntry. I wonder if we even should limit this here. It should be up to ZipFile and ZipOutputStream to throw on adding such an entry.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refs #500

/// <summary>
/// General ZipEntry helper extensions
/// </summary>
public static class ZipEntryExtensions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need to be public? (not sure if it's useful for other users or not?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not, but I know that I would appreciate having it when consuming the library (since the flag is exposed in a public property as an int).

@@ -512,11 +512,13 @@ private int ReadingNotSupported(byte[] destination, int offset, int count)
/// <returns>The actual number of bytes read.</returns>
private int InitialRead(byte[] destination, int offset, int count)
{
if (!CanDecompressEntry)
if (entry == null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it should be possible to get here in that case? (maybe auseful sanity check in case though)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't think so either, but since the CanDecompressEntry used to check it, I didn't want to remove it since the rest of the body dereferences entity a lot. It shouldn't be too hard to verify though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to query if changing this effects the handling of AES entries (where the 'entry.IsCrypted' path only handles ZipCrypto entries), but I don't think it can get this far for those because of the earlier checks in GetNextEntry.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, exactly. There is only one reference to the method, and that method sets and dereferences entity just before invoking this one. Hence I removed the check.

@Numpsy
Copy link
Contributor

Numpsy commented Feb 13, 2021

On another trivial not-directly-related-to-this-issue thought:

looking at the code just made me wonder if there enough instances of

if (entry.AESKeySize > 0)

use purely as a 'should the entry be AES encrypted' check to make it worth adding something like a

internal bool IsAESEncrypted => _aesEncryptionStrength > 0;

property to ZipEntry, even if only as an internal helper?

@Numpsy
Copy link
Contributor

Numpsy commented Feb 13, 2021

Changes seem ok otherwise though

@piksel
Copy link
Member Author

piksel commented Feb 13, 2021

Note that the reason for it immediately throwing in InitialRead (by invoking StoredDescriptorEntry) AND setting the read method to StoredDescriptorEntry is that in this situation, it's not just reading the entry data that is not possible. It's also not possible to skip it/seek to the next entry. This does however give the consumer a chance to read everything up to this entry and detect that such an entry was found. Perhaps not something anyone will use, but it feels like the "correct" way to handle it at least.

{
throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version + ")");
}
var usesDescriptor = (entry.Flags & (int)GeneralBitFlags.Descriptor) != 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can that use the HasFlag helper you added?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a lot of places where it can be used, but this is essential the same as using that method. It might be a bit easier to read, but the main issue I had were the places where the flags where compared to a magic number instead. Really opaque to the reader.
Anyhow, I won't add any more changes of that type to this PR, but I'll instead merge it so that it can be used in subsequent PRs.

@piksel piksel merged commit 06ff713 into master Feb 21, 2021
@piksel piksel deleted the storedescrex branch July 5, 2021 11:39
HowToDoThis added a commit to HowToDoThis/SharpZipLib that referenced this pull request Aug 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ZipInputStream class doesn't process correctly no compression entries with flag Bit 3 set
2 participants