@@ -33,7 +33,15 @@ const (
3333 _Float32
3434)
3535
36- func (d * decoder ) decode (offset uint , result reflect.Value ) (uint , error ) {
36+ const (
37+ // This is the value used in libmaxminddb
38+ maximumDataStructureDepth = 512
39+ )
40+
41+ func (d * decoder ) decode (offset uint , result reflect.Value , depth int ) (uint , error ) {
42+ if depth > maximumDataStructureDepth {
43+ return 0 , newInvalidDatabaseError ("exceeded maximum data structure depth; database is likely corrupt" )
44+ }
3745 typeNum , size , newOffset , err := d .decodeCtrlData (offset )
3846 if err != nil {
3947 return 0 , err
@@ -43,7 +51,7 @@ func (d *decoder) decode(offset uint, result reflect.Value) (uint, error) {
4351 result .Set (reflect .ValueOf (uintptr (offset )))
4452 return d .nextValueOffset (offset , 1 )
4553 }
46- return d .decodeFromType (typeNum , size , newOffset , result )
54+ return d .decodeFromType (typeNum , size , newOffset , result , depth + 1 )
4755}
4856
4957func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
@@ -95,19 +103,25 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
95103 return size , newOffset , nil
96104}
97105
98- func (d * decoder ) decodeFromType (dtype dataType , size uint , offset uint , result reflect.Value ) (uint , error ) {
106+ func (d * decoder ) decodeFromType (
107+ dtype dataType ,
108+ size uint ,
109+ offset uint ,
110+ result reflect.Value ,
111+ depth int ,
112+ ) (uint , error ) {
99113 result = d .indirect (result )
100114
101115 // For these types, size has a special meaning
102116 switch dtype {
103117 case _Bool :
104118 return d .unmarshalBool (size , offset , result )
105119 case _Map :
106- return d .unmarshalMap (size , offset , result )
120+ return d .unmarshalMap (size , offset , result , depth )
107121 case _Pointer :
108- return d .unmarshalPointer (size , offset , result )
122+ return d .unmarshalPointer (size , offset , result , depth )
109123 case _Slice :
110- return d .unmarshalSlice (size , offset , result )
124+ return d .unmarshalSlice (size , offset , result , depth )
111125 }
112126
113127 // For the remaining types, size is the byte size
@@ -283,41 +297,51 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
283297 return newOffset , newUnmarshalTypeError (value , result .Type ())
284298}
285299
286- func (d * decoder ) unmarshalMap (size uint , offset uint , result reflect.Value ) (uint , error ) {
300+ func (d * decoder ) unmarshalMap (
301+ size uint ,
302+ offset uint ,
303+ result reflect.Value ,
304+ depth int ,
305+ ) (uint , error ) {
287306 result = d .indirect (result )
288307 switch result .Kind () {
289308 default :
290309 return 0 , newUnmarshalTypeError ("map" , result .Type ())
291310 case reflect .Struct :
292- return d .decodeStruct (size , offset , result )
311+ return d .decodeStruct (size , offset , result , depth )
293312 case reflect .Map :
294- return d .decodeMap (size , offset , result )
313+ return d .decodeMap (size , offset , result , depth )
295314 case reflect .Interface :
296315 if result .NumMethod () == 0 {
297316 rv := reflect .ValueOf (make (map [string ]interface {}, size ))
298- newOffset , err := d .decodeMap (size , offset , rv )
317+ newOffset , err := d .decodeMap (size , offset , rv , depth )
299318 result .Set (rv )
300319 return newOffset , err
301320 }
302321 return 0 , newUnmarshalTypeError ("map" , result .Type ())
303322 }
304323}
305324
306- func (d * decoder ) unmarshalPointer (size uint , offset uint , result reflect.Value ) (uint , error ) {
325+ func (d * decoder ) unmarshalPointer (size uint , offset uint , result reflect.Value , depth int ) (uint , error ) {
307326 pointer , newOffset := d .decodePointer (size , offset )
308- _ , err := d .decode (pointer , result )
327+ _ , err := d .decode (pointer , result , depth )
309328 return newOffset , err
310329}
311330
312- func (d * decoder ) unmarshalSlice (size uint , offset uint , result reflect.Value ) (uint , error ) {
331+ func (d * decoder ) unmarshalSlice (
332+ size uint ,
333+ offset uint ,
334+ result reflect.Value ,
335+ depth int ,
336+ ) (uint , error ) {
313337 switch result .Kind () {
314338 case reflect .Slice :
315- return d .decodeSlice (size , offset , result )
339+ return d .decodeSlice (size , offset , result , depth )
316340 case reflect .Interface :
317341 if result .NumMethod () == 0 {
318342 a := []interface {}{}
319343 rv := reflect .ValueOf (& a ).Elem ()
320- newOffset , err := d .decodeSlice (size , offset , rv )
344+ newOffset , err := d .decodeSlice (size , offset , rv , depth )
321345 result .Set (rv )
322346 return newOffset , err
323347 }
@@ -430,7 +454,12 @@ func (d *decoder) decodeInt(size uint, offset uint) (int, uint, error) {
430454 return int (val ), newOffset , nil
431455}
432456
433- func (d * decoder ) decodeMap (size uint , offset uint , result reflect.Value ) (uint , error ) {
457+ func (d * decoder ) decodeMap (
458+ size uint ,
459+ offset uint ,
460+ result reflect.Value ,
461+ depth int ,
462+ ) (uint , error ) {
434463 if result .IsNil () {
435464 result .Set (reflect .MakeMap (result .Type ()))
436465 }
@@ -445,7 +474,7 @@ func (d *decoder) decodeMap(size uint, offset uint, result reflect.Value) (uint,
445474 }
446475
447476 value := reflect .New (result .Type ().Elem ())
448- offset , err = d .decode (offset , value )
477+ offset , err = d .decode (offset , value , depth )
449478 if err != nil {
450479 return 0 , err
451480 }
@@ -483,11 +512,16 @@ func (d *decoder) decodePointer(size uint, offset uint) (uint, uint) {
483512 return pointer , newOffset
484513}
485514
486- func (d * decoder ) decodeSlice (size uint , offset uint , result reflect.Value ) (uint , error ) {
515+ func (d * decoder ) decodeSlice (
516+ size uint ,
517+ offset uint ,
518+ result reflect.Value ,
519+ depth int ,
520+ ) (uint , error ) {
487521 result .Set (reflect .MakeSlice (result .Type (), int (size ), int (size )))
488522 for i := 0 ; i < int (size ); i ++ {
489523 var err error
490- offset , err = d .decode (offset , result .Index (i ))
524+ offset , err = d .decode (offset , result .Index (i ), depth )
491525 if err != nil {
492526 return 0 , err
493527 }
@@ -510,7 +544,12 @@ var (
510544 fieldMapMu sync.RWMutex
511545)
512546
513- func (d * decoder ) decodeStruct (size uint , offset uint , result reflect.Value ) (uint , error ) {
547+ func (d * decoder ) decodeStruct (
548+ size uint ,
549+ offset uint ,
550+ result reflect.Value ,
551+ depth int ,
552+ ) (uint , error ) {
514553 resultType := result .Type ()
515554
516555 fieldMapMu .RLock ()
@@ -544,7 +583,7 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
544583
545584 // This fills in embedded structs
546585 for i := range fields .anonymousFields {
547- _ , err := d .unmarshalMap (size , offset , result .Field (i ))
586+ _ , err := d .unmarshalMap (size , offset , result .Field (i ), depth )
548587 if err != nil {
549588 return 0 , err
550589 }
@@ -571,7 +610,7 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
571610 continue
572611 }
573612
574- offset , err = d .decode (offset , result .Field (j ))
613+ offset , err = d .decode (offset , result .Field (j ), depth )
575614 if err != nil {
576615 return 0 , err
577616 }
0 commit comments