Skip to content

Commit be5a06d

Browse files
authored
Merge pull request #180 from oschwald/greg/fixes
Add more defensive bounds and input checks
2 parents 31c2c6c + d2d1cc3 commit be5a06d

File tree

6 files changed

+263
-33
lines changed

6 files changed

+263
-33
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changes
22

3+
## 2.0.0-beta.9
4+
5+
- **SECURITY**: Fixed integer overflow vulnerability in search tree size
6+
calculation that could potentially allow malformed databases to trigger
7+
security issues.
8+
- **SECURITY**: Enhanced bounds checking in tree traversal functions to return
9+
proper errors instead of silent failures when encountering malformed
10+
databases.
11+
- Added validation for invalid prefixes in `NetworksWithin` to prevent
12+
unexpected behavior with malformed input.
13+
314
## 2.0.0-beta.8 - 2025-07-15
415

516
- Fixed "no next offset available" error that occurred when using custom

internal/decoder/data_decoder.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ func (d *DataDecoder) decodePointer(
246246
pointerValueOffset = 526336
247247
case 4:
248248
pointerValueOffset = 0
249+
default:
250+
return 0, 0, mmdberrors.NewInvalidDatabaseError("invalid pointer size: %d", pointerSize)
249251
}
250252

251253
pointer := unpacked + pointerValueOffset
@@ -477,6 +479,8 @@ func (d *DataDecoder) sizeFromCtrlByte(
477479
size = 285 + uintFromBytes(0, sizeBytes)
478480
case size > 30:
479481
size = uintFromBytes(0, sizeBytes) + 65821
482+
default:
483+
// size < 30, no modification needed
480484
}
481485
return size, newOffset, nil
482486
}

internal/decoder/reflection.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ func (d *ReflectionDecoder) unmarshalBool(
374374
result.Set(reflect.ValueOf(value))
375375
return newOffset, nil
376376
}
377+
default:
378+
// Fall through to error return
377379
}
378380
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
379381
}
@@ -400,6 +402,8 @@ func (d *ReflectionDecoder) unmarshalBytes(
400402
result.Set(reflect.ValueOf(value))
401403
return newOffset, nil
402404
}
405+
default:
406+
// Fall through to error return
403407
}
404408
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
405409
}
@@ -421,6 +425,8 @@ func (d *ReflectionDecoder) unmarshalFloat32(
421425
result.Set(reflect.ValueOf(value))
422426
return newOffset, nil
423427
}
428+
default:
429+
// Fall through to error return
424430
}
425431
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
426432
}
@@ -445,6 +451,8 @@ func (d *ReflectionDecoder) unmarshalFloat64(
445451
result.Set(reflect.ValueOf(value))
446452
return newOffset, nil
447453
}
454+
default:
455+
// Fall through to error return
448456
}
449457
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
450458
}
@@ -481,6 +489,8 @@ func (d *ReflectionDecoder) unmarshalInt32(
481489
result.Set(reflect.ValueOf(value))
482490
return newOffset, nil
483491
}
492+
default:
493+
// Fall through to error return
484494
}
485495
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
486496
}
@@ -492,8 +502,6 @@ func (d *ReflectionDecoder) unmarshalMap(
492502
depth int,
493503
) (uint, error) {
494504
switch result.Kind() {
495-
default:
496-
return 0, mmdberrors.NewUnmarshalTypeStrError("map", result.Type())
497505
case reflect.Struct:
498506
return d.decodeStruct(size, offset, result, depth)
499507
case reflect.Map:
@@ -508,6 +516,8 @@ func (d *ReflectionDecoder) unmarshalMap(
508516
return newOffset, err
509517
}
510518
return 0, mmdberrors.NewUnmarshalTypeStrError("map", result.Type())
519+
default:
520+
return 0, mmdberrors.NewUnmarshalTypeStrError("map", result.Type())
511521
}
512522
}
513523

@@ -556,6 +566,8 @@ func (d *ReflectionDecoder) unmarshalSlice(
556566
result.Set(rv.Value)
557567
return newOffset, err
558568
}
569+
default:
570+
// Fall through to error return
559571
}
560572
return 0, mmdberrors.NewUnmarshalTypeStrError("array", result.Type())
561573
}
@@ -578,6 +590,8 @@ func (d *ReflectionDecoder) unmarshalString(
578590
result.Set(reflect.ValueOf(value))
579591
return newOffset, nil
580592
}
593+
default:
594+
// Fall through to error return
581595
}
582596
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
583597
}
@@ -632,6 +646,8 @@ func (d *ReflectionDecoder) unmarshalUint(
632646
result.SetUint(value)
633647
return newOffset, nil
634648
}
649+
default:
650+
// Fall through to general unmarshaling logic
635651
}
636652

637653
switch result.Kind() {
@@ -656,6 +672,8 @@ func (d *ReflectionDecoder) unmarshalUint(
656672
result.Set(reflect.ValueOf(value))
657673
return newOffset, nil
658674
}
675+
default:
676+
// Fall through to error return
659677
}
660678
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
661679
}
@@ -691,6 +709,8 @@ func (d *ReflectionDecoder) unmarshalUint128(
691709
result.Set(reflect.ValueOf(value))
692710
return newOffset, nil
693711
}
712+
default:
713+
// Fall through to error return
694714
}
695715
return newOffset, mmdberrors.NewUnmarshalTypeError(value, result.Type())
696716
}
@@ -1210,6 +1230,8 @@ func (d *ReflectionDecoder) tryFastDecodeTyped(
12101230
addressableValue{result.Elem(), false},
12111231
expectedType.Elem(),
12121232
)
1233+
default:
1234+
// Type not supported for fast path
12131235
}
12141236

12151237
return 0, false

0 commit comments

Comments
 (0)