Skip to content

Commit 266071c

Browse files
committed
Set maximum data structure depth to 512
1 parent e0a01fd commit 266071c

File tree

4 files changed

+66
-27
lines changed

4 files changed

+66
-27
lines changed

decoder.go

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4957
func (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
}

decoder_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func validateDecoding(t *testing.T, tests map[string]interface{}) {
204204
d := decoder{inputBytes}
205205

206206
var result interface{}
207-
_, err := d.decode(0, reflect.ValueOf(&result))
207+
_, err := d.decode(0, reflect.ValueOf(&result), 0)
208208
assert.Nil(t, err)
209209

210210
if !reflect.DeepEqual(result, expected) {
@@ -230,7 +230,7 @@ func TestPointers(t *testing.T) {
230230

231231
for offset, expectedValue := range expected {
232232
var actual map[string]string
233-
_, err := d.decode(offset, reflect.ValueOf(&actual))
233+
_, err := d.decode(offset, reflect.ValueOf(&actual), 0)
234234
assert.Nil(t, err)
235235
if !reflect.DeepEqual(actual, expectedValue) {
236236
t.Errorf("Decode for pointer at %d failed", offset)

reader.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func FromBytes(buffer []byte) (*Reader, error) {
5959
var metadata Metadata
6060

6161
rvMetdata := reflect.ValueOf(&metadata)
62-
_, err := metadataDecoder.decode(0, rvMetdata)
62+
_, err := metadataDecoder.decode(0, rvMetdata, 0)
6363
if err != nil {
6464
return nil, err
6565
}
@@ -149,7 +149,7 @@ func (r *Reader) Decode(offset uintptr, result interface{}) error {
149149
return errors.New("result param must be a pointer")
150150
}
151151

152-
_, err := r.decoder.decode(uint(offset), reflect.ValueOf(result))
152+
_, err := r.decoder.decode(uint(offset), reflect.ValueOf(result), 0)
153153
return err
154154
}
155155

verifier.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func (v *verifier) verifyDataSection(offsets map[uint]bool) error {
134134
for offset < bufferLen {
135135
var data interface{}
136136
rv := reflect.ValueOf(&data)
137-
newOffset, err := decoder.decode(offset, rv)
137+
newOffset, err := decoder.decode(offset, rv, 0)
138138
if err != nil {
139139
return newInvalidDatabaseError("received decoding error (%v) at offset of %v", err, offset)
140140
}

0 commit comments

Comments
 (0)