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.
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):
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.
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.