mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
compress/flate: fix another deflate Reset inconsistency
While investigating #34121, fixed by CL 193605, I discovered another case where Reset was not quite resetting enough. This specific case is not a problem in Reset itself but rather that the Huffman bit writer in one code path is using uninitialized memory left over from a previous block, making the compression not choose the optimal compression method. Fixes #34121. Change-Id: I29245b28214d924e382f91e2c56b4b8a9b7da13d Reviewed-on: https://go-review.googlesource.com/c/go/+/243140 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
parent
8d4330742c
commit
4469f5446a
@ -512,33 +512,57 @@ func TestWriterReset(t *testing.T) {
|
|||||||
t.Errorf("level %d Writer not reset after Reset", level)
|
t.Errorf("level %d Writer not reset after Reset", level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, NoCompression) })
|
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, DefaultCompression) })
|
levels := []int{0, 1, 2, 5, 9}
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, BestCompression) })
|
for _, level := range levels {
|
||||||
dict := []byte("we are the world")
|
t.Run(fmt.Sprint(level), func(t *testing.T) {
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, NoCompression, dict) })
|
testResetOutput(t, level, nil)
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, DefaultCompression, dict) })
|
})
|
||||||
testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, BestCompression, dict) })
|
}
|
||||||
|
|
||||||
|
t.Run("dict", func(t *testing.T) {
|
||||||
|
for _, level := range levels {
|
||||||
|
t.Run(fmt.Sprint(level), func(t *testing.T) {
|
||||||
|
testResetOutput(t, level, nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResetOutput(t *testing.T, newWriter func(w io.Writer) (*Writer, error)) {
|
func testResetOutput(t *testing.T, level int, dict []byte) {
|
||||||
|
writeData := func(w *Writer) {
|
||||||
|
msg := []byte("now is the time for all good gophers")
|
||||||
|
w.Write(msg)
|
||||||
|
w.Flush()
|
||||||
|
|
||||||
|
hello := []byte("hello world")
|
||||||
|
for i := 0; i < 1024; i++ {
|
||||||
|
w.Write(hello)
|
||||||
|
}
|
||||||
|
|
||||||
|
fill := bytes.Repeat([]byte("x"), 65000)
|
||||||
|
w.Write(fill)
|
||||||
|
}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
w, err := newWriter(buf)
|
var w *Writer
|
||||||
|
var err error
|
||||||
|
if dict == nil {
|
||||||
|
w, err = NewWriter(buf, level)
|
||||||
|
} else {
|
||||||
|
w, err = NewWriterDict(buf, level, dict)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("NewWriter: %v", err)
|
t.Fatalf("NewWriter: %v", err)
|
||||||
}
|
}
|
||||||
b := []byte("hello world")
|
|
||||||
for i := 0; i < 1024; i++ {
|
writeData(w)
|
||||||
w.Write(b)
|
|
||||||
}
|
|
||||||
w.Close()
|
w.Close()
|
||||||
out1 := buf.Bytes()
|
out1 := buf.Bytes()
|
||||||
|
|
||||||
buf2 := new(bytes.Buffer)
|
buf2 := new(bytes.Buffer)
|
||||||
w.Reset(buf2)
|
w.Reset(buf2)
|
||||||
for i := 0; i < 1024; i++ {
|
writeData(w)
|
||||||
w.Write(b)
|
|
||||||
}
|
|
||||||
w.Close()
|
w.Close()
|
||||||
out2 := buf2.Bytes()
|
out2 := buf2.Bytes()
|
||||||
|
|
||||||
|
@ -634,6 +634,7 @@ func (w *huffmanBitWriter) writeBlockHuff(eof bool, input []byte) {
|
|||||||
w.literalFreq[endBlockMarker] = 1
|
w.literalFreq[endBlockMarker] = 1
|
||||||
|
|
||||||
const numLiterals = endBlockMarker + 1
|
const numLiterals = endBlockMarker + 1
|
||||||
|
w.offsetFreq[0] = 1
|
||||||
const numOffsets = 1
|
const numOffsets = 1
|
||||||
|
|
||||||
w.literalEncoding.generate(w.literalFreq, 15)
|
w.literalEncoding.generate(w.literalFreq, 15)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user