[squeak-dev] Buffer overrun in ZipPlugin
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Fri Mar 31 21:05:42 UTC 2017
I believe that the problem lies in DeflateStream>>deflateBlock
Especially the lines that compute lastIndex:
[blockPosition < position] whileTrue:[
(position + MaxMatch > writeLimit)
ifTrue:[lastIndex := writeLimit - MaxMatch]
ifFalse:[lastIndex := position].
Because the expectations below is:
deflateBlock: lastIndex chainLength: chainLength goodMatch: goodMatch
"Continue deflating the receiver's collection from blockPosition to
lastIndex.
Note that lastIndex must be at least MaxMatch away from the end of
collection"
And because lastIndex and position are 0 based.
While writeLimit is a size (65536).
I think that the code should rather be:
[blockPosition < position] whileTrue:[
(position + MaxMatch + 1 > writeLimit)
ifTrue:[lastIndex := writeLimit - MaxMatch - 1]
ifFalse:[lastIndex := position].
My failing example pass with above patch.
I'm about to commit it.
Before I do so, are there some extensive tests for zlib?
2017-03-31 21:13 GMT+02:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:
> Hi,
> some remember that from time to time, especially when the ZipPlugin is
> disabled, the DeflateStream fallback code is failing with a 'subscript is
> out of bounds: 65537'
>
> I have a reproducible example with quite a large file
>
> | zip file |
> zip := (FileStream fileNamed: 'snapshot.bin.gz') binary
> contentsOfEntireFile asString.
> file := zip unzipped.
> file zipped unzipped = file
>
> which gives me:
>
> ByteString(Object)>>error:
> ByteString(Object)>>errorSubscriptBounds:
> ByteString(Object)>>at:
> ByteString>>at:
> ByteString>>byteAt:
> GZipWriteStream(DeflateStream)>>updateHashAt:
> GZipWriteStream(DeflateStream)>>insertStringAt:
> GZipWriteStream(DeflateStream)>>deflateBlock:chainLength:goodMatch:
> GZipWriteStream(ZipWriteStream)>>deflateBlock:chainLength:goodMatch:
> GZipWriteStream(DeflateStream)>>deflateBlock
> GZipWriteStream(DeflateStream)>>next:putAll:startingAt:
> GZipWriteStream(DeflateStream)>>nextPutAll:
> ByteString(String)>>zipped
>
> When the plugin is enabled, the example works.
> So I've been tracking the differences between DeflatePlugin and
> DeflateStream fallback code for some times without success.
>
> What if I add a bound check in the DeflatePlugin?
> Then the plugin equally fails. I mean it reads past zipCollection bounds.
>
> So there's something bad in the implementation.
> Why does the example seem to work is still mysterious to me.
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20170331/a5a122f2/attachment.html>
More information about the Squeak-dev
mailing list
|