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.