build(deps): bump github.com/klauspost/compress from 1.19.1 to 1.19.2

Bumps [github.com/klauspost/compress](https://github.com/klauspost/compress) from 1.19.1 to 1.19.2.
- [Release notes](https://github.com/klauspost/compress/releases)
- [Commits](https://github.com/klauspost/compress/compare/v1.19.1...v1.19.2)

---
updated-dependencies:
- dependency-name: github.com/klauspost/compress
  dependency-version: 1.19.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot] authored and GitHub committed 2026-08-14 23:24:18 +00:00
1 parent e1bbb3df6a
commit da7420a420
14 files changed
+1525 -505

No files matched your search

+1 -1
View File
@@ -44,7 +44,7 @@ require (
github.com/google/uuid v1.6.0
github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0
github.com/intel/goresctrl v0.13.0
github.com/klauspost/compress v1.19.1
github.com/klauspost/compress v1.19.2
github.com/mdlayher/vsock v1.3.0
github.com/moby/locker v1.0.1
github.com/moby/sys/mountinfo v0.7.2
+2 -2
View File
@@ -205,8 +205,8 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.19.2 h1:hMRETovs/pu/dVWN7zIT1PGG8t509MwT6bO7XSi26R8=
github.com/klauspost/compress v1.19.2/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/knqyf263/go-plugin v0.9.0 h1:CQs2+lOPIlkZVtcb835ZYDEoyyWJWLbSTWeCs0EwTwI=
github.com/knqyf263/go-plugin v0.9.0/go.mod h1:2z5lCO1/pez6qGo8CvCxSlBFSEat4MEp1DrnA+f7w8Q=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+15 -188
View File
@@ -1,222 +1,49 @@
//go:build amd64 && !appengine && !noasm && gc
// This file contains the specialisation of Decoder.Decompress4X
// and Decoder.Decompress1X that use an asm implementation of thir main loops.
// amd64 stubs and dispatch for the asm loops used by decompress_asm.go.
package huff0
import (
"errors"
"fmt"
"github.com/klauspost/compress/internal/cpuinfo"
)
// decompress4x_main_loop_x86 is an x86 assembler implementation
// decompress4x_main_loop_amd64 is an x86 assembler implementation
// of Decompress4X when tablelog > 8.
//
//go:noescape
func decompress4x_main_loop_amd64(ctx *decompress4xContext)
// decompress4x_8b_loop_x86 is an x86 assembler implementation
// decompress4x_8b_main_loop_amd64 is an x86 assembler implementation
// of Decompress4X when tablelog <= 8 which decodes 4 entries
// per loop.
//
//go:noescape
func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext)
// fallback8BitSize is the size where using Go version is faster.
const fallback8BitSize = 800
type decompress4xContext struct {
pbr *[4]bitReaderShifted
peekBits uint8
out *byte
dstEvery int
tbl *dEntrySingle
decoded int
limit *byte
}
// Decompress4X will decompress a 4X encoded stream.
// The length of the supplied input must match the end of a block exactly.
// The *capacity* of the dst slice must match the destination size of
// the uncompressed data exactly.
func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
if len(d.dt.single) == 0 {
return nil, errors.New("no table loaded")
}
if len(src) < 6+(4*1) {
return nil, errors.New("input too small")
}
use8BitTables := d.actualTableLog <= 8
if cap(dst) < fallback8BitSize && use8BitTables {
return d.decompress4X8bit(dst, src)
}
var br [4]bitReaderShifted
// Decode "jump table"
start := 6
for i := range 3 {
length := int(src[i*2]) | (int(src[i*2+1]) << 8)
if start+length >= len(src) {
return nil, errors.New("truncated input (or invalid offset)")
}
err := br[i].init(src[start : start+length])
if err != nil {
return nil, err
}
start += length
}
err := br[3].init(src[start:])
if err != nil {
return nil, err
}
// destination, offset to match first output
dstSize := cap(dst)
dst = dst[:dstSize]
out := dst
dstEvery := (dstSize + 3) / 4
const tlSize = 1 << tableLogMax
const tlMask = tlSize - 1
single := d.dt.single[:tlSize]
var decoded int
if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) {
ctx := decompress4xContext{
pbr: &br,
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
out: &out[0],
dstEvery: dstEvery,
tbl: &single[0],
limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last.
}
if use8BitTables {
decompress4x_8b_main_loop_amd64(&ctx)
} else {
decompress4x_main_loop_amd64(&ctx)
}
decoded = ctx.decoded
out = out[decoded/4:]
}
// Decode remaining.
remainBytes := dstEvery - (decoded / 4)
for i := range br {
offset := dstEvery * i
endsAt := min(offset+remainBytes, len(out))
br := &br[i]
bitsLeft := br.remaining()
for bitsLeft > 0 {
br.fill()
if offset >= endsAt {
return nil, errors.New("corruption detected: stream overrun 4")
}
// Read value and increment offset.
val := br.peekBitsFast(d.actualTableLog)
v := single[val&tlMask].entry
nBits := uint8(v)
br.advance(nBits)
bitsLeft -= uint(nBits)
out[offset] = uint8(v >> 8)
offset++
}
if offset != endsAt {
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
}
decoded += offset - dstEvery*i
err = br.close()
if err != nil {
return nil, err
}
}
if dstSize != decoded {
return nil, errors.New("corruption detected: short output block")
}
return dst, nil
}
// decompress4x_main_loop_x86 is an x86 assembler implementation
// decompress1x_main_loop_amd64 is an x86 assembler implementation
// of Decompress1X when tablelog > 8.
//
//go:noescape
func decompress1x_main_loop_amd64(ctx *decompress1xContext)
// decompress4x_main_loop_x86 is an x86 with BMI2 assembler implementation
// decompress1x_main_loop_bmi2 is an x86 with BMI2 assembler implementation
// of Decompress1X when tablelog > 8.
//
//go:noescape
func decompress1x_main_loop_bmi2(ctx *decompress1xContext)
type decompress1xContext struct {
pbr *bitReaderShifted
peekBits uint8
out *byte
outCap int
tbl *dEntrySingle
decoded int
func decompress4x_main_loop_asm(ctx *decompress4xContext) {
decompress4x_main_loop_amd64(ctx)
}
// Error reported by asm implementations
const error_max_decoded_size_exeeded = -1
func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) {
decompress4x_8b_main_loop_amd64(ctx)
}
// Decompress1X will decompress a 1X encoded stream.
// The cap of the output buffer will be the maximum decompressed size.
// The length of the supplied input must match the end of a block exactly.
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
if len(d.dt.single) == 0 {
return nil, errors.New("no table loaded")
func decompress1x_main_loop_asm(ctx *decompress1xContext) {
if cpuinfo.HasBMI2() {
decompress1x_main_loop_bmi2(ctx)
} else {
decompress1x_main_loop_amd64(ctx)
}
var br bitReaderShifted
err := br.init(src)
if err != nil {
return dst, err
}
maxDecodedSize := cap(dst)
dst = dst[:maxDecodedSize]
const tlSize = 1 << tableLogMax
const tlMask = tlSize - 1
if maxDecodedSize >= 4 {
ctx := decompress1xContext{
pbr: &br,
out: &dst[0],
outCap: maxDecodedSize,
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
tbl: &d.dt.single[0],
}
if cpuinfo.HasBMI2() {
decompress1x_main_loop_bmi2(&ctx)
} else {
decompress1x_main_loop_amd64(&ctx)
}
if ctx.decoded == error_max_decoded_size_exeeded {
return nil, ErrMaxDecodedSizeExceeded
}
dst = dst[:ctx.decoded]
}
// br < 8, so uint8 is fine
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
for bitsLeft > 0 {
br.fill()
if len(dst) >= maxDecodedSize {
br.close()
return nil, ErrMaxDecodedSizeExceeded
}
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
nBits := uint8(v.entry)
br.advance(nBits)
bitsLeft -= nBits
dst = append(dst, uint8(v.entry>>8))
}
return dst, br.close()
}
+2 -2
View File
@@ -1,6 +1,6 @@
// Code generated by command: go run gen.go -out ../decompress_amd64.s -pkg=huff0. DO NOT EDIT.
// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT.
//go:build amd64 && !appengine && !noasm && gc
//go:build !appengine && !noasm && gc
// func decompress4x_main_loop_amd64(ctx *decompress4xContext)
TEXT ·decompress4x_main_loop_amd64(SB), $0-8
+37
View File
@@ -0,0 +1,37 @@
//go:build arm64 && !appengine && !noasm && gc
// arm64 stubs and dispatch for the asm loops used by decompress_asm.go.
// The asm (decompress_arm64.s) is generated by the avo arm64 lowering
// printer from the same source as the amd64 asm; see _generate/gen.go.
package huff0
// decompress4x_main_loop_arm64 is an arm64 assembler implementation
// of Decompress4X when tablelog > 8.
//
//go:noescape
func decompress4x_main_loop_arm64(ctx *decompress4xContext)
// decompress4x_8b_main_loop_arm64 is an arm64 assembler implementation
// of Decompress4X when tablelog <= 8 which decodes 4 entries
// per loop.
//
//go:noescape
func decompress4x_8b_main_loop_arm64(ctx *decompress4xContext)
// decompress1x_main_loop_arm64 is an arm64 assembler implementation
// of Decompress1X when tablelog > 8.
//
//go:noescape
func decompress1x_main_loop_arm64(ctx *decompress1xContext)
func decompress4x_main_loop_asm(ctx *decompress4xContext) {
decompress4x_main_loop_arm64(ctx)
}
func decompress4x_8b_main_loop_asm(ctx *decompress4xContext) {
decompress4x_8b_main_loop_arm64(ctx)
}
func decompress1x_main_loop_asm(ctx *decompress1xContext) {
decompress1x_main_loop_arm64(ctx)
}
+851
View File
@@ -0,0 +1,851 @@
// Code generated by command: go run gen.go -out ../decompress.s -arch amd64,arm64 -pkg=huff0. DO NOT EDIT.
// EXPERIMENTAL arm64 output lowered from an amd64 avo program.
//go:build arm64 && !appengine && !noasm && gc
// func decompress4x_main_loop_amd64(ctx *decompress4xContext)
TEXT ·decompress4x_main_loop_arm64(SB), $0-8
// Preload values
MOVD ctx+0(FP), R0
MOVBU 8(R0), R6
MOVD 16(R0), R3
MOVD 48(R0), R5
MOVD 24(R0), R7
MOVD 32(R0), R8
MOVD (R0), R9
// Main loop
main_loop:
MOVD $0, R2
CMP R5, R3
CSET GE, R16
BFI $0, R16, $8, R2
// br0.fillFast32()
MOVD 32(R9), R10
MOVBU 40(R9), R11
CMP $0x20, R11
BLS skip_fill0
MOVD 24(R9), R0
SUB $0x20, R11, R11
SUB $0x04, R0, R0
MOVD (R9), R12
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R12, R0, R15
MOVWU (R15), R12
MOVD R11, R1
LSL R1, R12, R12
MOVD R0, 24(R9)
ORR R12, R10, R10
// exhausted += (br0.off < 4)
CMP $0x04, R0
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill0:
// val0 := br0.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br0.peekTopBits(peekBits)
MOVD R6, R1
MOVD R10, R12
LSR R1, R12, R12
// v1 := table[val1&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v1.entry))
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// these two writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
MOVH R0, (R3)
// update the bitreader structure
MOVD R10, 32(R9)
MOVB R11, 40(R9)
// br1.fillFast32()
MOVD 80(R9), R10
MOVBU 88(R9), R11
CMP $0x20, R11
BLS skip_fill1
MOVD 72(R9), R0
SUB $0x20, R11, R11
SUB $0x04, R0, R0
MOVD 48(R9), R12
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R12, R0, R15
MOVWU (R15), R12
MOVD R11, R1
LSL R1, R12, R12
MOVD R0, 72(R9)
ORR R12, R10, R10
// exhausted += (br1.off < 4)
CMP $0x04, R0
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill1:
// val0 := br1.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br1.peekTopBits(peekBits)
MOVD R6, R1
MOVD R10, R12
LSR R1, R12, R12
// v1 := table[val1&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v1.entry))
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// these two writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
ADD R7, R3, R15
MOVH R0, (R15)
// update the bitreader structure
MOVD R10, 80(R9)
MOVB R11, 88(R9)
// br2.fillFast32()
MOVD 128(R9), R10
MOVBU 136(R9), R11
CMP $0x20, R11
BLS skip_fill2
MOVD 120(R9), R0
SUB $0x20, R11, R11
SUB $0x04, R0, R0
MOVD 96(R9), R12
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R12, R0, R15
MOVWU (R15), R12
MOVD R11, R1
LSL R1, R12, R12
MOVD R0, 120(R9)
ORR R12, R10, R10
// exhausted += (br2.off < 4)
CMP $0x04, R0
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill2:
// val0 := br2.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br2.peekTopBits(peekBits)
MOVD R6, R1
MOVD R10, R12
LSR R1, R12, R12
// v1 := table[val1&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v1.entry))
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// these two writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
ADD R7<<1, R3, R15
MOVH R0, (R15)
// update the bitreader structure
MOVD R10, 128(R9)
MOVB R11, 136(R9)
// br3.fillFast32()
MOVD 176(R9), R10
MOVBU 184(R9), R11
CMP $0x20, R11
BLS skip_fill3
MOVD 168(R9), R0
SUB $0x20, R11, R11
SUB $0x04, R0, R0
MOVD 144(R9), R12
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R12, R0, R15
MOVWU (R15), R12
MOVD R11, R1
LSL R1, R12, R12
MOVD R0, 168(R9)
ORR R12, R10, R10
// exhausted += (br3.off < 4)
CMP $0x04, R0
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill3:
// val0 := br3.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br3.peekTopBits(peekBits)
MOVD R6, R1
MOVD R10, R12
LSR R1, R12, R12
// v1 := table[val1&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v1.entry))
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// these two writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
ADD R7<<1, R7, R1
ADD R1, R3, R15
MOVH R0, (R15)
// update the bitreader structure
MOVD R10, 176(R9)
MOVB R11, 184(R9)
ADD $0x02, R3, R3
AND $0xff, R2, R15
AND $0xff, R2, R16
TST R16, R15
BEQ main_loop
MOVD ctx+0(FP), R0
MOVD 16(R0), R16
SUB R16, R3, R3
LSL $0x02, R3, R3
MOVD R3, 40(R0)
RET
// func decompress4x_8b_main_loop_amd64(ctx *decompress4xContext)
TEXT ·decompress4x_8b_main_loop_arm64(SB), $0-8
// Preload values
MOVD ctx+0(FP), R1
MOVBU 8(R1), R6
MOVD 16(R1), R3
MOVD 48(R1), R5
MOVD 24(R1), R7
MOVD 32(R1), R8
MOVD (R1), R9
// Main loop
main_loop:
MOVD $0, R2
CMP R5, R3
CSET GE, R16
BFI $0, R16, $8, R2
// br0.fillFast32()
MOVD 32(R9), R10
MOVBU 40(R9), R11
CMP $0x20, R11
BLS skip_fill0
MOVD 24(R9), R12
SUB $0x20, R11, R11
SUB $0x04, R12, R12
MOVD (R9), R13
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R13, R12, R15
MOVWU (R15), R13
MOVD R11, R1
LSL R1, R13, R13
MOVD R12, 24(R9)
ORR R13, R10, R10
// exhausted += (br0.off < 4)
CMP $0x04, R12
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill0:
// val0 := br0.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br0.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v1 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v1.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// val2 := br0.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v2 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v2.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val3 := br0.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v3 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br0.advance(uint8(v3.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// these four writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
// out[id * dstEvery + 3] = uint8(v2.entry >> 8)
// out[id * dstEvery + 4] = uint8(v3.entry >> 8)
MOVW R0, (R3)
// update the bitreader structure
MOVD R10, 32(R9)
MOVB R11, 40(R9)
// br1.fillFast32()
MOVD 80(R9), R10
MOVBU 88(R9), R11
CMP $0x20, R11
BLS skip_fill1
MOVD 72(R9), R12
SUB $0x20, R11, R11
SUB $0x04, R12, R12
MOVD 48(R9), R13
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R13, R12, R15
MOVWU (R15), R13
MOVD R11, R1
LSL R1, R13, R13
MOVD R12, 72(R9)
ORR R13, R10, R10
// exhausted += (br1.off < 4)
CMP $0x04, R12
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill1:
// val0 := br1.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br1.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v1 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v1.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// val2 := br1.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v2 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v2.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val3 := br1.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v3 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br1.advance(uint8(v3.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// these four writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
// out[id * dstEvery + 3] = uint8(v2.entry >> 8)
// out[id * dstEvery + 4] = uint8(v3.entry >> 8)
ADD R7, R3, R15
MOVW R0, (R15)
// update the bitreader structure
MOVD R10, 80(R9)
MOVB R11, 88(R9)
// br2.fillFast32()
MOVD 128(R9), R10
MOVBU 136(R9), R11
CMP $0x20, R11
BLS skip_fill2
MOVD 120(R9), R12
SUB $0x20, R11, R11
SUB $0x04, R12, R12
MOVD 96(R9), R13
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R13, R12, R15
MOVWU (R15), R13
MOVD R11, R1
LSL R1, R13, R13
MOVD R12, 120(R9)
ORR R13, R10, R10
// exhausted += (br2.off < 4)
CMP $0x04, R12
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill2:
// val0 := br2.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br2.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v1 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v1.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// val2 := br2.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v2 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v2.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val3 := br2.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v3 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br2.advance(uint8(v3.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// these four writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
// out[id * dstEvery + 3] = uint8(v2.entry >> 8)
// out[id * dstEvery + 4] = uint8(v3.entry >> 8)
ADD R7<<1, R3, R15
MOVW R0, (R15)
// update the bitreader structure
MOVD R10, 128(R9)
MOVB R11, 136(R9)
// br3.fillFast32()
MOVD 176(R9), R10
MOVBU 184(R9), R11
CMP $0x20, R11
BLS skip_fill3
MOVD 168(R9), R12
SUB $0x20, R11, R11
SUB $0x04, R12, R12
MOVD 144(R9), R13
// b.value |= uint64(low) << (b.bitsRead & 63)
ADD R13, R12, R15
MOVWU (R15), R13
MOVD R11, R1
LSL R1, R13, R13
MOVD R12, 168(R9)
ORR R13, R10, R10
// exhausted += (br3.off < 4)
CMP $0x04, R12
CSINC HS, R2, R2, R16
BFI $0, R16, $8, R2
skip_fill3:
// val0 := br3.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v0 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v0.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val1 := br3.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v1 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v1.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// val2 := br3.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v2 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v2.entry)
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
// val3 := br3.peekTopBits(peekBits)
MOVD R10, R12
MOVD R6, R1
LSR R1, R12, R12
// v3 := table[val0&mask]
ADD R12<<1, R8, R15
MOVHU (R15), R1
// br3.advance(uint8(v3.entry)
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
LSL R1, R10, R10
ADD R1, R11, R15
BFI $0, R15, $8, R11
REVW R0, R0
// these four writes get coalesced
// out[id * dstEvery + 0] = uint8(v0.entry >> 8)
// out[id * dstEvery + 1] = uint8(v1.entry >> 8)
// out[id * dstEvery + 3] = uint8(v2.entry >> 8)
// out[id * dstEvery + 4] = uint8(v3.entry >> 8)
ADD R7<<1, R7, R1
ADD R1, R3, R15
MOVW R0, (R15)
// update the bitreader structure
MOVD R10, 176(R9)
MOVB R11, 184(R9)
ADD $0x04, R3, R3
AND $0xff, R2, R15
AND $0xff, R2, R16
TST R16, R15
BEQ main_loop
MOVD ctx+0(FP), R0
MOVD 16(R0), R16
SUB R16, R3, R3
LSL $0x02, R3, R3
MOVD R3, 40(R0)
RET
// func decompress1x_main_loop_amd64(ctx *decompress1xContext)
TEXT ·decompress1x_main_loop_arm64(SB), $0-8
MOVD ctx+0(FP), R1
MOVD 16(R1), R2
MOVD 24(R1), R3
CMP $0x04, R3
BLO error_max_decoded_size_exceeded
ADD R3, R2, R3
MOVD (R1), R5
MOVD (R5), R7
MOVD 24(R5), R8
MOVD 32(R5), R9
MOVBU 40(R5), R10
MOVD 32(R1), R5
MOVBU 8(R1), R6
JMP loop_condition
main_loop:
// Check if we have room for 4 bytes in the output buffer
ADD $4, R2, R1
CMP R3, R1
BGE error_max_decoded_size_exceeded
// Decode 4 values
CMP $0x20, R10
BLT bitReader_fillFast_1_end
SUB $0x20, R10, R10
SUB $0x04, R8, R8
ADD R8, R7, R15
MOVWU (R15), R11
MOVD R10, R1
LSL R1, R11, R11
ORR R11, R9, R9
bitReader_fillFast_1_end:
MOVD R6, R1
MOVD R9, R11
LSR R1, R11, R11
ADD R11<<1, R5, R15
MOVHU (R15), R1
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
MOVBU R1, R1
ADD R1, R10, R10
LSL R1, R9, R9
MOVD R6, R1
MOVD R9, R11
LSR R1, R11, R11
ADD R11<<1, R5, R15
MOVHU (R15), R1
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
MOVBU R1, R1
ADD R1, R10, R10
LSL R1, R9, R9
REVW R0, R0
CMP $0x20, R10
BLT bitReader_fillFast_2_end
SUB $0x20, R10, R10
SUB $0x04, R8, R8
ADD R8, R7, R15
MOVWU (R15), R11
MOVD R10, R1
LSL R1, R11, R11
ORR R11, R9, R9
bitReader_fillFast_2_end:
MOVD R6, R1
MOVD R9, R11
LSR R1, R11, R11
ADD R11<<1, R5, R15
MOVHU (R15), R1
UBFX $8, R1, $8, R16
BFI $8, R16, $8, R0
MOVBU R1, R1
ADD R1, R10, R10
LSL R1, R9, R9
MOVD R6, R1
MOVD R9, R11
LSR R1, R11, R11
ADD R11<<1, R5, R15
MOVHU (R15), R1
UBFX $8, R1, $8, R16
BFI $0, R16, $8, R0
MOVBU R1, R1
ADD R1, R10, R10
LSL R1, R9, R9
REVW R0, R0
// Store the decoded values
MOVW R0, (R2)
ADD $0x04, R2, R2
loop_condition:
CMP $0x08, R8
BGE main_loop
// Update ctx structure
MOVD ctx+0(FP), R0
MOVD 16(R0), R16
SUB R16, R2, R2
MOVD R2, 40(R0)
MOVD (R0), R0
MOVD R8, 24(R0)
MOVD R9, 32(R0)
MOVB R10, 40(R0)
RET
// Report error
error_max_decoded_size_exceeded:
MOVD ctx+0(FP), R0
MOVD $-1, R1
MOVD R1, 40(R0)
RET
// skipped decompress1x_main_loop_bmi2 (generic twin preferred on arm64)
+193
View File
@@ -0,0 +1,193 @@
//go:build (amd64 || arm64) && !appengine && !noasm && gc
// This file contains the specialisation of Decoder.Decompress4X
// and Decoder.Decompress1X that use an asm implementation of their main loops.
// The asm function stubs and any per-arch dispatch live in decompress_amd64.go
// and decompress_arm64.go.
package huff0
import (
"errors"
"fmt"
)
// fallback8BitSize is the size where using Go version is faster.
const fallback8BitSize = 800
type decompress4xContext struct {
pbr *[4]bitReaderShifted
peekBits uint8
out *byte
dstEvery int
tbl *dEntrySingle
decoded int
limit *byte
}
// Decompress4X will decompress a 4X encoded stream.
// The length of the supplied input must match the end of a block exactly.
// The *capacity* of the dst slice must match the destination size of
// the uncompressed data exactly.
func (d *Decoder) Decompress4X(dst, src []byte) ([]byte, error) {
if len(d.dt.single) == 0 {
return nil, errors.New("no table loaded")
}
if len(src) < 6+(4*1) {
return nil, errors.New("input too small")
}
use8BitTables := d.actualTableLog <= 8
if cap(dst) < fallback8BitSize && use8BitTables {
return d.decompress4X8bit(dst, src)
}
var br [4]bitReaderShifted
// Decode "jump table"
start := 6
for i := range 3 {
length := int(src[i*2]) | (int(src[i*2+1]) << 8)
if start+length >= len(src) {
return nil, errors.New("truncated input (or invalid offset)")
}
err := br[i].init(src[start : start+length])
if err != nil {
return nil, err
}
start += length
}
err := br[3].init(src[start:])
if err != nil {
return nil, err
}
// destination, offset to match first output
dstSize := cap(dst)
dst = dst[:dstSize]
out := dst
dstEvery := (dstSize + 3) / 4
const tlSize = 1 << tableLogMax
const tlMask = tlSize - 1
single := d.dt.single[:tlSize]
var decoded int
if len(out) > 4*4 && !(br[0].off < 4 || br[1].off < 4 || br[2].off < 4 || br[3].off < 4) {
ctx := decompress4xContext{
pbr: &br,
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
out: &out[0],
dstEvery: dstEvery,
tbl: &single[0],
limit: &out[dstEvery-4], // Always stop decoding when first buffer gets here to avoid writing OOB on last.
}
if use8BitTables {
decompress4x_8b_main_loop_asm(&ctx)
} else {
decompress4x_main_loop_asm(&ctx)
}
decoded = ctx.decoded
out = out[decoded/4:]
}
// Decode remaining.
remainBytes := dstEvery - (decoded / 4)
for i := range br {
offset := dstEvery * i
endsAt := min(offset+remainBytes, len(out))
br := &br[i]
bitsLeft := br.remaining()
for bitsLeft > 0 {
br.fill()
if offset >= endsAt {
return nil, errors.New("corruption detected: stream overrun 4")
}
// Read value and increment offset.
val := br.peekBitsFast(d.actualTableLog)
v := single[val&tlMask].entry
nBits := uint8(v)
br.advance(nBits)
bitsLeft -= uint(nBits)
out[offset] = uint8(v >> 8)
offset++
}
if offset != endsAt {
return nil, fmt.Errorf("corruption detected: short output block %d, end %d != %d", i, offset, endsAt)
}
decoded += offset - dstEvery*i
err = br.close()
if err != nil {
return nil, err
}
}
if dstSize != decoded {
return nil, errors.New("corruption detected: short output block")
}
return dst, nil
}
type decompress1xContext struct {
pbr *bitReaderShifted
peekBits uint8
out *byte
outCap int
tbl *dEntrySingle
decoded int
}
// Error reported by asm implementations
const error_max_decoded_size_exeeded = -1
// Decompress1X will decompress a 1X encoded stream.
// The cap of the output buffer will be the maximum decompressed size.
// The length of the supplied input must match the end of a block exactly.
func (d *Decoder) Decompress1X(dst, src []byte) ([]byte, error) {
if len(d.dt.single) == 0 {
return nil, errors.New("no table loaded")
}
var br bitReaderShifted
err := br.init(src)
if err != nil {
return dst, err
}
maxDecodedSize := cap(dst)
dst = dst[:maxDecodedSize]
const tlSize = 1 << tableLogMax
const tlMask = tlSize - 1
if maxDecodedSize >= 4 {
ctx := decompress1xContext{
pbr: &br,
out: &dst[0],
outCap: maxDecodedSize,
peekBits: uint8((64 - d.actualTableLog) & 63), // see: bitReaderShifted.peekBitsFast()
tbl: &d.dt.single[0],
}
decompress1x_main_loop_asm(&ctx)
if ctx.decoded == error_max_decoded_size_exeeded {
return nil, ErrMaxDecodedSizeExceeded
}
dst = dst[:ctx.decoded]
}
// br < 8, so uint8 is fine
bitsLeft := uint8(br.off)*8 + 64 - br.bitsRead
for bitsLeft > 0 {
br.fill()
if len(dst) >= maxDecodedSize {
br.close()
return nil, ErrMaxDecodedSizeExceeded
}
v := d.dt.single[br.peekBitsFast(d.actualTableLog)&tlMask]
nBits := uint8(v.entry)
br.advance(nBits)
bitsLeft -= nBits
dst = append(dst, uint8(v.entry>>8))
}
return dst, br.close()
}
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !amd64 || appengine || !gc || noasm
//go:build (!amd64 && !arm64) || appengine || !gc || noasm
// This file contains a generic implementation of Decoder.Decompress4X.
package huff0
+3 -6
View File
@@ -400,8 +400,9 @@ func (b *blockDec) decodeLiterals(in []byte, hist *history) (remain []byte, err
}
}
var err error
// Use our out buffer.
huff.MaxDecodedSize = litRegenSize
// Decoder.Decompress* uses cap(dst) for the size limit. Do not write
// MaxDecodedSize on hist.huffTree: with a trained dictionary that
// pointer aliases the shared dict.litEnc and concurrent DecodeAll races.
if fourStreams {
literals, err = huff.Decoder().Decompress4X(b.literalBuf[:0:litRegenSize], literals)
} else {
@@ -673,10 +674,6 @@ func (b *blockDec) executeSequences(hist *history) error {
hbytes := hist.b
if len(hbytes) > hist.windowSize {
hbytes = hbytes[len(hbytes)-hist.windowSize:]
// We do not need history anymore.
if hist.dict != nil {
hist.dict.content = nil
}
}
hist.decoders.windowSize = hist.windowSize
hist.decoders.out = b.dst[:0]
+64 -21
View File
@@ -296,40 +296,81 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
if offset > 3 {
newOffsets[offset-3]++
} else {
newOffsets[uint32(o.Offsets[offset-1])]++
// Repeat codes reference the training Offsets. Skip unset
// (zero) entries so they are not ranked as real offsets.
prev := o.Offsets[offset-1]
if prev > 0 {
newOffsets[uint32(prev)]++
}
}
}
}
// Find most used offsets.
var sortedOffsets []uint32
for k := range newOffsets {
if k == 0 {
continue
}
sortedOffsets = append(sortedOffsets, k)
}
sort.Slice(sortedOffsets, func(i, j int) bool {
a, b := sortedOffsets[i], sortedOffsets[j]
if a == b {
ca, cb := newOffsets[a], newOffsets[b]
if ca == cb {
// Prefer the longer offset
return sortedOffsets[i] > sortedOffsets[j]
return a > b
}
return newOffsets[sortedOffsets[i]] > newOffsets[sortedOffsets[j]]
return ca > cb
})
if len(sortedOffsets) > 3 {
if debug {
print("Offsets:")
for i, v := range sortedOffsets {
if i > 20 {
break
}
printf("[%d: %d],", v, newOffsets[v])
if debug {
print("Offsets:")
for i, v := range sortedOffsets {
if i > 20 {
break
}
println("")
printf("[%d: %d],", v, newOffsets[v])
}
sortedOffsets = sortedOffsets[:3]
println("")
}
for i, v := range sortedOffsets {
o.Offsets[i] = int(v)
// Dictionary recent-offsets must be three positive values within the
// history. Ranked matches may be fewer (or empty when only unset
// repeat codes were seen), so fill remaining slots with defaults.
used := make(map[int]bool, 3)
var finalOffsets [3]int
nOff := 0
for _, v := range sortedOffsets {
iv := int(v)
if iv <= 0 || iv > len(hist) || used[iv] {
continue
}
finalOffsets[nOff] = iv
used[iv] = true
nOff++
if nOff == 3 {
break
}
}
for _, def := range []int{1, 4, 8} {
if nOff == 3 {
break
}
if def <= len(hist) && !used[def] {
finalOffsets[nOff] = def
used[def] = true
nOff++
}
}
for def := 1; nOff < 3 && def <= len(hist); def++ {
if !used[def] {
finalOffsets[nOff] = def
used[def] = true
nOff++
}
}
if nOff < 3 {
return nil, fmt.Errorf("could not determine 3 valid dictionary offsets (history size %d)", len(hist))
}
o.Offsets = finalOffsets
if debug {
println("New repeat offsets", o.Offsets)
}
@@ -337,6 +378,9 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
if nUsed == 0 || seqs == 0 {
return nil, fmt.Errorf("%d blocks, %d sequences found", nUsed, seqs)
}
if litTotal == 0 {
return nil, errors.New("0 literals found")
}
if debug {
println("Sequences:", seqs, "Blocks:", nUsed, "Literals:", litTotal)
}
@@ -517,11 +561,10 @@ func BuildDict(o BuildDictOptions) ([]byte, error) {
out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[1])))
out.Write(binary.LittleEndian.AppendUint32(nil, uint32(o.Offsets[2])))
out.Write(hist)
if _, err := loadDict(out.Bytes()); err != nil {
return nil, fmt.Errorf("built dictionary failed validation: %w", err)
}
if debug {
_, err := loadDict(out.Bytes())
if err != nil {
panic(err)
}
i, err := InspectDictionary(out.Bytes())
if err != nil {
panic(err)
+2 -2
View File
@@ -2081,7 +2081,7 @@ sequenceDecs_decodeSync_amd64_match_len_ofs_ok:
MOVQ 16(SP), R13
// Check if we have enough space in s.out
LEAQ (AX)(R13*1), R14
LEAQ 16(AX)(R13*1), R14
ADDQ R10, R14
CMPQ R14, 32(SP)
JA error_not_enough_space
@@ -2601,7 +2601,7 @@ sequenceDecs_decodeSync_bmi2_match_len_ofs_ok:
MOVQ 16(SP), R13
// Check if we have enough space in s.out
LEAQ (CX)(R13*1), R14
LEAQ 16(CX)(R13*1), R14
ADDQ R9, R14
CMPQ R14, 32(SP)
JA error_not_enough_space
File diff suppressed because it is too large. Load diff
+30 -3
View File
@@ -77,6 +77,35 @@ const errorNotEnoughSpace = 5
// error reported when bits are overread.
const errorOverread = 6
// useSafeDecodeSync reports whether decodeSyncSimple must use the bounds-exact
// ("safe") copy variants for the current buffer geometry.
//
// When the output and literal buffers have compressedBlockOverAlloc (16)
// bytes of slack past their logical use, the assembly may use extended
// memory copies that read and write in 16-byte blocks, overrunning the end
// of a literal run or match by up to 15 bytes. Otherwise it must use the
// bounds-exact ("safe") copies. This mirrors the analogous, always-dynamic
// selection in executeSimple below.
//
// The unsafe copies were disabled in #644 (2022) as a mitigation for a
// crash, but that crash's root cause — an unguarded bitReader overread that
// produced out-of-range match offsets/lengths — was fixed three days later
// in #645, which also added the fuzz corpus that has guarded this path since.
// See #1168. An asan-instrumented fuzz job (see .github/workflows/go.yml)
// covers the extended-copy path, which -race and plain fuzzing cannot.
func (s *sequenceDecs) useSafeDecodeSync() bool {
if s.maxSyncLen == 0 && cap(s.out)-len(s.out) < maxCompressedBlockSizeAlloc {
return true
}
if s.maxSyncLen > 0 && cap(s.out)-len(s.out)-compressedBlockOverAlloc < int(s.maxSyncLen) {
return true
}
if cap(s.literals) < len(s.literals)+compressedBlockOverAlloc {
return true
}
return false
}
// decode sequences from the stream with the provided history but without a dictionary.
func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
if len(s.dict) > 0 {
@@ -86,9 +115,7 @@ func (s *sequenceDecs) decodeSyncSimple(hist []byte) (bool, error) {
return false, nil
}
// FIXME: Using unsafe memory copies leads to rare, random crashes
// with fuzz testing. It is therefore disabled for now.
const useSafe = true
useSafe := s.useSafeDecodeSync()
br := s.br
+1 -1
View File
@@ -415,7 +415,7 @@ github.com/intel/goresctrl/pkg/utils
# github.com/json-iterator/go v1.1.12
## explicit; go 1.12
github.com/json-iterator/go
# github.com/klauspost/compress v1.19.1
# github.com/klauspost/compress v1.19.2
## explicit; go 1.24
github.com/klauspost/compress
github.com/klauspost/compress/flate