adamhathcock/sharpcompress

AbstractReader.Skip doesn't work for UsePostDataDescriptor zip streams

AlexVallat opened this issue · 6 comments

In AbstractReader.Skip() the shortcut to skip data by reading the raw stream rather than decompressing doesn't work if .CompressedSize is 0 due to a UsePostDataDescriptor formatted zip entry header.

It might be related to the thing you just fixed but that was me skipping data start position.

Anyway, if the descriptor doesn't put in a compressed size I don't know how I can just skip it without decompressing.

It's possible to scan the bytes for a zip header but that doesn't feel correct anyway. Already had issues with nested archives.

I don't think you can skip it without decompressing, if the size isn't known. The problem is that it should not skip 0 bytes and assume it's skipped the contents, I think it has to use the fallback path of actually reading the contents (like it does for the Entry.IsSolid case).

OHH...I see. It thinks it should just skip 0 bytes. Yeah, you're right it should decompress it.

Any chance of a PR for this issue?

Simplest solution I can think of is to add to the ZipEntry constructor:

if (FlagUtility.HasFlag(filePart.Header.Flags, HeaderFlags.UsePostDataDescriptor))
{
    IsSolid = true;
}

but that might be abusing the IsSolid property? I only saw it set for Rars, and only consumed in the Skip() method so this would probably be OK, but it smells a bit. Could rename the property to DecompressDuringSkip or similar, or otherwise I think it's going to take some extra plumbing.

Or alternatively you could assume that if CompressedSize was 0 it should use a decompressed skip - probably harmless as if it really is empty it won't take long to decompress it!

I guess where IsSolid is being checked should also check for the flag header and a size of zero to trigger the decompression

Unfortunately that's in AbstractReader, and therefore doesn't have access to the ZipEntry Header - it shouldn't, in principle, have knowledge of zip-specific flags.