@@ -33,7 +33,15 @@ const (
33
33
_Float32
34
34
)
35
35
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
+ }
37
45
typeNum , size , newOffset , err := d .decodeCtrlData (offset )
38
46
if err != nil {
39
47
return 0 , err
@@ -43,7 +51,7 @@ func (d *decoder) decode(offset uint, result reflect.Value) (uint, error) {
43
51
result .Set (reflect .ValueOf (uintptr (offset )))
44
52
return d .nextValueOffset (offset , 1 )
45
53
}
46
- return d .decodeFromType (typeNum , size , newOffset , result )
54
+ return d .decodeFromType (typeNum , size , newOffset , result , depth + 1 )
47
55
}
48
56
49
57
func (d * decoder ) decodeCtrlData (offset uint ) (dataType , uint , uint , error ) {
@@ -95,19 +103,25 @@ func (d *decoder) sizeFromCtrlByte(ctrlByte byte, offset uint, typeNum dataType)
95
103
return size , newOffset , nil
96
104
}
97
105
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 ) {
99
113
result = d .indirect (result )
100
114
101
115
// For these types, size has a special meaning
102
116
switch dtype {
103
117
case _Bool :
104
118
return d .unmarshalBool (size , offset , result )
105
119
case _Map :
106
- return d .unmarshalMap (size , offset , result )
120
+ return d .unmarshalMap (size , offset , result , depth )
107
121
case _Pointer :
108
- return d .unmarshalPointer (size , offset , result )
122
+ return d .unmarshalPointer (size , offset , result , depth )
109
123
case _Slice :
110
- return d .unmarshalSlice (size , offset , result )
124
+ return d .unmarshalSlice (size , offset , result , depth )
111
125
}
112
126
113
127
// For the remaining types, size is the byte size
@@ -283,41 +297,51 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
283
297
return newOffset , newUnmarshalTypeError (value , result .Type ())
284
298
}
285
299
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 ) {
287
306
result = d .indirect (result )
288
307
switch result .Kind () {
289
308
default :
290
309
return 0 , newUnmarshalTypeError ("map" , result .Type ())
291
310
case reflect .Struct :
292
- return d .decodeStruct (size , offset , result )
311
+ return d .decodeStruct (size , offset , result , depth )
293
312
case reflect .Map :
294
- return d .decodeMap (size , offset , result )
313
+ return d .decodeMap (size , offset , result , depth )
295
314
case reflect .Interface :
296
315
if result .NumMethod () == 0 {
297
316
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 )
299
318
result .Set (rv )
300
319
return newOffset , err
301
320
}
302
321
return 0 , newUnmarshalTypeError ("map" , result .Type ())
303
322
}
304
323
}
305
324
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 ) {
307
326
pointer , newOffset := d .decodePointer (size , offset )
308
- _ , err := d .decode (pointer , result )
327
+ _ , err := d .decode (pointer , result , depth )
309
328
return newOffset , err
310
329
}
311
330
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 ) {
313
337
switch result .Kind () {
314
338
case reflect .Slice :
315
- return d .decodeSlice (size , offset , result )
339
+ return d .decodeSlice (size , offset , result , depth )
316
340
case reflect .Interface :
317
341
if result .NumMethod () == 0 {
318
342
a := []interface {}{}
319
343
rv := reflect .ValueOf (& a ).Elem ()
320
- newOffset , err := d .decodeSlice (size , offset , rv )
344
+ newOffset , err := d .decodeSlice (size , offset , rv , depth )
321
345
result .Set (rv )
322
346
return newOffset , err
323
347
}
@@ -430,7 +454,12 @@ func (d *decoder) decodeInt(size uint, offset uint) (int, uint, error) {
430
454
return int (val ), newOffset , nil
431
455
}
432
456
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 ) {
434
463
if result .IsNil () {
435
464
result .Set (reflect .MakeMap (result .Type ()))
436
465
}
@@ -445,7 +474,7 @@ func (d *decoder) decodeMap(size uint, offset uint, result reflect.Value) (uint,
445
474
}
446
475
447
476
value := reflect .New (result .Type ().Elem ())
448
- offset , err = d .decode (offset , value )
477
+ offset , err = d .decode (offset , value , depth )
449
478
if err != nil {
450
479
return 0 , err
451
480
}
@@ -483,11 +512,16 @@ func (d *decoder) decodePointer(size uint, offset uint) (uint, uint) {
483
512
return pointer , newOffset
484
513
}
485
514
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 ) {
487
521
result .Set (reflect .MakeSlice (result .Type (), int (size ), int (size )))
488
522
for i := 0 ; i < int (size ); i ++ {
489
523
var err error
490
- offset , err = d .decode (offset , result .Index (i ))
524
+ offset , err = d .decode (offset , result .Index (i ), depth )
491
525
if err != nil {
492
526
return 0 , err
493
527
}
@@ -510,7 +544,12 @@ var (
510
544
fieldMapMu sync.RWMutex
511
545
)
512
546
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 ) {
514
553
resultType := result .Type ()
515
554
516
555
fieldMapMu .RLock ()
@@ -544,7 +583,7 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
544
583
545
584
// This fills in embedded structs
546
585
for i := range fields .anonymousFields {
547
- _ , err := d .unmarshalMap (size , offset , result .Field (i ))
586
+ _ , err := d .unmarshalMap (size , offset , result .Field (i ), depth )
548
587
if err != nil {
549
588
return 0 , err
550
589
}
@@ -571,7 +610,7 @@ func (d *decoder) decodeStruct(size uint, offset uint, result reflect.Value) (ui
571
610
continue
572
611
}
573
612
574
- offset , err = d .decode (offset , result .Field (j ))
613
+ offset , err = d .decode (offset , result .Field (j ), depth )
575
614
if err != nil {
576
615
return 0 , err
577
616
}
0 commit comments