vendor: github.com/klauspost/compress v1.16.5

full diff: https://github.com/klauspost/compress/compare/v1.16.3...v1.16.5

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit 497b13c661)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2023-09-19 16:38:35 +02:00
parent d9f94d5719
commit cde0441dc8
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
15 changed files with 278 additions and 250 deletions

View File

@ -57,7 +57,7 @@ require (
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/mux v1.8.0 // indirect github.com/gorilla/mux v1.8.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.16.3 // indirect github.com/klauspost/compress v1.16.5 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/moby/sys/symlink v0.2.0 // indirect github.com/moby/sys/symlink v0.2.0 // indirect

View File

@ -243,8 +243,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY= github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=

View File

@ -16,6 +16,15 @@ This package provides various compression algorithms.
# changelog # changelog
* Apr 5, 2023 - [v1.16.4](https://github.com/klauspost/compress/releases/tag/v1.16.4)
* zstd: Improve zstd best efficiency by @greatroar and @klauspost in https://github.com/klauspost/compress/pull/784
* zstd: Respect WithAllLitEntropyCompression https://github.com/klauspost/compress/pull/792
* zstd: Fix amd64 not always detecting corrupt data https://github.com/klauspost/compress/pull/785
* zstd: Various minor improvements by @greatroar in https://github.com/klauspost/compress/pull/788 https://github.com/klauspost/compress/pull/794 https://github.com/klauspost/compress/pull/795
* s2: Fix huge block overflow https://github.com/klauspost/compress/pull/779
* s2: Allow CustomEncoder fallback https://github.com/klauspost/compress/pull/780
* gzhttp: Suppport ResponseWriter Unwrap() in gzhttp handler by @jgimenez in https://github.com/klauspost/compress/pull/799
* Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1) * Mar 13, 2023 - [v1.16.1](https://github.com/klauspost/compress/releases/tag/v1.16.1)
* zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776 * zstd: Speed up + improve best encoder by @greatroar in https://github.com/klauspost/compress/pull/776
* gzhttp: Add optional [BREACH mitigation](https://github.com/klauspost/compress/tree/master/gzhttp#breach-mitigation). https://github.com/klauspost/compress/pull/762 https://github.com/klauspost/compress/pull/768 https://github.com/klauspost/compress/pull/769 https://github.com/klauspost/compress/pull/770 https://github.com/klauspost/compress/pull/767 * gzhttp: Add optional [BREACH mitigation](https://github.com/klauspost/compress/tree/master/gzhttp#breach-mitigation). https://github.com/klauspost/compress/pull/762 https://github.com/klauspost/compress/pull/768 https://github.com/klauspost/compress/pull/769 https://github.com/klauspost/compress/pull/770 https://github.com/klauspost/compress/pull/767
@ -615,6 +624,8 @@ Here are other packages of good quality and pure Go (no cgo wrappers or autoconv
* [github.com/pierrec/lz4](https://github.com/pierrec/lz4) - strong multithreaded LZ4 compression. * [github.com/pierrec/lz4](https://github.com/pierrec/lz4) - strong multithreaded LZ4 compression.
* [github.com/cosnicolaou/pbzip2](https://github.com/cosnicolaou/pbzip2) - multithreaded bzip2 decompression. * [github.com/cosnicolaou/pbzip2](https://github.com/cosnicolaou/pbzip2) - multithreaded bzip2 decompression.
* [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer. * [github.com/dsnet/compress](https://github.com/dsnet/compress) - brotli decompression, bzip2 writer.
* [github.com/ronanh/intcomp](https://github.com/ronanh/intcomp) - Integer compression.
* [github.com/spenczar/fpc](https://github.com/spenczar/fpc) - Float compression.
# license # license

View File

@ -473,7 +473,7 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
return b.encodeLits(b.literals, rawAllLits) return b.encodeLits(b.literals, rawAllLits)
} }
// We want some difference to at least account for the headers. // We want some difference to at least account for the headers.
saved := b.size - len(b.literals) - (b.size >> 5) saved := b.size - len(b.literals) - (b.size >> 6)
if saved < 16 { if saved < 16 {
if org == nil { if org == nil {
return errIncompressible return errIncompressible
@ -779,10 +779,13 @@ func (b *blockEnc) encode(org []byte, raw, rawAllLits bool) error {
} }
b.output = wr.out b.output = wr.out
// Maybe even add a bigger margin.
if len(b.output)-3-bhOffset >= b.size { if len(b.output)-3-bhOffset >= b.size {
// Maybe even add a bigger margin. // Discard and encode as raw block.
b.output = b.encodeRawTo(b.output[:bhOffset], org)
b.popOffsets()
b.litEnc.Reuse = huff0.ReusePolicyNone b.litEnc.Reuse = huff0.ReusePolicyNone
return errIncompressible return nil
} }
// Size is output minus block header. // Size is output minus block header.

View File

@ -109,7 +109,7 @@ func (r *readerWrapper) readBig(n int, dst []byte) ([]byte, error) {
} }
func (r *readerWrapper) readByte() (byte, error) { func (r *readerWrapper) readByte() (byte, error) {
n2, err := r.r.Read(r.tmp[:1]) n2, err := io.ReadFull(r.r, r.tmp[:1])
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
err = io.ErrUnexpectedEOF err = io.ErrUnexpectedEOF

View File

@ -455,12 +455,7 @@ func (d *Decoder) nextBlock(blocking bool) (ok bool) {
} }
if len(next.b) > 0 { if len(next.b) > 0 {
n, err := d.current.crc.Write(next.b) d.current.crc.Write(next.b)
if err == nil {
if n != len(next.b) {
d.current.err = io.ErrShortWrite
}
}
} }
if next.err == nil && next.d != nil && next.d.hasCRC { if next.err == nil && next.d != nil && next.d.hasCRC {
got := uint32(d.current.crc.Sum64()) got := uint32(d.current.crc.Sum64())

View File

@ -34,7 +34,7 @@ type match struct {
est int32 est int32
} }
const highScore = 25000 const highScore = maxMatchLen * 8
// estBits will estimate output bits from predefined tables. // estBits will estimate output bits from predefined tables.
func (m *match) estBits(bitsPerByte int32) { func (m *match) estBits(bitsPerByte int32) {
@ -159,7 +159,6 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) {
// nextEmit is where in src the next emitLiteral should start from. // nextEmit is where in src the next emitLiteral should start from.
nextEmit := s nextEmit := s
cv := load6432(src, s)
// Relative offsets // Relative offsets
offset1 := int32(blk.recentOffsets[0]) offset1 := int32(blk.recentOffsets[0])
@ -173,7 +172,6 @@ func (e *bestFastEncoder) Encode(blk *blockEnc, src []byte) {
blk.literals = append(blk.literals, src[nextEmit:until]...) blk.literals = append(blk.literals, src[nextEmit:until]...)
s.litLen = uint32(until - nextEmit) s.litLen = uint32(until - nextEmit)
} }
_ = addLiterals
if debugEncoder { if debugEncoder {
println("recent offsets:", blk.recentOffsets) println("recent offsets:", blk.recentOffsets)
@ -188,7 +186,9 @@ encodeLoop:
panic("offset0 was 0") panic("offset0 was 0")
} }
const goodEnough = 100 const goodEnough = 250
cv := load6432(src, s)
nextHashL := hashLen(cv, bestLongTableBits, bestLongLen) nextHashL := hashLen(cv, bestLongTableBits, bestLongLen)
nextHashS := hashLen(cv, bestShortTableBits, bestShortLen) nextHashS := hashLen(cv, bestShortTableBits, bestShortLen)
@ -201,11 +201,45 @@ encodeLoop:
return return
} }
if debugAsserts { if debugAsserts {
if offset <= 0 {
panic(offset)
}
if !bytes.Equal(src[s:s+4], src[offset:offset+4]) { if !bytes.Equal(src[s:s+4], src[offset:offset+4]) {
panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first)) panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
} }
} }
cand := match{offset: offset, s: s, length: 4 + e.matchlen(s+4, offset+4, src), rep: rep} // Try to quick reject if we already have a long match.
if m.length > 16 {
left := len(src) - int(m.s+m.length)
// If we are too close to the end, keep as is.
if left <= 0 {
return
}
checkLen := m.length - (s - m.s) - 8
if left > 2 && checkLen > 4 {
// Check 4 bytes, 4 bytes from the end of the current match.
a := load3232(src, offset+checkLen)
b := load3232(src, s+checkLen)
if a != b {
return
}
}
}
l := 4 + e.matchlen(s+4, offset+4, src)
if rep < 0 {
// Extend candidate match backwards as far as possible.
tMin := s - e.maxMatchOff
if tMin < 0 {
tMin = 0
}
for offset > tMin && s > nextEmit && src[offset-1] == src[s-1] && l < maxMatchLength {
s--
offset--
l++
}
}
cand := match{offset: offset, s: s, length: l, rep: rep}
cand.estBits(bitsPerByte) cand.estBits(bitsPerByte)
if m.est >= highScore || cand.est-m.est+(cand.s-m.s)*bitsPerByte>>10 < 0 { if m.est >= highScore || cand.est-m.est+(cand.s-m.s)*bitsPerByte>>10 < 0 {
*m = cand *m = cand
@ -219,17 +253,29 @@ encodeLoop:
improve(&best, candidateS.prev-e.cur, s, uint32(cv), -1) improve(&best, candidateS.prev-e.cur, s, uint32(cv), -1)
if canRepeat && best.length < goodEnough { if canRepeat && best.length < goodEnough {
cv32 := uint32(cv >> 8) if s == nextEmit {
spp := s + 1 // Check repeats straight after a match.
improve(&best, spp-offset1, spp, cv32, 1) improve(&best, s-offset2, s, uint32(cv), 1|4)
improve(&best, spp-offset2, spp, cv32, 2) improve(&best, s-offset3, s, uint32(cv), 2|4)
improve(&best, spp-offset3, spp, cv32, 3) if offset1 > 1 {
if best.length > 0 { improve(&best, s-(offset1-1), s, uint32(cv), 3|4)
cv32 = uint32(cv >> 24) }
spp += 2 }
// If either no match or a non-repeat match, check at + 1
if best.rep <= 0 {
cv32 := uint32(cv >> 8)
spp := s + 1
improve(&best, spp-offset1, spp, cv32, 1) improve(&best, spp-offset1, spp, cv32, 1)
improve(&best, spp-offset2, spp, cv32, 2) improve(&best, spp-offset2, spp, cv32, 2)
improve(&best, spp-offset3, spp, cv32, 3) improve(&best, spp-offset3, spp, cv32, 3)
if best.rep < 0 {
cv32 = uint32(cv >> 24)
spp += 2
improve(&best, spp-offset1, spp, cv32, 1)
improve(&best, spp-offset2, spp, cv32, 2)
improve(&best, spp-offset3, spp, cv32, 3)
}
} }
} }
// Load next and check... // Load next and check...
@ -244,41 +290,44 @@ encodeLoop:
if s >= sLimit { if s >= sLimit {
break encodeLoop break encodeLoop
} }
cv = load6432(src, s)
continue continue
} }
s++
candidateS = e.table[hashLen(cv>>8, bestShortTableBits, bestShortLen)] candidateS = e.table[hashLen(cv>>8, bestShortTableBits, bestShortLen)]
cv = load6432(src, s) cv = load6432(src, s+1)
cv2 := load6432(src, s+1) cv2 := load6432(src, s+2)
candidateL = e.longTable[hashLen(cv, bestLongTableBits, bestLongLen)] candidateL = e.longTable[hashLen(cv, bestLongTableBits, bestLongLen)]
candidateL2 := e.longTable[hashLen(cv2, bestLongTableBits, bestLongLen)] candidateL2 := e.longTable[hashLen(cv2, bestLongTableBits, bestLongLen)]
// Short at s+1 // Short at s+1
improve(&best, candidateS.offset-e.cur, s, uint32(cv), -1) improve(&best, candidateS.offset-e.cur, s+1, uint32(cv), -1)
// Long at s+1, s+2 // Long at s+1, s+2
improve(&best, candidateL.offset-e.cur, s, uint32(cv), -1) improve(&best, candidateL.offset-e.cur, s+1, uint32(cv), -1)
improve(&best, candidateL.prev-e.cur, s, uint32(cv), -1) improve(&best, candidateL.prev-e.cur, s+1, uint32(cv), -1)
improve(&best, candidateL2.offset-e.cur, s+1, uint32(cv2), -1) improve(&best, candidateL2.offset-e.cur, s+2, uint32(cv2), -1)
improve(&best, candidateL2.prev-e.cur, s+1, uint32(cv2), -1) improve(&best, candidateL2.prev-e.cur, s+2, uint32(cv2), -1)
if false { if false {
// Short at s+3. // Short at s+3.
// Too often worse... // Too often worse...
improve(&best, e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+2, uint32(cv2>>8), -1) improve(&best, e.table[hashLen(cv2>>8, bestShortTableBits, bestShortLen)].offset-e.cur, s+3, uint32(cv2>>8), -1)
} }
// See if we can find a better match by checking where the current best ends.
// Use that offset to see if we can find a better full match. // Start check at a fixed offset to allow for a few mismatches.
if sAt := best.s + best.length; sAt < sLimit { // For this compression level 2 yields the best results.
nextHashL := hashLen(load6432(src, sAt), bestLongTableBits, bestLongLen) // We cannot do this if we have already indexed this position.
candidateEnd := e.longTable[nextHashL] const skipBeginning = 2
// Start check at a fixed offset to allow for a few mismatches. if best.s > s-skipBeginning {
// For this compression level 2 yields the best results. // See if we can find a better match by checking where the current best ends.
const skipBeginning = 2 // Use that offset to see if we can find a better full match.
if pos := candidateEnd.offset - e.cur - best.length + skipBeginning; pos >= 0 { if sAt := best.s + best.length; sAt < sLimit {
improve(&best, pos, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1) nextHashL := hashLen(load6432(src, sAt), bestLongTableBits, bestLongLen)
if pos := candidateEnd.prev - e.cur - best.length + skipBeginning; pos >= 0 { candidateEnd := e.longTable[nextHashL]
improve(&best, pos, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1)
if off := candidateEnd.offset - e.cur - best.length + skipBeginning; off >= 0 {
improve(&best, off, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1)
if off := candidateEnd.prev - e.cur - best.length + skipBeginning; off >= 0 {
improve(&best, off, best.s+skipBeginning, load3232(src, best.s+skipBeginning), -1)
}
} }
} }
} }
@ -292,51 +341,34 @@ encodeLoop:
// We have a match, we can store the forward value // We have a match, we can store the forward value
if best.rep > 0 { if best.rep > 0 {
s = best.s
var seq seq var seq seq
seq.matchLen = uint32(best.length - zstdMinMatch) seq.matchLen = uint32(best.length - zstdMinMatch)
if debugAsserts && s <= nextEmit {
// We might be able to match backwards. panic("s <= nextEmit")
// Extend as long as we can.
start := best.s
// We end the search early, so we don't risk 0 literals
// and have to do special offset treatment.
startLimit := nextEmit + 1
tMin := s - e.maxMatchOff
if tMin < 0 {
tMin = 0
} }
repIndex := best.offset addLiterals(&seq, best.s)
for repIndex > tMin && start > startLimit && src[repIndex-1] == src[start-1] && seq.matchLen < maxMatchLength-zstdMinMatch-1 {
repIndex--
start--
seq.matchLen++
}
addLiterals(&seq, start)
// rep 0 // Repeat. If bit 4 is set, this is a non-lit repeat.
seq.offset = uint32(best.rep) seq.offset = uint32(best.rep & 3)
if debugSequences { if debugSequences {
println("repeat sequence", seq, "next s:", s) println("repeat sequence", seq, "next s:", s)
} }
blk.sequences = append(blk.sequences, seq) blk.sequences = append(blk.sequences, seq)
// Index match start+1 (long) -> s - 1 // Index old s + 1 -> s - 1
index0 := s index0 := s + 1
s = best.s + best.length s = best.s + best.length
nextEmit = s nextEmit = s
if s >= sLimit { if s >= sLimit {
if debugEncoder { if debugEncoder {
println("repeat ended", s, best.length) println("repeat ended", s, best.length)
} }
break encodeLoop break encodeLoop
} }
// Index skipped... // Index skipped...
off := index0 + e.cur off := index0 + e.cur
for index0 < s-1 { for index0 < s {
cv0 := load6432(src, index0) cv0 := load6432(src, index0)
h0 := hashLen(cv0, bestLongTableBits, bestLongLen) h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
h1 := hashLen(cv0, bestShortTableBits, bestShortLen) h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
@ -346,17 +378,19 @@ encodeLoop:
index0++ index0++
} }
switch best.rep { switch best.rep {
case 2: case 2, 4 | 1:
offset1, offset2 = offset2, offset1 offset1, offset2 = offset2, offset1
case 3: case 3, 4 | 2:
offset1, offset2, offset3 = offset3, offset1, offset2 offset1, offset2, offset3 = offset3, offset1, offset2
case 4 | 3:
offset1, offset2, offset3 = offset1-1, offset1, offset2
} }
cv = load6432(src, s)
continue continue
} }
// A 4-byte match has been found. Update recent offsets. // A 4-byte match has been found. Update recent offsets.
// We'll later see if more than 4 bytes. // We'll later see if more than 4 bytes.
index0 := s + 1
s = best.s s = best.s
t := best.offset t := best.offset
offset1, offset2, offset3 = s-t, offset1, offset2 offset1, offset2, offset3 = s-t, offset1, offset2
@ -369,22 +403,9 @@ encodeLoop:
panic("invalid offset") panic("invalid offset")
} }
// Extend the n-byte match as long as possible.
l := best.length
// Extend backwards
tMin := s - e.maxMatchOff
if tMin < 0 {
tMin = 0
}
for t > tMin && s > nextEmit && src[t-1] == src[s-1] && l < maxMatchLength {
s--
t--
l++
}
// Write our sequence // Write our sequence
var seq seq var seq seq
l := best.length
seq.litLen = uint32(s - nextEmit) seq.litLen = uint32(s - nextEmit)
seq.matchLen = uint32(l - zstdMinMatch) seq.matchLen = uint32(l - zstdMinMatch)
if seq.litLen > 0 { if seq.litLen > 0 {
@ -401,10 +422,8 @@ encodeLoop:
break encodeLoop break encodeLoop
} }
// Index match start+1 (long) -> s - 1 // Index old s + 1 -> s - 1
index0 := s - l + 1 for index0 < s {
// every entry
for index0 < s-1 {
cv0 := load6432(src, index0) cv0 := load6432(src, index0)
h0 := hashLen(cv0, bestLongTableBits, bestLongLen) h0 := hashLen(cv0, bestLongTableBits, bestLongLen)
h1 := hashLen(cv0, bestShortTableBits, bestShortLen) h1 := hashLen(cv0, bestShortTableBits, bestShortLen)
@ -413,50 +432,6 @@ encodeLoop:
e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset} e.table[h1] = prevEntry{offset: off, prev: e.table[h1].offset}
index0++ index0++
} }
cv = load6432(src, s)
if !canRepeat {
continue
}
// Check offset 2
for {
o2 := s - offset2
if load3232(src, o2) != uint32(cv) {
// Do regular search
break
}
// Store this, since we have it.
nextHashS := hashLen(cv, bestShortTableBits, bestShortLen)
nextHashL := hashLen(cv, bestLongTableBits, bestLongLen)
// We have at least 4 byte match.
// No need to check backwards. We come straight from a match
l := 4 + e.matchlen(s+4, o2+4, src)
e.longTable[nextHashL] = prevEntry{offset: s + e.cur, prev: e.longTable[nextHashL].offset}
e.table[nextHashS] = prevEntry{offset: s + e.cur, prev: e.table[nextHashS].offset}
seq.matchLen = uint32(l) - zstdMinMatch
seq.litLen = 0
// Since litlen is always 0, this is offset 1.
seq.offset = 1
s += l
nextEmit = s
if debugSequences {
println("sequence", seq, "next s:", s)
}
blk.sequences = append(blk.sequences, seq)
// Swap offset 1 and 2.
offset1, offset2 = offset2, offset1
if s >= sLimit {
// Finished
break encodeLoop
}
cv = load6432(src, s)
}
} }
if int(nextEmit) < len(src) { if int(nextEmit) < len(src) {

View File

@ -277,23 +277,9 @@ func (e *Encoder) nextBlock(final bool) error {
s.eofWritten = true s.eofWritten = true
} }
err := errIncompressible s.err = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
// If we got the exact same number of literals as input, if s.err != nil {
// assume the literals cannot be compressed. return s.err
if len(src) != len(blk.literals) || len(src) != e.o.blockSize {
err = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
}
switch err {
case errIncompressible:
if debugEncoder {
println("Storing incompressible block as raw")
}
blk.encodeRaw(src)
// In fast mode, we do not transfer offsets, so we don't have to deal with changing the.
case nil:
default:
s.err = err
return err
} }
_, s.err = s.w.Write(blk.output) _, s.err = s.w.Write(blk.output)
s.nWritten += int64(len(blk.output)) s.nWritten += int64(len(blk.output))
@ -343,22 +329,8 @@ func (e *Encoder) nextBlock(final bool) error {
} }
s.wWg.Done() s.wWg.Done()
}() }()
err := errIncompressible s.writeErr = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
// If we got the exact same number of literals as input, if s.writeErr != nil {
// assume the literals cannot be compressed.
if len(src) != len(blk.literals) || len(src) != e.o.blockSize {
err = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
}
switch err {
case errIncompressible:
if debugEncoder {
println("Storing incompressible block as raw")
}
blk.encodeRaw(src)
// In fast mode, we do not transfer offsets, so we don't have to deal with changing the.
case nil:
default:
s.writeErr = err
return return
} }
_, s.writeErr = s.w.Write(blk.output) _, s.writeErr = s.w.Write(blk.output)
@ -568,25 +540,15 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
// If we got the exact same number of literals as input, // If we got the exact same number of literals as input,
// assume the literals cannot be compressed. // assume the literals cannot be compressed.
err := errIncompressible
oldout := blk.output oldout := blk.output
if len(blk.literals) != len(src) || len(src) != e.o.blockSize { // Output directly to dst
// Output directly to dst blk.output = dst
blk.output = dst
err = blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
}
switch err { err := blk.encode(src, e.o.noEntropy, !e.o.allLitEntropy)
case errIncompressible: if err != nil {
if debugEncoder {
println("Storing incompressible block as raw")
}
dst = blk.encodeRawTo(dst, src)
case nil:
dst = blk.output
default:
panic(err) panic(err)
} }
dst = blk.output
blk.output = oldout blk.output = oldout
} else { } else {
enc.Reset(e.o.dict, false) enc.Reset(e.o.dict, false)
@ -605,25 +567,11 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
if len(src) == 0 { if len(src) == 0 {
blk.last = true blk.last = true
} }
err := errIncompressible err := blk.encode(todo, e.o.noEntropy, !e.o.allLitEntropy)
// If we got the exact same number of literals as input, if err != nil {
// assume the literals cannot be compressed.
if len(blk.literals) != len(todo) || len(todo) != e.o.blockSize {
err = blk.encode(todo, e.o.noEntropy, !e.o.allLitEntropy)
}
switch err {
case errIncompressible:
if debugEncoder {
println("Storing incompressible block as raw")
}
dst = blk.encodeRawTo(dst, todo)
blk.popOffsets()
case nil:
dst = append(dst, blk.output...)
default:
panic(err) panic(err)
} }
dst = append(dst, blk.output...)
blk.reset(nil) blk.reset(nil)
} }
} }

