Skip to content

Bug in OutputWindow.cs that will cause ZipInputStream.Read() to never run out of data in certain corrupt ZIP files #19

Description

@klavatar

HI there, I recently discovered a potential bug in Zip/Compression/Streams/OutputWindow.cs that, when combined with a corrupt ZIP archive, may cause ZipInputStream.Read() to never run out of data.

Specifically, in line 208 (version 0.86.0.518):

    copyEnd = (windowEnd - windowFilled + len) & WindowMask;

Where copyEnd is supposed to be a positive index into the window. However, given a ZIP archive that is corrupt in a particular way (I have an example ZIP file that triggers this behavior), (windowEnd - windowFilled + len) will become negative. However, the "& WindowMask" operator masks off the high bits, which converts the number back to positive. This throws off the subsequent logic and will set the code into an infinite loop where the ZipInputStream.Read() calls always returns "new" data, and therefore never return "0".

So I made a simple modification that first checks to see if (windowEnd - windowFilled + len) is negative. If that's the case, I simply throw a "WIndow overflow" error, something like this.

            int endOffset = windowEnd - windowFilled + len;
            if (endOffset < 0) {
                throw new InvalidOperationException("Window overflow");
            }
            copyEnd = endOffset & WindowMask;

This seems to correctly detect the corruption and throw an exception.

I think there must be more elegant ways to fix this, but this quick-and-dirty trick did it for me. I wnt to re-iterate that this only happens (as far as I know) when the ZIP file is corrupt, but since I have to deal with ZIP files that are created by others, this does come in handy. Hope this might be helpful to someone.

  • K.

Metadata

Metadata

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions