1
// Copyright 2016 The Snappy-Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
7
// decode writes the decoding of src to dst. It assumes that the varint-encoded
8
// length of the decompressed bytes has already been read, and that len(dst)
11
// It returns 0 on success or a decodeErrCodeXxx error code on failure.
12
func decode(dst, src []byte) int {
13
var d, s, offset, length int
15
switch src[s] & 0x03 {
17
x := uint32(src[s] >> 2)
23
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
24
return decodeErrCodeCorrupt
29
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
30
return decodeErrCodeCorrupt
32
x = uint32(src[s-2]) | uint32(src[s-1])<<8
35
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
36
return decodeErrCodeCorrupt
38
x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
41
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
42
return decodeErrCodeCorrupt
44
x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
48
return decodeErrCodeUnsupportedLiteralLength
50
if length > len(dst)-d || length > len(src)-s {
51
return decodeErrCodeCorrupt
53
copy(dst[d:], src[s:s+length])
60
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
61
return decodeErrCodeCorrupt
63
length = 4 + int(src[s-2])>>2&0x7
64
offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1]))
68
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
69
return decodeErrCodeCorrupt
71
length = 1 + int(src[s-3])>>2
72
offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8)
76
if uint(s) > uint(len(src)) { // The uint conversions catch overflow from the previous line.
77
return decodeErrCodeCorrupt
79
length = 1 + int(src[s-5])>>2
80
offset = int(uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24)
83
if offset <= 0 || d < offset || length > len(dst)-d {
84
return decodeErrCodeCorrupt
86
// Copy from an earlier sub-slice of dst to a later sub-slice.
87
// If no overlap, use the built-in copy:
89
copy(dst[d:d+length], dst[d-offset:])
94
// Unlike the built-in copy function, this byte-by-byte copy always runs
95
// forwards, even if the slices overlap. Conceptually, this is:
97
// d += forwardCopy(dst[d:d+length], dst[d-offset:])
99
// We align the slices into a and b and show the compiler they are the same size.
100
// This allows the loop to run without bounds checks.
101
a := dst[d : d+length]
110
return decodeErrCodeCorrupt