View File

@ -39,7 +39,7 @@ func (o *encoderOptions) setDefault() {
blockSize: maxCompressedBlockSize, blockSize: maxCompressedBlockSize,
windowSize: 8 << 20, windowSize: 8 << 20,
level: SpeedDefault, level: SpeedDefault,
allLitEntropy: true, allLitEntropy: false,
lowMem: false, lowMem: false,
} }
} }
@ -238,7 +238,7 @@ func WithEncoderLevel(l EncoderLevel) EOption {
} }
} }
if !o.customALEntropy { if !o.customALEntropy {
o.allLitEntropy = l > SpeedFastest o.allLitEntropy = l > SpeedDefault
} }
return nil return nil

View File

@ -293,13 +293,9 @@ func (d *frameDec) next(block *blockDec) error {
return nil return nil
} }
// checkCRC will check the checksum if the frame has one. // checkCRC will check the checksum, assuming the frame has one.
// Will return ErrCRCMismatch if crc check failed, otherwise nil. // Will return ErrCRCMismatch if crc check failed, otherwise nil.
func (d *frameDec) checkCRC() error { func (d *frameDec) checkCRC() error {
if !d.HasCheckSum {
return nil
}
// We can overwrite upper tmp now // We can overwrite upper tmp now
buf, err := d.rawInput.readSmall(4) buf, err := d.rawInput.readSmall(4)
if err != nil { if err != nil {
@ -307,10 +303,6 @@ func (d *frameDec) checkCRC() error {
return err return err
} }
if d.o.ignoreChecksum {
return nil
}
want := binary.LittleEndian.Uint32(buf[:4]) want := binary.LittleEndian.Uint32(buf[:4])
got := uint32(d.crc.Sum64()) got := uint32(d.crc.Sum64())
@ -326,17 +318,13 @@ func (d *frameDec) checkCRC() error {
return nil return nil
} }
// consumeCRC reads the checksum data if the frame has one. // consumeCRC skips over the checksum, assuming the frame has one.
func (d *frameDec) consumeCRC() error { func (d *frameDec) consumeCRC() error {
if d.HasCheckSum { _, err := d.rawInput.readSmall(4)
_, err := d.rawInput.readSmall(4) if err != nil {
if err != nil { println("CRC missing?", err)
println("CRC missing?", err)
return err
}
} }
return err
return nil
} }
// runDecoder will run the decoder for the remainder of the frame. // runDecoder will run the decoder for the remainder of the frame.
@ -415,15 +403,8 @@ func (d *frameDec) runDecoder(dst []byte, dec *blockDec) ([]byte, error) {
if d.o.ignoreChecksum { if d.o.ignoreChecksum {
err = d.consumeCRC() err = d.consumeCRC()
} else { } else {
var n int d.crc.Write(dst[crcStart:])
n, err = d.crc.Write(dst[crcStart:]) err = d.checkCRC()
if err == nil {
if n != len(dst)-crcStart {
err = io.ErrShortWrite
} else {
err = d.checkCRC()
}
}
} }
} }
} }

