Skip to content

Commit 869dae0

Browse files
authored
Merge pull request #132 from DataDog/viq111/bulk-fix-highlycompressed-payloads
[bulk] Fix being able to Decompress large payloads
2 parents ea68dca + bf7b920 commit 869dae0

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

zstd_bulk.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -112,20 +112,20 @@ func (p *BulkProcessor) Decompress(dst, src []byte) ([]byte, error) {
112112

113113
contentSize := decompressSizeHint(src)
114114
if cap(dst) >= contentSize {
115-
dst = dst[0:contentSize]
115+
dst = dst[0:cap(dst)]
116116
} else {
117117
dst = make([]byte, contentSize)
118118
}
119119

120-
if contentSize == 0 {
120+
if len(dst) == 0 {
121121
return dst, nil
122122
}
123123

124124
dctx := C.ZSTD_createDCtx()
125125
cWritten := C.ZSTD_decompress_usingDDict(
126126
dctx,
127127
unsafe.Pointer(&dst[0]),
128-
C.size_t(contentSize),
128+
C.size_t(len(dst)),
129129
unsafe.Pointer(&src[0]),
130130
C.size_t(len(src)),
131131
p.dDict,

zstd_bullk_test.go

+34-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func TestBulkEmptyOrNilDictionary(t *testing.T) {
9898
}
9999
}
100100

101-
func TestBulkCompressEmptyOrNilContent(t *testing.T) {
101+
func TestBulkCompressDecompressEmptyOrNilContent(t *testing.T) {
102102
p := newBulkProcessor(t, dict, BestSpeed)
103103
compressed, err := p.Compress(nil, nil)
104104
if err != nil {
@@ -115,6 +115,14 @@ func TestBulkCompressEmptyOrNilContent(t *testing.T) {
115115
if len(compressed) < 4 {
116116
t.Error("magic number doesn't exist")
117117
}
118+
119+
decompressed, err := p.Decompress(nil, compressed)
120+
if err != nil {
121+
t.Error("failed to decompress")
122+
}
123+
if len(decompressed) != 0 {
124+
t.Error("content was not decompressed correctly")
125+
}
118126
}
119127

120128
func TestBulkCompressIntoGivenDestination(t *testing.T) {
@@ -216,6 +224,31 @@ func TestBulkCompressAndDecompressInReverseOrder(t *testing.T) {
216224
}
217225
}
218226

227+
func TestBulkDecompressHighlyCompressable(t *testing.T) {
228+
p := newBulkProcessor(t, dict, BestSpeed)
229+
230+
// Generate a big payload
231+
msgSize := 10 * 1000 * 1000 // 10 MiB
232+
msg := make([]byte, msgSize)
233+
compressed, err := Compress(nil, msg)
234+
if err != nil {
235+
t.Error("failed to compress")
236+
}
237+
238+
// Regular decompression would trigger zipbomb prevention
239+
_, err = p.Decompress(nil, compressed)
240+
if !IsDstSizeTooSmallError(err) {
241+
t.Error("expected too small error")
242+
}
243+
244+
// Passing an output should suceed the decompression
245+
dst := make([]byte, 10*msgSize)
246+
_, err = p.Decompress(dst, compressed)
247+
if err != nil {
248+
t.Errorf("failed to decompress: %s", err)
249+
}
250+
}
251+
219252
// BenchmarkBulkCompress-8 780148 1505 ns/op 61.14 MB/s 208 B/op 5 allocs/op
220253
func BenchmarkBulkCompress(b *testing.B) {
221254
p := newBulkProcessor(b, dict, BestSpeed)

0 commit comments

Comments
 (0)