<div dir="ltr"><div><div><div><div><div><div>I believe that the problem lies in DeflateStream>>deflateBlock<br><br></div>Especially the lines that compute lastIndex:<br><br>    [blockPosition < position] whileTrue:[<br>        (position + MaxMatch > writeLimit)<br>            ifTrue:[lastIndex := writeLimit - MaxMatch]<br>            ifFalse:[lastIndex := position].<br><br></div>Because the expectations below is:<br>deflateBlock: lastIndex chainLength: chainLength goodMatch: goodMatch<br>    "Continue deflating the receiver's collection from blockPosition to lastIndex.<br>    Note that lastIndex must be at least MaxMatch away from the end of collection"<br><br></div>And because lastIndex and position are 0 based.<br>While writeLimit is a size (65536).<br><br>I think that the code should rather be:<br></div><br>    [blockPosition < position] whileTrue:[<br>        (position + MaxMatch + 1 > writeLimit)<br>            ifTrue:[lastIndex := writeLimit - MaxMatch - 1]<br>            ifFalse:[lastIndex := position].<br><br></div>My failing example pass with above patch.<br></div>I'm about to commit it.<br>Before I do so, are there some extensive tests for zlib?<br></div><div class="gmail_extra"><br><div class="gmail_quote">2017-03-31 21:13 GMT+02:00 Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div>Hi,<br></div>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'<br><br></div>I have a reproducible example with quite a large file<br><br>    | zip file |<br>    zip := (FileStream fileNamed: 'snapshot.bin.gz') binary contentsOfEntireFile asString.<br>    file := zip unzipped.<br>    file zipped unzipped = file<br><br>which gives me:<br><br>ByteString(Object)>>error:<br>ByteString(Object)>><wbr>errorSubscriptBounds:<br>ByteString(Object)>>at:<br>ByteString>>at:<br>ByteString>>byteAt:<br>GZipWriteStream(DeflateStream)<wbr>>>updateHashAt:<br>GZipWriteStream(DeflateStream)<wbr>>>insertStringAt:<br>GZipWriteStream(DeflateStream)<wbr>>>deflateBlock:chainLength:<wbr>goodMatch:<br>GZipWriteStream(<wbr>ZipWriteStream)>>deflateBlock:<wbr>chainLength:goodMatch:<br>GZipWriteStream(DeflateStream)<wbr>>>deflateBlock<br>GZipWriteStream(DeflateStream)<wbr>>>next:putAll:startingAt:<br>GZipWriteStream(DeflateStream)<wbr>>>nextPutAll:<br>ByteString(String)>>zipped<br><br></div>When the plugin is enabled, the example works.<br></div><div>So I've been tracking the differences between DeflatePlugin and DeflateStream fallback code for some times without success.<br><br>What if I add a bound check in the DeflatePlugin?<br></div><div>Then the plugin equally fails. I mean it reads past zipCollection bounds.<br><br></div><div>So there's something bad in the implementation.<br></div><div>Why does the example seem to work is still mysterious to me.<br><br></div><div><div><br></div></div></div>
</blockquote></div><br></div>