1
0
mirror of https://github.com/golang/go synced 2024-11-11 22:50:22 -07:00

[klauspost/fix-inconsistent-deflate-reset] Address code review.

Change-Id: I11dd190ac9f190f70c52221b352f829377e7cd64
This commit is contained in:
Klaus Post 2020-05-07 14:44:44 +02:00
parent 2fb09aaa48
commit 8b35798cdd
No known key found for this signature in database
GPG Key ID: BAA2096BE0B8A075

View File

@ -4,15 +4,23 @@
package flate
import "math"
// This encoding algorithm, which prioritizes speed over output size, is
// based on Snappy's LZ77-style encoder: github.com/golang/snappy
const (
tableBits = 14 // Bits used in the table.
tableSize = 1 << tableBits // Size of the table.
tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks.
tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.
bufferReset = (1 << 31) - maxStoreBlockSize*2 - 1 // Reset the buffer offset when reaching this.
tableBits = 14 // Bits used in the table.
tableSize = 1 << tableBits // Size of the table.
tableMask = tableSize - 1 // Mask for table indices. Redundant, but can eliminate bounds checks.
tableShift = 32 - tableBits // Right-shift to get the tableBits most significant bits of a uint32.
// Reset the buffer offset when reaching this.
// Offsets are stored between blocks as int32 values.
// Since the offset we are checking against is at the beginning
// of the buffer, we need to subtract the current and input
// buffer to not risk overflowing the int32.
bufferReset = math.MaxInt32 - maxStoreBlockSize*2
)
func load32(b []byte, i int32) uint32 {
@ -61,7 +69,7 @@ func newDeflateFast() *deflateFast {
func (e *deflateFast) encode(dst []token, src []byte) []token {
// Ensure that e.cur doesn't wrap.
if e.cur >= bufferReset {
e.resetAll()
e.shiftOffsets()
}
// This check isn't in the Snappy implementation, but there, the caller
@ -265,17 +273,16 @@ func (e *deflateFast) reset() {
e.cur += maxMatchOffset
// Protect against e.cur wraparound.
if e.cur > bufferReset {
e.resetAll()
if e.cur >= bufferReset {
e.shiftOffsets()
}
}
// resetAll resets the deflateFast struct and is only called in rare
// situations to prevent integer overflow. It manually resets each field
// to avoid causing large stack growth.
// shiftOffsets will shift down all match offset.
// This is only called in rare situations to prevent integer overflow.
//
// See https://golang.org/issue/18636.
func (e *deflateFast) resetAll() {
// See https://golang.org/issue/18636 and https://github.com/golang/go/issues/34121.
func (e *deflateFast) shiftOffsets() {
if len(e.prev) == 0 {
// We have no history; just clear the table.
for i := range e.table[:] {