Skip to content

Commit 0396178

Browse files
authored
zstd: BuildDict fails with RLE table (#951)
* zstd: BuildDict fails with RLE table We cannot build a useable table if RLE. Add a fake entry to generate valid tables. * Prevent offsets longer than dict to be selected.
1 parent 8411e1d commit 0396178

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

zstd/dict.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
273273
enc.Encode(&block, b)
274274
addValues(&remain, block.literals)
275275
litTotal += len(block.literals)
276+
if len(block.sequences) == 0 {
277+
continue
278+
}
276279
seqs += len(block.sequences)
277280
block.genCodes()
278281
addHist(&ll, block.coders.llEnc.Histogram())
@@ -286,6 +289,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
286289
if offset == 0 {
287290
continue
288291
}
292+
if int(offset) >= len(o.History) {
293+
continue
294+
}
289295
if offset > 3 {
290296
newOffsets[offset-3]++
291297
} else {
@@ -336,6 +342,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
336342
if seqs/nUsed < 512 {
337343
// Use 512 as minimum.
338344
nUsed = seqs / 512
345+
if nUsed == 0 {
346+
nUsed = 1
347+
}
339348
}
340349
copyHist := func(dst *fseEncoder, src *[256]int) ([]byte, error) {
341350
hist := dst.Histogram()
@@ -358,6 +367,28 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
358367
fakeLength += v
359368
hist[i] = uint32(v)
360369
}
370+
371+
// Ensure we aren't trying to represent RLE.
372+
if maxCount == fakeLength {
373+
for i := range hist {
374+
if uint8(i) == maxSym {
375+
fakeLength++
376+
maxSym++
377+
hist[i+1] = 1
378+
if maxSym > 1 {
379+
break
380+
}
381+
}
382+
if hist[0] == 0 {
383+
fakeLength++
384+
hist[i] = 1
385+
if maxSym > 1 {
386+
break
387+
}
388+
}
389+
}
390+
}
391+
361392
dst.HistogramFinished(maxSym, maxCount)
362393
dst.reUsed = false
363394
dst.useRLE = false

0 commit comments

Comments
 (0)