@@ -34,34 +34,43 @@ const (
3434)
3535
3636func (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+ }
3841
3942 if typeNum != _Pointer && result .Kind () == reflect .Uintptr {
4043 result .Set (reflect .ValueOf (uintptr (offset )))
41- return d .nextValueOffset (offset , 1 ), nil
44+ return d .nextValueOffset (offset , 1 )
4245 }
4346 return d .decodeFromType (typeNum , size , newOffset , result )
4447}
4548
46- func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint ) {
49+ func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
4750 newOffset := offset + 1
51+ if offset >= uint (len (d .buffer )) {
52+ return 0 , 0 , 0 , newOffsetError ()
53+ }
4854 ctrlByte := d .buffer [offset ]
4955
5056 typeNum := dataType (ctrlByte >> 5 )
5157 if typeNum == _Extended {
58+ if newOffset >= uint (len (d .buffer )) {
59+ return 0 , 0 , 0 , newOffsetError ()
60+ }
5261 typeNum = dataType (d .buffer [newOffset ] + 7 )
5362 newOffset ++
5463 }
5564
5665 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
5968}
6069
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 ) {
6271 size := uint (ctrlByte & 0x1f )
6372 if typeNum == _Extended {
64- return size , offset
73+ return size , offset , nil
6574 }
6675
6776 var bytesToRead uint
@@ -70,6 +79,9 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
7079 }
7180
7281 newOffset := offset + bytesToRead
82+ if newOffset > uint (len (d .buffer )) {
83+ return 0 , 0 , newOffsetError ()
84+ }
7385 sizeBytes := d .buffer [offset :newOffset ]
7486
7587 switch {
@@ -80,15 +92,29 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
8092 case size > 30 :
8193 size = uint (uintFromBytes (0 , sizeBytes )) + 65821
8294 }
83- return size , newOffset
95+ return size , newOffset , nil
8496}
8597
8698func (d * decoder ) decodeFromType (dtype dataType , size uint , offset uint , result reflect.Value ) (uint , error ) {
8799 result = d .indirect (result )
88100
101+ // For these types, size has a special meaning
89102 switch dtype {
90103 case _Bool :
91104 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 {
92118 case _Bytes :
93119 return d .unmarshalBytes (size , offset , result )
94120 case _Float32 :
@@ -97,12 +123,6 @@ func (d *decoder) decodeFromType(dtype dataType, size uint, offset uint, result
97123 return d .unmarshalFloat64 (size , offset , result )
98124 case _Int32 :
99125 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 )
106126 case _String :
107127 return d .unmarshalString (size , offset , result )
108128 case _Uint16 :
@@ -544,7 +564,10 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
544564 // optimization: https://github.com/golang/go/issues/3512
545565 j , ok := fields .namedFields [string (key )]
546566 if ! ok {
547- offset = d .nextValueOffset (offset , 1 )
567+ offset , err = d .nextValueOffset (offset , 1 )
568+ if err != nil {
569+ return 0 , err
570+ }
548571 continue
549572 }
550573
@@ -584,7 +607,10 @@ func uintFromBytes(prefix uint64, uintBytes []byte) uint64 {
584607// copying the bytes when decoding a struct. Previously, we achieved this by
585608// using unsafe.
586609func (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+ }
588614 if typeNum == _Pointer {
589615 pointer , ptrOffset := d .decodePointer (size , dataOffset )
590616 key , _ , err := d .decodeKey (pointer )
@@ -594,17 +620,23 @@ func (d *decoder) decodeKey(offset uint) ([]byte, uint, error) {
594620 return nil , 0 , newInvalidDatabaseError ("unexpected type when decoding string: %v" , typeNum )
595621 }
596622 newOffset := dataOffset + size
623+ if newOffset > uint (len (d .buffer )) {
624+ return nil , 0 , newOffsetError ()
625+ }
597626 return d .buffer [dataOffset :newOffset ], newOffset , nil
598627}
599628
600629// This function is used to skip ahead to the next value without decoding
601630// the one at the offset passed in. The size bits have different meanings for
602631// different data types
603- func (d * decoder ) nextValueOffset (offset uint , numberToSkip uint ) uint {
632+ func (d * decoder ) nextValueOffset (offset uint , numberToSkip uint ) ( uint , error ) {
604633 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
606639 }
607- typeNum , size , offset := d .decodeCtrlData (offset )
608640 switch typeNum {
609641 case _Pointer :
610642 _ , offset = d .decodePointer (size , offset )
0 commit comments