Skip to content

Commit 43c36f4

Browse files
committed
[zstd] Fix unneededly allocate large decompression buffer
Fix #118 With the introduction of #115 to prevent zipbombs, the check was too strict and was checking a too large size boundary. This fixes it and adds a test
1 parent e5990c1 commit 43c36f4

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

zstd.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const (
3636
// decompressed, err := zstd.Decompress(dst, src)
3737
decompressSizeBufferLimit = 1000 * 1000
3838

39-
zstdFrameHeaderSizeMax = 18 // From zstd.h. Since it's experimental API, hardcoding it
39+
zstdFrameHeaderSizeMin = 2 // From zstd.h. Since it's experimental API, hardcoding it
4040
)
4141

4242
// CompressBound returns the worst case size needed for a destination buffer,
@@ -67,7 +67,7 @@ func decompressSizeHint(src []byte) int {
6767
}
6868

6969
hint := upperBound
70-
if len(src) >= zstdFrameHeaderSizeMax {
70+
if len(src) >= zstdFrameHeaderSizeMin {
7171
hint = int(C.ZSTD_getFrameContentSize(unsafe.Pointer(&src[0]), C.size_t(len(src))))
7272
if hint < 0 { // On error, just use upperBound
7373
hint = upperBound

zstd_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,25 @@ func TestBadPayloadZipBomb(t *testing.T) {
293293
}
294294
}
295295

296+
func TestSmallPayload(t *testing.T) {
297+
// Test that we can compress really small payloads and this doesn't generate a huge output buffer
298+
compressed, err := Compress(nil, []byte("a"))
299+
if err != nil {
300+
t.Fatalf("failed to compress: %s", err)
301+
}
302+
303+
preAllocated := make([]byte, 1, 64) // Don't use more than that
304+
decompressed, err := Decompress(preAllocated, compressed)
305+
if err != nil {
306+
t.Fatalf("failed to compress: %s", err)
307+
}
308+
309+
if &(preAllocated[0]) != &(decompressed[0]) { // They should point to the same spot (no realloc)
310+
t.Fatal("Compression buffer was changed")
311+
}
312+
313+
}
314+
296315
func BenchmarkCompression(b *testing.B) {
297316
if raw == nil {
298317
b.Fatal(ErrNoPayloadEnv)

0 commit comments

Comments
 (0)