[squeak-dev] The Trunk: Compression-nice.52.mcz
commits at source.squeak.org
commits at source.squeak.org
Fri Mar 31 22:30:30 UTC 2017
Nicolas Cellier uploaded a new version of Compression to project The Trunk:
http://source.squeak.org/trunk/Compression-nice.52.mcz
==================== Summary ====================
Name: Compression-nice.52
Author: nice
Time: 1 April 2017, 12:30:20.191934 am
UUID: 470505e6-d35d-450a-9804-29b904c5853d
Ancestors: Compression-ul.51
Correct a bug that can cause ZlibPlugin to read past the zipCollection boundary in DeflateBlock.
If the plugin is disabled, there will be a 'subscript is out of bounds: 65537' in DeflateStream fallback code.
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
This bug is triggered by some input data, for example if you extract the snapshot.bin file from the zip archive the archive http://source.squeak.org/VMMaker/VMMaker.oscog-nice.794.mcz
We need MinMatch bytes to insert the string following the best match.
(confirmed by comment near the end of a C version http://git.savannah.gnu.org/cgit/gzip.git/tree/deflate.c)
Since we pass lastIndex-1 to the primitive, and that the longest match can be up to MaxMatch, we are going to read the zipCollection up to:
lastIndex - 1 + MaxMatch - 1 + MinMatch - 1 (0 based)
Thus we must have:
lastIndex - 1 + MaxMatch - 1 + MinMatch - 1 < writeLimit
We have MinMatch = 3, thus the simplification
lastIndex + MaxMatch < writeLimit
Thus the requirement:
lastIndex + MaxMatch + 1 <= writeLimit
=============== Diff against Compression-ul.51 ===============
Item was changed:
----- Method: DeflateStream>>deflateBlock (in category 'deflating') -----
deflateBlock
"Deflate the current contents of the stream"
| flushNeeded lastIndex |
(blockStart == nil) ifTrue:[
"One time initialization for the first block"
1 to: MinMatch-1 do:[:i| self updateHashAt: i].
blockStart := 0].
[blockPosition < position] whileTrue:[
+ (position + MaxMatch + 1 > writeLimit)
+ ifTrue:[lastIndex := writeLimit - MaxMatch - 1]
- (position + MaxMatch > writeLimit)
- ifTrue:[lastIndex := writeLimit - MaxMatch]
ifFalse:[lastIndex := position].
flushNeeded := self deflateBlock: lastIndex-1
chainLength: self hashChainLength
goodMatch: self goodMatchLength.
flushNeeded ifTrue:[
self flushBlock.
blockStart := blockPosition].
"Make room for more data"
self moveContentsToFront].
!
More information about the Squeak-dev
mailing list
|