Skip to content

Commit b4d25d2

Browse files
tviDivjot Arora
authored andcommitted
Fix bsoncore overflow (#223)
1 parent 6bd1ab1 commit b4d25d2

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

x/bsonx/bsoncore/bsoncore.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ func ReadElement(src []byte) (Element, []byte, bool) {
123123
if elemLength > len(src) {
124124
return nil, src, false
125125
}
126+
if elemLength < 0 {
127+
return nil, src, false
128+
}
126129
return src[:elemLength], src[elemLength:], true
127130
}
128131

@@ -723,13 +726,18 @@ func appendi32(dst []byte, i32 int32) []byte {
723726
// ReadLength reads an int32 length from src and returns the length and the remaining bytes. If
724727
// there aren't enough bytes to read a valid length, src is returned unomdified and the returned
725728
// bool will be false.
726-
func ReadLength(src []byte) (int32, []byte, bool) { return readi32(src) }
729+
func ReadLength(src []byte) (int32, []byte, bool) {
730+
ln, src, ok := readi32(src)
731+
if ln < 0 {
732+
return ln, src, false
733+
}
734+
return ln, src, ok
735+
}
727736

728737
func readi32(src []byte) (int32, []byte, bool) {
729738
if len(src) < 4 {
730739
return 0, src, false
731740
}
732-
733741
return (int32(src[0]) | int32(src[1])<<8 | int32(src[2])<<16 | int32(src[3])<<24), src[4:], true
734742
}
735743

x/bsonx/document_test.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,25 @@ func TestDocument(t *testing.T) {
6565
t.Parallel()
6666
t.Run("UnmarshalingError", func(t *testing.T) {
6767
t.Parallel()
68-
invalid := []byte{0x01, 0x02}
69-
want := bsoncore.NewInsufficientBytesError(nil, nil)
70-
_, got := ReadDoc(invalid)
71-
if !compareErrors(got, want) {
72-
t.Errorf("Expected errors to match. got %v; want %v", got, want)
68+
testCases := []struct {
69+
name string
70+
invalid []byte
71+
}{
72+
{"base", []byte{0x01, 0x02}},
73+
{"fuzzed1", []byte("0\x990\xc4")}, // fuzzed
74+
{"fuzzed2", []byte("\x10\x00\x00\x00\x10\x000000\x0600\x00\x05\x00\xff\xff\xff\u007f")}, // fuzzed
75+
}
76+
77+
for _, tc := range testCases {
78+
tc := tc
79+
t.Run(tc.name, func(t *testing.T) {
80+
t.Parallel()
81+
want := bsoncore.NewInsufficientBytesError(nil, nil)
82+
_, got := ReadDoc(tc.invalid)
83+
if !compareErrors(got, want) {
84+
t.Errorf("Expected errors to match. got %v; want %v", got, want)
85+
}
86+
})
7387
}
7488
})
7589
t.Run("success", func(t *testing.T) {

0 commit comments

Comments
 (0)