...
1
2
3
4
5 package snapref
6
7
8
9
10
11
12 func decode(dst, src []byte) int {
13 var d, s, offset, length int
14 for s < len(src) {
15 switch src[s] & 0x03 {
16 case tagLiteral:
17 x := uint32(src[s] >> 2)
18 switch {
19 case x < 60:
20 s++
21 case x == 60:
22 s += 2
23 if uint(s) > uint(len(src)) {
24 return decodeErrCodeCorrupt
25 }
26 x = uint32(src[s-1])
27 case x == 61:
28 s += 3
29 if uint(s) > uint(len(src)) {
30 return decodeErrCodeCorrupt
31 }
32 x = uint32(src[s-2]) | uint32(src[s-1])<<8
33 case x == 62:
34 s += 4
35 if uint(s) > uint(len(src)) {
36 return decodeErrCodeCorrupt
37 }
38 x = uint32(src[s-3]) | uint32(src[s-2])<<8 | uint32(src[s-1])<<16
39 case x == 63:
40 s += 5
41 if uint(s) > uint(len(src)) {
42 return decodeErrCodeCorrupt
43 }
44 x = uint32(src[s-4]) | uint32(src[s-3])<<8 | uint32(src[s-2])<<16 | uint32(src[s-1])<<24
45 }
46 length = int(x) + 1
47 if length <= 0 {
48 return decodeErrCodeUnsupportedLiteralLength
49 }
50 if length > len(dst)-d || length > len(src)-s {
51 return decodeErrCodeCorrupt
52 }
53 copy(dst[d:], src[s:s+length])
54 d += length
55 s += length
56 continue
57
58 case tagCopy1:
59 s += 2
60 if uint(s) > uint(len(src)) {
61 return decodeErrCodeCorrupt
62 }
63 length = 4 + int(src[s-2])>>2&0x7
64 offset = int(uint32(src[s-2])&0xe0<<3 | uint32(src[s-1]))
65
66 case tagCopy2:
67 s += 3
68 if uint(s) > uint(len(src)) {
69 return decodeErrCodeCorrupt
70 }
71 length = 1 + int(src[s-3])>>2
72 offset = int(uint32(src[s-2]) | uint32(src[s-1])<<8)
73
74 case tagCopy4:
75 s += 5
76 if uint(s) > uint(len(src)) {
77 return decodeErrCodeCorrupt
78 }
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)
81 }
82
83 if offset <= 0 || d < offset || length > len(dst)-d {
84 return decodeErrCodeCorrupt
85 }
86
87
88 if offset >= length {
89 copy(dst[d:d+length], dst[d-offset:])
90 d += length
91 continue
92 }
93
94
95
96
97
98
99
100
101 a := dst[d : d+length]
102 b := dst[d-offset:]
103 b = b[:len(a)]
104 for i := range a {
105 a[i] = b[i]
106 }
107 d += length
108 }
109 if d != len(dst) {
110 return decodeErrCodeCorrupt
111 }
112 return 0
113 }
114
View as plain text