@@ -34,34 +34,43 @@ const (
34
34
)
35
35
36
36
func (d * decoder ) decode (offset uint , result reflect.Value ) (uint , error ) {
37
- typeNum , size , newOffset := d .decodeCtrlData (offset )
37
+ typeNum , size , newOffset , err := d .decodeCtrlData (offset )
38
+ if err != nil {
39
+ return 0 , err
40
+ }
38
41
39
42
if typeNum != _Pointer && result .Kind () == reflect .Uintptr {
40
43
result .Set (reflect .ValueOf (uintptr (offset )))
41
- return d .nextValueOffset (offset , 1 ), nil
44
+ return d .nextValueOffset (offset , 1 )
42
45
}
43
46
return d .decodeFromType (typeNum , size , newOffset , result )
44
47
}
45
48
46
- func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint ) {
49
+ func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
47
50
newOffset := offset + 1
51
+ if offset >= uint (len (d .buffer )) {
52
+ return 0 , 0 , 0 , newOffsetError ()
53
+ }
48
54
ctrlByte := d .buffer [offset ]
49
55
50
56
typeNum := dataType (ctrlByte >> 5 )
51
57
if typeNum == _Extended {
58
+ if newOffset >= uint (len (d .buffer )) {
59
+ return 0 , 0 , 0 , newOffsetError ()
60
+ }
52
61
typeNum = dataType (d .buffer [newOffset ] + 7 )
53
62
newOffset ++
54
63
}
55
64
56
65
var size uint
57
- size , newOffset = d .sizeFromCtrlByte (ctrlByte , newOffset , typeNum )
58
- return typeNum , size , newOffset
66
+ size , newOffset , err : = d .sizeFromCtrlByte (ctrlByte , newOffset , typeNum )
67
+ return typeNum , size , newOffset , err
59
68
}
60
69
61
- func (d * decoder ) sizeFromCtrlByte (ctrlByte byte , offset uint , typeNum dataType ) (uint , uint ) {
70
+ func (d * decoder ) sizeFromCtrlByte (ctrlByte byte , offset uint , typeNum dataType ) (uint , uint , error ) {
62
71
size := uint (ctrlByte & 0x1f )
63
72
if typeNum == _Extended {
64
- return size , offset
73
+ return size , offset , nil
65
74
}
66
75
67
76
var bytesToRead uint
@@ -70,6 +79,9 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
70
79
}
71
80
72
81
newOffset := offset + bytesToRead
82
+ if newOffset > uint (len (d .buffer )) {
83
+ return 0 , 0 , newOffsetError ()
84
+ }
73
85
sizeBytes := d .buffer [offset :newOffset ]
74
86
75
87
switch {
@@ -80,15 +92,29 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
80
92
case size > 30 :
81
93
size = uint (uintFromBytes (0 , sizeBytes )) + 65821
82
94
}
83
- return size , newOffset
95
+ return size , newOffset , nil
84
96
}
85
97
86
98
func (d * decoder ) decodeFromType (dtype dataType , size uint , offset uint , result reflect.Value ) (uint , error ) {
87
99
result = d .indirect (result )
88
100
101
+ // For these types, size has a special meaning
89
102
switch dtype {
90
103
case _Bool :
91
104
return d .unmarshalBool (size , offset , result )
105
+ case _Map :
106
+ return d .unmarshalMap (size , offset , result )
107
+ case _Pointer :
108
+ return d .unmarshalPointer (size , offset , result )
109
+ case _Slice :
110
+ return d .unmarshalSlice (size , offset , result )
111
+ }
112
+
113
+ // For the remaining types, size is the byte size
114
+ if offset + size > uint (len (d .buffer )) {
115
+ return 0 , newOffsetError ()
116
+ }
117
+ switch dtype {
92
118
case _Bytes :
93
119
return d .unmarshalBytes (size , offset , result )
94
120
case _Float32 :
@@ -97,12 +123,6 @@ func (d *decoder) decodeFromType(dtype dataType, size uint, offset uint, result
97
123
return d .unmarshalFloat64 (size , offset , result )
98
124
case _Int32 :
99
125
return d .unmarshalInt32 (size , offset , result )
100
- case _Map :
101
- return d .unmarshalMap (size , offset , result )
102
- case _Pointer :
103
- return d .unmarshalPointer (size , offset , result )
104
- case _Slice :
105
- return d .unmarshalSlice (size , offset , result )
106
126
case _String :
107
127
return d .unmarshalString (size , offset , result )
108
128
case _Uint16 :
@@ -544,7 +564,10 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
544
564
// optimization: https://github.com/golang/go/issues/3512
545
565
j , ok := fields .namedFields [string (key )]
546
566
if ! ok {
547
- offset = d .nextValueOffset (offset , 1 )
567
+ offset , err = d .nextValueOffset (offset , 1 )
568
+ if err != nil {
569
+ return 0 , err
570
+ }
548
571
continue
549
572
}
550
573
@@ -584,7 +607,10 @@ func uintFromBytes(prefix uint64, uintBytes []byte) uint64 {
584
607
// copying the bytes when decoding a struct. Previously, we achieved this by
585
608
// using unsafe.
586
609
func (d * decoder ) decodeKey (offset uint ) ([]byte , uint , error ) {
587
- typeNum , size , dataOffset := d .decodeCtrlData (offset )
610
+ typeNum , size , dataOffset , err := d .decodeCtrlData (offset )
611
+ if err != nil {
612
+ return nil , 0 , err
613
+ }
588
614
if typeNum == _Pointer {
589
615
pointer , ptrOffset := d .decodePointer (size , dataOffset )
590
616
key , _ , err := d .decodeKey (pointer )
@@ -594,17 +620,23 @@ func (d *decoder) decodeKey(offset uint) ([]byte, uint, error) {
594
620
return nil , 0 , newInvalidDatabaseError ("unexpected type when decoding string: %v" , typeNum )
595
621
}
596
622
newOffset := dataOffset + size
623
+ if newOffset > uint (len (d .buffer )) {
624
+ return nil , 0 , newOffsetError ()
625
+ }
597
626
return d .buffer [dataOffset :newOffset ], newOffset , nil
598
627
}
599
628
600
629
// This function is used to skip ahead to the next value without decoding
601
630
// the one at the offset passed in. The size bits have different meanings for
602
631
// different data types
603
- func (d * decoder ) nextValueOffset (offset uint , numberToSkip uint ) uint {
632
+ func (d * decoder ) nextValueOffset (offset uint , numberToSkip uint ) ( uint , error ) {
604
633
if numberToSkip == 0 {
605
- return offset
634
+ return offset , nil
635
+ }
636
+ typeNum , size , offset , err := d .decodeCtrlData (offset )
637
+ if err != nil {
638
+ return 0 , err
606
639
}
607
- typeNum , size , offset := d .decodeCtrlData (offset )
608
640
switch typeNum {
609
641
case _Pointer :
610
642
_ , offset = d .decodePointer (size , offset )
0 commit comments