View File

@ -236,9 +236,12 @@ func (s *sequenceDecs) decodeSync(hist []byte) error {
maxBlockSize = s.windowSize maxBlockSize = s.windowSize
} }
if debugDecoder {
println("decodeSync: decoding", seqs, "sequences", br.remain(), "bits remain on stream")
}
for i := seqs - 1; i >= 0; i-- { for i := seqs - 1; i >= 0; i-- {
if br.overread() { if br.overread() {
printf("reading sequence %d, exceeded available data\n", seqs-i) printf("reading sequence %d, exceeded available data. Overread by %d\n", seqs-i, -br.remain())
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
var ll, mo, ml int var ll, mo, ml int

View File

@ -5,6 +5,7 @@ package zstd
import ( import (
"fmt" "fmt"
"io"
"github.com/klauspost/compress/internal/cpuinfo" "github.com/klauspost/compress/internal/cpuinfo"
) )
@ -134,6 +135,9 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", return true, fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available",
ctx.ll, ctx.litRemain+ctx.ll) ctx.ll, ctx.litRemain+ctx.ll)
case errorOverread:
return true, io.ErrUnexpectedEOF
case errorNotEnoughSpace: case errorNotEnoughSpace:
size := ctx.outPosition + ctx.ll + ctx.ml size := ctx.outPosition + ctx.ll + ctx.ml
if debugDecoder { if debugDecoder {
@ -202,6 +206,9 @@ const errorNotEnoughLiterals = 4
// error reported when capacity of `out` is too small // error reported when capacity of `out` is too small
const errorNotEnoughSpace = 5 const errorNotEnoughSpace = 5
// error reported when bits are overread.
const errorOverread = 6
// sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm. // sequenceDecs_decode implements the main loop of sequenceDecs in x86 asm.
// //
// Please refer to seqdec_generic.go for the reference implementation. // Please refer to seqdec_generic.go for the reference implementation.
@ -247,6 +254,10 @@ func (s *sequenceDecs) decode(seqs []seqVals) error {
litRemain: len(s.literals), litRemain: len(s.literals),
} }
if debugDecoder {
println("decode: decoding", len(seqs), "sequences", br.remain(), "bits remain on stream")
}
s.seqSize = 0 s.seqSize = 0
lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56 lte56bits := s.maxBits+s.offsets.fse.actualTableLog+s.matchLengths.fse.actualTableLog+s.litLengths.fse.actualTableLog <= 56
var errCode int var errCode int
@ -277,6 +288,8 @@ func (s *sequenceDecs) decode(seqs []seqVals) error {
case errorNotEnoughLiterals: case errorNotEnoughLiterals:
ll := ctx.seqs[i].ll ll := ctx.seqs[i].ll
return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll) return fmt.Errorf("unexpected literal count, want %d bytes, but only %d is available", ll, ctx.litRemain+ll)
case errorOverread:
return io.ErrUnexpectedEOF
} }
return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode) return fmt.Errorf("sequenceDecs_decode_amd64 returned erronous code %d", errCode)
@ -291,6 +304,9 @@ func (s *sequenceDecs) decode(seqs []seqVals) error {
if s.seqSize > maxBlockSize { if s.seqSize > maxBlockSize {
return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize) return fmt.Errorf("output bigger than max block size (%d)", maxBlockSize)
} }
if debugDecoder {
println("decode: ", br.remain(), "bits remain on stream. code:", errCode)
}
err := br.close() err := br.close()
if err != nil { if err != nil {
printf("Closing sequences: %v, %+v\n", err, *br) printf("Closing sequences: %v, %+v\n", err, *br)

View File

@ -38,7 +38,7 @@ sequenceDecs_decode_amd64_main_loop:
sequenceDecs_decode_amd64_fill_byte_by_byte: sequenceDecs_decode_amd64_fill_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decode_amd64_fill_end JLE sequenceDecs_decode_amd64_fill_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decode_amd64_fill_end JLE sequenceDecs_decode_amd64_fill_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -49,6 +49,10 @@ sequenceDecs_decode_amd64_fill_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decode_amd64_fill_byte_by_byte JMP sequenceDecs_decode_amd64_fill_byte_by_byte
sequenceDecs_decode_amd64_fill_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decode_amd64_fill_end: sequenceDecs_decode_amd64_fill_end:
// Update offset // Update offset
MOVQ R9, AX MOVQ R9, AX
@ -105,7 +109,7 @@ sequenceDecs_decode_amd64_ml_update_zero:
sequenceDecs_decode_amd64_fill_2_byte_by_byte: sequenceDecs_decode_amd64_fill_2_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decode_amd64_fill_2_end JLE sequenceDecs_decode_amd64_fill_2_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decode_amd64_fill_2_end JLE sequenceDecs_decode_amd64_fill_2_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -116,6 +120,10 @@ sequenceDecs_decode_amd64_fill_2_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte JMP sequenceDecs_decode_amd64_fill_2_byte_by_byte
sequenceDecs_decode_amd64_fill_2_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decode_amd64_fill_2_end: sequenceDecs_decode_amd64_fill_2_end:
// Update literal length // Update literal length
MOVQ DI, AX MOVQ DI, AX
@ -320,6 +328,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // func sequenceDecs_decode_56_amd64(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
// Requires: CMOV // Requires: CMOV
TEXT ·sequenceDecs_decode_56_amd64(SB), $8-32 TEXT ·sequenceDecs_decode_56_amd64(SB), $8-32
@ -356,7 +369,7 @@ sequenceDecs_decode_56_amd64_main_loop:
sequenceDecs_decode_56_amd64_fill_byte_by_byte: sequenceDecs_decode_56_amd64_fill_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decode_56_amd64_fill_end JLE sequenceDecs_decode_56_amd64_fill_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decode_56_amd64_fill_end JLE sequenceDecs_decode_56_amd64_fill_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -367,6 +380,10 @@ sequenceDecs_decode_56_amd64_fill_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte JMP sequenceDecs_decode_56_amd64_fill_byte_by_byte
sequenceDecs_decode_56_amd64_fill_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decode_56_amd64_fill_end: sequenceDecs_decode_56_amd64_fill_end:
// Update offset // Update offset
MOVQ R9, AX MOVQ R9, AX
@ -613,6 +630,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // func sequenceDecs_decode_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
// Requires: BMI, BMI2, CMOV // Requires: BMI, BMI2, CMOV
TEXT ·sequenceDecs_decode_bmi2(SB), $8-32 TEXT ·sequenceDecs_decode_bmi2(SB), $8-32
@ -649,7 +671,7 @@ sequenceDecs_decode_bmi2_main_loop:
sequenceDecs_decode_bmi2_fill_byte_by_byte: sequenceDecs_decode_bmi2_fill_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decode_bmi2_fill_end JLE sequenceDecs_decode_bmi2_fill_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decode_bmi2_fill_end JLE sequenceDecs_decode_bmi2_fill_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -660,6 +682,10 @@ sequenceDecs_decode_bmi2_fill_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decode_bmi2_fill_byte_by_byte JMP sequenceDecs_decode_bmi2_fill_byte_by_byte
sequenceDecs_decode_bmi2_fill_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decode_bmi2_fill_end: sequenceDecs_decode_bmi2_fill_end:
// Update offset // Update offset
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -700,7 +726,7 @@ sequenceDecs_decode_bmi2_fill_end:
sequenceDecs_decode_bmi2_fill_2_byte_by_byte: sequenceDecs_decode_bmi2_fill_2_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decode_bmi2_fill_2_end JLE sequenceDecs_decode_bmi2_fill_2_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decode_bmi2_fill_2_end JLE sequenceDecs_decode_bmi2_fill_2_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -711,6 +737,10 @@ sequenceDecs_decode_bmi2_fill_2_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decode_bmi2_fill_2_byte_by_byte JMP sequenceDecs_decode_bmi2_fill_2_byte_by_byte
sequenceDecs_decode_bmi2_fill_2_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decode_bmi2_fill_2_end: sequenceDecs_decode_bmi2_fill_2_end:
// Update literal length // Update literal length
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -889,6 +919,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int // func sequenceDecs_decode_56_bmi2(s *sequenceDecs, br *bitReader, ctx *decodeAsmContext) int
// Requires: BMI, BMI2, CMOV // Requires: BMI, BMI2, CMOV
TEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32 TEXT ·sequenceDecs_decode_56_bmi2(SB), $8-32
@ -925,7 +960,7 @@ sequenceDecs_decode_56_bmi2_main_loop:
sequenceDecs_decode_56_bmi2_fill_byte_by_byte: sequenceDecs_decode_56_bmi2_fill_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decode_56_bmi2_fill_end JLE sequenceDecs_decode_56_bmi2_fill_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decode_56_bmi2_fill_end JLE sequenceDecs_decode_56_bmi2_fill_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -936,6 +971,10 @@ sequenceDecs_decode_56_bmi2_fill_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decode_56_bmi2_fill_byte_by_byte JMP sequenceDecs_decode_56_bmi2_fill_byte_by_byte
sequenceDecs_decode_56_bmi2_fill_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decode_56_bmi2_fill_end: sequenceDecs_decode_56_bmi2_fill_end:
// Update offset // Update offset
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -1140,6 +1179,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool // func sequenceDecs_executeSimple_amd64(ctx *executeAsmContext) bool
// Requires: SSE // Requires: SSE
TEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9 TEXT ·sequenceDecs_executeSimple_amd64(SB), $8-9
@ -1804,7 +1848,7 @@ sequenceDecs_decodeSync_amd64_main_loop:
sequenceDecs_decodeSync_amd64_fill_byte_by_byte: sequenceDecs_decodeSync_amd64_fill_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decodeSync_amd64_fill_end JLE sequenceDecs_decodeSync_amd64_fill_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decodeSync_amd64_fill_end JLE sequenceDecs_decodeSync_amd64_fill_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -1815,6 +1859,10 @@ sequenceDecs_decodeSync_amd64_fill_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte JMP sequenceDecs_decodeSync_amd64_fill_byte_by_byte
sequenceDecs_decodeSync_amd64_fill_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decodeSync_amd64_fill_end: sequenceDecs_decodeSync_amd64_fill_end:
// Update offset // Update offset
MOVQ R9, AX MOVQ R9, AX
@ -1871,7 +1919,7 @@ sequenceDecs_decodeSync_amd64_ml_update_zero:
sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte: sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decodeSync_amd64_fill_2_end JLE sequenceDecs_decodeSync_amd64_fill_2_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decodeSync_amd64_fill_2_end JLE sequenceDecs_decodeSync_amd64_fill_2_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -1882,6 +1930,10 @@ sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte JMP sequenceDecs_decodeSync_amd64_fill_2_byte_by_byte
sequenceDecs_decodeSync_amd64_fill_2_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decodeSync_amd64_fill_2_end: sequenceDecs_decodeSync_amd64_fill_2_end:
// Update literal length // Update literal length
MOVQ DI, AX MOVQ DI, AX
@ -2291,6 +2343,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// Return with not enough output space error // Return with not enough output space error
error_not_enough_space: error_not_enough_space:
MOVQ ctx+16(FP), AX MOVQ ctx+16(FP), AX
@ -2356,7 +2413,7 @@ sequenceDecs_decodeSync_bmi2_main_loop:
sequenceDecs_decodeSync_bmi2_fill_byte_by_byte: sequenceDecs_decodeSync_bmi2_fill_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decodeSync_bmi2_fill_end JLE sequenceDecs_decodeSync_bmi2_fill_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decodeSync_bmi2_fill_end JLE sequenceDecs_decodeSync_bmi2_fill_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -2367,6 +2424,10 @@ sequenceDecs_decodeSync_bmi2_fill_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decodeSync_bmi2_fill_byte_by_byte JMP sequenceDecs_decodeSync_bmi2_fill_byte_by_byte
sequenceDecs_decodeSync_bmi2_fill_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decodeSync_bmi2_fill_end: sequenceDecs_decodeSync_bmi2_fill_end:
// Update offset // Update offset
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -2407,7 +2468,7 @@ sequenceDecs_decodeSync_bmi2_fill_end:
sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte: sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decodeSync_bmi2_fill_2_end JLE sequenceDecs_decodeSync_bmi2_fill_2_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decodeSync_bmi2_fill_2_end JLE sequenceDecs_decodeSync_bmi2_fill_2_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -2418,6 +2479,10 @@ sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte JMP sequenceDecs_decodeSync_bmi2_fill_2_byte_by_byte
sequenceDecs_decodeSync_bmi2_fill_2_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decodeSync_bmi2_fill_2_end: sequenceDecs_decodeSync_bmi2_fill_2_end:
// Update literal length // Update literal length
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -2801,6 +2866,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// Return with not enough output space error // Return with not enough output space error
error_not_enough_space: error_not_enough_space:
MOVQ ctx+16(FP), AX MOVQ ctx+16(FP), AX
@ -2866,7 +2936,7 @@ sequenceDecs_decodeSync_safe_amd64_main_loop:
sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte: sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decodeSync_safe_amd64_fill_end JLE sequenceDecs_decodeSync_safe_amd64_fill_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decodeSync_safe_amd64_fill_end JLE sequenceDecs_decodeSync_safe_amd64_fill_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -2877,6 +2947,10 @@ sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte JMP sequenceDecs_decodeSync_safe_amd64_fill_byte_by_byte
sequenceDecs_decodeSync_safe_amd64_fill_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decodeSync_safe_amd64_fill_end: sequenceDecs_decodeSync_safe_amd64_fill_end:
// Update offset // Update offset
MOVQ R9, AX MOVQ R9, AX
@ -2933,7 +3007,7 @@ sequenceDecs_decodeSync_safe_amd64_ml_update_zero:
sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte: sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte:
CMPQ SI, $0x00 CMPQ SI, $0x00
JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end JLE sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread
CMPQ BX, $0x07 CMPQ BX, $0x07
JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end JLE sequenceDecs_decodeSync_safe_amd64_fill_2_end
SHLQ $0x08, DX SHLQ $0x08, DX
@ -2944,6 +3018,10 @@ sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte:
ORQ AX, DX ORQ AX, DX
JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte JMP sequenceDecs_decodeSync_safe_amd64_fill_2_byte_by_byte
sequenceDecs_decodeSync_safe_amd64_fill_2_check_overread:
CMPQ BX, $0x40
JA error_overread
sequenceDecs_decodeSync_safe_amd64_fill_2_end: sequenceDecs_decodeSync_safe_amd64_fill_2_end:
// Update literal length // Update literal length
MOVQ DI, AX MOVQ DI, AX
@ -3455,6 +3533,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// Return with not enough output space error // Return with not enough output space error
error_not_enough_space: error_not_enough_space:
MOVQ ctx+16(FP), AX MOVQ ctx+16(FP), AX
@ -3520,7 +3603,7 @@ sequenceDecs_decodeSync_safe_bmi2_main_loop:
sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte: sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decodeSync_safe_bmi2_fill_end JLE sequenceDecs_decodeSync_safe_bmi2_fill_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decodeSync_safe_bmi2_fill_end JLE sequenceDecs_decodeSync_safe_bmi2_fill_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -3531,6 +3614,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte JMP sequenceDecs_decodeSync_safe_bmi2_fill_byte_by_byte
sequenceDecs_decodeSync_safe_bmi2_fill_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decodeSync_safe_bmi2_fill_end: sequenceDecs_decodeSync_safe_bmi2_fill_end:
// Update offset // Update offset
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -3571,7 +3658,7 @@ sequenceDecs_decodeSync_safe_bmi2_fill_end:
sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte: sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte:
CMPQ BX, $0x00 CMPQ BX, $0x00
JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread
CMPQ DX, $0x07 CMPQ DX, $0x07
JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end JLE sequenceDecs_decodeSync_safe_bmi2_fill_2_end
SHLQ $0x08, AX SHLQ $0x08, AX
@ -3582,6 +3669,10 @@ sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte:
ORQ CX, AX ORQ CX, AX
JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte JMP sequenceDecs_decodeSync_safe_bmi2_fill_2_byte_by_byte
sequenceDecs_decodeSync_safe_bmi2_fill_2_check_overread:
CMPQ DX, $0x40
JA error_overread
sequenceDecs_decodeSync_safe_bmi2_fill_2_end: sequenceDecs_decodeSync_safe_bmi2_fill_2_end:
// Update literal length // Update literal length
MOVQ $0x00000808, CX MOVQ $0x00000808, CX
@ -4067,6 +4158,11 @@ error_not_enough_literals:
MOVQ $0x00000004, ret+24(FP) MOVQ $0x00000004, ret+24(FP)
RET RET
// Return with overread error
error_overread:
MOVQ $0x00000006, ret+24(FP)
RET
// Return with not enough output space error // Return with not enough output space error
error_not_enough_space: error_not_enough_space:
MOVQ ctx+16(FP), AX MOVQ ctx+16(FP), AX

View File

@ -128,11 +128,11 @@ func matchLen(a, b []byte) (n int) {
} }
func load3232(b []byte, i int32) uint32 { func load3232(b []byte, i int32) uint32 {
return binary.LittleEndian.Uint32(b[i:]) return binary.LittleEndian.Uint32(b[:len(b):len(b)][i:])
} }
func load6432(b []byte, i int32) uint64 { func load6432(b []byte, i int32) uint64 {
return binary.LittleEndian.Uint64(b[i:]) return binary.LittleEndian.Uint64(b[:len(b):len(b)][i:])
} }
type byter interface { type byter interface {

2
vendor/modules.txt vendored
View File

@ -138,7 +138,7 @@ github.com/imdario/mergo
# github.com/inconshreveable/mousetrap v1.1.0 # github.com/inconshreveable/mousetrap v1.1.0
## explicit; go 1.18 ## explicit; go 1.18
github.com/inconshreveable/mousetrap github.com/inconshreveable/mousetrap
# github.com/klauspost/compress v1.16.3 # github.com/klauspost/compress v1.16.5
## explicit; go 1.18 ## explicit; go 1.18
github.com/klauspost/compress github.com/klauspost/compress
github.com/klauspost/compress/fse github.com/klauspost/compress/fse