Skip to content

Commit ccec934

Browse files
committed
compress/lzw: reject writing bytes that don't fit into litWidth.
Fixes #11142. Change-Id: Id772c4364c47776d6afe86b0939b9c6281e85edc Reviewed-on: https://go-review.googlesource.com/11227 Reviewed-by: Russ Cox <[email protected]>
1 parent 0c247bf commit ccec934

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

src/compress/lzw/writer.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -138,16 +138,23 @@ func (e *encoder) Write(p []byte) (n int, err error) {
138138
if len(p) == 0 {
139139
return 0, nil
140140
}
141+
if maxLit := uint8(1<<e.litWidth - 1); maxLit != 0xff {
142+
for _, x := range p {
143+
if x > maxLit {
144+
e.err = errors.New("lzw: input byte too large for the litWidth")
145+
return 0, e.err
146+
}
147+
}
148+
}
141149
n = len(p)
142-
litMask := uint32(1<<e.litWidth - 1)
143150
code := e.savedCode
144151
if code == invalidCode {
145152
// The first code sent is always a literal code.
146-
code, p = uint32(p[0])&litMask, p[1:]
153+
code, p = uint32(p[0]), p[1:]
147154
}
148155
loop:
149156
for _, x := range p {
150-
literal := uint32(x) & litMask
157+
literal := uint32(x)
151158
key := code<<8 | literal
152159
// If there is a hash table hit for this key then we continue the loop
153160
// and do not emit a code yet.

src/compress/lzw/writer_test.go

+10
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ func TestWriterReturnValues(t *testing.T) {
104104
}
105105
}
106106

107+
func TestSmallLitWidth(t *testing.T) {
108+
w := NewWriter(ioutil.Discard, LSB, 2)
109+
if _, err := w.Write([]byte{0x03}); err != nil {
110+
t.Fatalf("write a byte < 1<<2: %v", err)
111+
}
112+
if _, err := w.Write([]byte{0x04}); err == nil {
113+
t.Fatal("write a byte >= 1<<2: got nil error, want non-nil")
114+
}
115+
}
116+
107117
func benchmarkEncoder(b *testing.B, n int) {
108118
b.StopTimer()
109119
b.SetBytes(int64(n))

0 commit comments

Comments
 (0)