Skip to content

Commit 4ce6f08

Browse files
committed
lzma: fix handling of small dictionary sizes
As Matt Dainty (@bodgit) reported there is an issue if the header of the LZMA stream is less than the minimum dictionary size of 4096 byte. The specification of the LZMA format says that in that case a dictionary size of 4096 byte should be used, our code returns an error. This commit changes the behavior and adds a simple test case to test for the right behavior. Fixes [#52](#52)
1 parent 0b7c695 commit 4ce6f08

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

lzma/reader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (c ReaderConfig) NewReader(lzma io.Reader) (r *Reader, err error) {
7070
return nil, err
7171
}
7272
if r.h.dictCap < MinDictCap {
73-
return nil, errors.New("lzma: dictionary capacity too small")
73+
r.h.dictCap = MinDictCap
7474
}
7575
dictCap := r.h.dictCap
7676
if c.DictCap > dictCap {

lzma/reader_test.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ func TestReaderAll(t *testing.T) {
112112
}
113113
}
114114

115-
//
116115
func Example_reader() {
117116
f, err := os.Open("fox.lzma")
118117
if err != nil {
@@ -310,3 +309,43 @@ func TestReaderErrAgain(t *testing.T) {
310309
}
311310
}
312311
}
312+
313+
func TestMinDictSize(t *testing.T) {
314+
const file = "examples/a.txt"
315+
uncompressed, err := os.ReadFile(file)
316+
if err != nil {
317+
t.Fatalf("os.ReadFile(%q) error %s", file, err)
318+
}
319+
f := bytes.NewReader(uncompressed)
320+
321+
buf := new(bytes.Buffer)
322+
cfg := WriterConfig{DictCap: 4096}
323+
w, err := cfg.NewWriter(buf)
324+
if err != nil {
325+
t.Fatalf("WriterConfig(%+v).NewWriter(buf) error %s", cfg, err)
326+
}
327+
defer w.Close()
328+
if _, err = io.Copy(w, f); err != nil {
329+
t.Fatalf("io.Copy(w, f) error %s", err)
330+
}
331+
if err = w.Close(); err != nil {
332+
t.Fatalf("w.Close() error %s", err)
333+
}
334+
335+
compressed := buf.Bytes()
336+
putUint32LE(compressed[1:5], 0)
337+
338+
z := bytes.NewReader(compressed)
339+
r, err := NewReader(z)
340+
if err != nil {
341+
t.Fatalf("NewReader(z) error %s", err)
342+
}
343+
u, err := io.ReadAll(r)
344+
if err != nil {
345+
t.Fatalf("io.ReadAll(r) error %s", err)
346+
}
347+
348+
if !bytes.Equal(u, uncompressed) {
349+
t.Fatalf("got %q; want %q", u, uncompressed)
350+
}
351+
}

0 commit comments

Comments
 (0)