12a1f914f4
* update github.com/alecthomas/chroma v0.8.0 -> v0.8.1 * github.com/blevesearch/bleve v1.0.10 -> v1.0.12 * editorconfig-core-go v2.1.1 -> v2.3.7 * github.com/gliderlabs/ssh v0.2.2 -> v0.3.1 * migrate editorconfig.ParseBytes to Parse * github.com/shurcooL/vfsgen to 0d455de96546 * github.com/go-git/go-git/v5 v5.1.0 -> v5.2.0 * github.com/google/uuid v1.1.1 -> v1.1.2 * github.com/huandu/xstrings v1.3.0 -> v1.3.2 * github.com/klauspost/compress v1.10.11 -> v1.11.1 * github.com/markbates/goth v1.61.2 -> v1.65.0 * github.com/mattn/go-sqlite3 v1.14.0 -> v1.14.4 * github.com/mholt/archiver v3.3.0 -> v3.3.2 * github.com/microcosm-cc/bluemonday 4f7140c49acb -> v1.0.4 * github.com/minio/minio-go v7.0.4 -> v7.0.5 * github.com/olivere/elastic v7.0.9 -> v7.0.20 * github.com/urfave/cli v1.20.0 -> v1.22.4 * github.com/prometheus/client_golang v1.1.0 -> v1.8.0 * github.com/xanzy/go-gitlab v0.37.0 -> v0.38.1 * mvdan.cc/xurls v2.1.0 -> v2.2.0 Co-authored-by: Lauris BH <lauris@nix.lv>
99 lines
2.1 KiB
Go
99 lines
2.1 KiB
Go
// +build !amd64 appengine !gc noasm
|
|
|
|
package lz4
|
|
|
|
func decodeBlock(dst, src []byte) (ret int) {
|
|
const hasError = -2
|
|
defer func() {
|
|
if recover() != nil {
|
|
ret = hasError
|
|
}
|
|
}()
|
|
|
|
var si, di int
|
|
for {
|
|
// Literals and match lengths (token).
|
|
b := int(src[si])
|
|
si++
|
|
|
|
// Literals.
|
|
if lLen := b >> 4; lLen > 0 {
|
|
switch {
|
|
case lLen < 0xF && si+16 < len(src):
|
|
// Shortcut 1
|
|
// if we have enough room in src and dst, and the literals length
|
|
// is small enough (0..14) then copy all 16 bytes, even if not all
|
|
// are part of the literals.
|
|
copy(dst[di:], src[si:si+16])
|
|
si += lLen
|
|
di += lLen
|
|
if mLen := b & 0xF; mLen < 0xF {
|
|
// Shortcut 2
|
|
// if the match length (4..18) fits within the literals, then copy
|
|
// all 18 bytes, even if not all are part of the literals.
|
|
mLen += 4
|
|
if offset := int(src[si]) | int(src[si+1])<<8; mLen <= offset {
|
|
i := di - offset
|
|
end := i + 18
|
|
if end > len(dst) {
|
|
// The remaining buffer may not hold 18 bytes.
|
|
// See https://github.com/pierrec/lz4/issues/51.
|
|
end = len(dst)
|
|
}
|
|
copy(dst[di:], dst[i:end])
|
|
si += 2
|
|
di += mLen
|
|
continue
|
|
}
|
|
}
|
|
case lLen == 0xF:
|
|
for src[si] == 0xFF {
|
|
lLen += 0xFF
|
|
si++
|
|
}
|
|
lLen += int(src[si])
|
|
si++
|
|
fallthrough
|
|
default:
|
|
copy(dst[di:di+lLen], src[si:si+lLen])
|
|
si += lLen
|
|
di += lLen
|
|
}
|
|
}
|
|
if si >= len(src) {
|
|
return di
|
|
}
|
|
|
|
offset := int(src[si]) | int(src[si+1])<<8
|
|
if offset == 0 {
|
|
return hasError
|
|
}
|
|
si += 2
|
|
|
|
// Match.
|
|
mLen := b & 0xF
|
|
if mLen == 0xF {
|
|
for src[si] == 0xFF {
|
|
mLen += 0xFF
|
|
si++
|
|
}
|
|
mLen += int(src[si])
|
|
si++
|
|
}
|
|
mLen += minMatch
|
|
|
|
// Copy the match.
|
|
expanded := dst[di-offset:]
|
|
if mLen > offset {
|
|
// Efficiently copy the match dst[di-offset:di] into the dst slice.
|
|
bytesToCopy := offset * (mLen / offset)
|
|
for n := offset; n <= bytesToCopy+offset; n *= 2 {
|
|
copy(expanded[n:], expanded[:n])
|
|
}
|
|
di += bytesToCopy
|
|
mLen -= bytesToCopy
|
|
}
|
|
di += copy(dst[di:di+mLen], expanded[:mLen])
|
|
}
|
|
}
|