Skip to content

Commit 2bb951e

Browse files
committed
Add bounds check suggested by Copilot
1 parent 6c76e0a commit 2bb951e

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

internal/decoder/decoder.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,14 @@ func (d *Decoder) DecodeUInt128() (hi, lo uint64, err error) {
224224
)
225225
}
226226

227+
if offset+size > uint(len(d.d.buffer)) {
228+
return 0, 0, mmdberrors.NewInvalidDatabaseError(
229+
"the MaxMind DB file's data section contains bad data (offset+size %d exceeds buffer length %d)",
230+
offset+size,
231+
len(d.d.buffer),
232+
)
233+
}
234+
227235
for _, b := range d.d.buffer[offset : offset+size] {
228236
var carry byte
229237
lo, carry = append64(lo, b)
@@ -392,6 +400,13 @@ func (d *Decoder) decodeBytes(typ Type) ([]byte, error) {
392400
if err != nil {
393401
return nil, err
394402
}
403+
if offset+size > uint(len(d.d.buffer)) {
404+
return nil, mmdberrors.NewInvalidDatabaseError(
405+
"the MaxMind DB file's data section contains bad data (offset+size %d exceeds buffer length %d)",
406+
offset+size,
407+
len(d.d.buffer),
408+
)
409+
}
395410
d.setNextOffset(offset + size)
396411
return d.d.buffer[offset : offset+size], nil
397412
}

internal/decoder/decoder_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,32 @@ func TestPointersInDecoder(t *testing.T) {
366366
})
367367
}
368368
}
369+
370+
// TestBoundsChecking verifies that buffer access is properly bounds-checked
371+
// to prevent panics on malformed databases.
372+
func TestBoundsChecking(t *testing.T) {
373+
// Create a very small buffer that would cause out-of-bounds access
374+
// if bounds checking is not working
375+
smallBuffer := []byte{0x44, 0x41} // Type string (0x4), size 4, but only 2 bytes total
376+
dd := NewDataDecoder(smallBuffer)
377+
decoder := &Decoder{d: dd, offset: 0}
378+
379+
// This should fail gracefully with an error instead of panicking
380+
_, err := decoder.DecodeString()
381+
require.Error(t, err)
382+
require.Contains(t, err.Error(), "exceeds buffer length")
383+
384+
// Test DecodeBytes bounds checking
385+
_, err = decoder.decodeBytes(TypeBytes)
386+
require.Error(t, err)
387+
require.Contains(t, err.Error(), "exceeds buffer length")
388+
389+
// Test DecodeUInt128 bounds checking
390+
largeBuffer := []byte{0x0B, 0x01} // Type uint128 (0x0), size 11, but only 2 bytes total
391+
dd2 := NewDataDecoder(largeBuffer)
392+
decoder2 := &Decoder{d: dd2, offset: 0}
393+
394+
_, _, err = decoder2.DecodeUInt128()
395+
require.Error(t, err)
396+
require.Contains(t, err.Error(), "exceeds buffer length")
397+
}

0 commit comments

Comments
 (0)