Skip to content

Commit 8621791

Browse files
author
Divjot Arora
authored
GODRIVER-1520 Fix panics for lone scope (#331)
1 parent c03b147 commit 8621791

File tree

2 files changed

+59
-21
lines changed

2 files changed

+59
-21
lines changed

bson/bsonrw/extjson_parser.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
115115
case jpsSawKey:
116116
t = wrapperKeyBSONType(ejp.k)
117117

118-
if t == bsontype.JavaScript {
118+
switch t {
119+
case bsontype.JavaScript:
119120
// just saw $code, need to check for $scope at same level
120121
_, err := ejp.readValue(bsontype.JavaScript)
121122

@@ -137,6 +138,8 @@ func (ejp *extJSONParser) peekType() (bsontype.Type, error) {
137138
default:
138139
err = ErrInvalidJSON
139140
}
141+
case bsontype.CodeWithScope:
142+
err = errors.New("invalid extended JSON: code with $scope must contain $code before $scope")
140143
}
141144
}
142145
}

bson/bsonrw/extjson_parser_test.go

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ func TestExtJSONParserPeekType(t *testing.T) {
9393
errFs: []expectedErrorFunc{expectNoError},
9494
}
9595
}
96+
makeInvalidTestCase := func(desc, input string, lastEF expectedErrorFunc) peekTypeTestCase {
97+
return peekTypeTestCase{
98+
desc: desc, input: input,
99+
typs: []bsontype.Type{bsontype.Type(0)},
100+
errFs: []expectedErrorFunc{lastEF},
101+
}
102+
}
96103

97104
makeInvalidPeekTypeTestCase := func(desc, input string, lastEF expectedErrorFunc) peekTypeTestCase {
98105
return peekTypeTestCase{
@@ -140,18 +147,26 @@ func TestExtJSONParserPeekType(t *testing.T) {
140147
typs: []bsontype.Type{bsontype.Array, bsontype.Type(0)},
141148
errFs: []expectedErrorFunc{expectNoError, expectError},
142149
},
150+
makeInvalidTestCase("lone $scope", `{"$scope": {}}`, expectError),
143151
}
144152

145153
for _, tc := range cases {
146-
ejp := newExtJSONParser(strings.NewReader(tc.input), true)
147-
148-
for i, eTyp := range tc.typs {
149-
errF := tc.errFs[i]
150-
151-
typ, err := ejp.peekType()
152-
typDiff(t, eTyp, typ, tc.desc)
153-
errF(t, err, tc.desc)
154-
}
154+
t.Run(tc.desc, func(t *testing.T) {
155+
ejp := newExtJSONParser(strings.NewReader(tc.input), true)
156+
157+
for i, eTyp := range tc.typs {
158+
errF := tc.errFs[i]
159+
160+
typ, err := ejp.peekType()
161+
errF(t, err, tc.desc)
162+
if err != nil {
163+
// Don't inspect the type if there was an error
164+
return
165+
}
166+
167+
typDiff(t, eTyp, typ, tc.desc)
168+
}
169+
})
155170
}
156171
}
157172

@@ -295,24 +310,44 @@ func TestExtJSONParserReadKeyReadValue(t *testing.T) {
295310
secondKeyError("invalid input: missing comma", `{"a": 1 "b"`, "a", bsontype.Int32, &extJSONValue{t: bsontype.Int32, v: int32(1)}),
296311
secondKeyError("invalid input: extra comma", `{"a": 1,, "b"`, "a", bsontype.Int32, &extJSONValue{t: bsontype.Int32, v: int32(1)}),
297312
secondKeyError("invalid input: trailing comma in object", `{"a": 1,}`, "a", bsontype.Int32, &extJSONValue{t: bsontype.Int32, v: int32(1)}),
313+
{
314+
desc: "invalid input: lone scope after a complete value",
315+
input: `{"a": "", "b": {"$scope: ""}}`,
316+
keys: []string{"a"},
317+
typs: []bsontype.Type{bsontype.String},
318+
vals: []*extJSONValue{{bsontype.String, ""}},
319+
keyEFs: []expectedErrorFunc{expectNoError, expectNoError},
320+
valEFs: []expectedErrorFunc{expectNoError, expectError},
321+
},
322+
{
323+
desc: "invalid input: lone scope nested",
324+
input: `{"a":{"b":{"$scope":{`,
325+
keys: []string{},
326+
typs: []bsontype.Type{},
327+
vals: []*extJSONValue{nil},
328+
keyEFs: []expectedErrorFunc{expectNoError},
329+
valEFs: []expectedErrorFunc{expectError},
330+
},
298331
}
299332

300333
for _, tc := range cases {
301-
ejp := newExtJSONParser(strings.NewReader(tc.input), true)
334+
t.Run(tc.desc, func(t *testing.T) {
335+
ejp := newExtJSONParser(strings.NewReader(tc.input), true)
302336

303-
for i, eKey := range tc.keys {
304-
eTyp := tc.typs[i]
305-
eVal := tc.vals[i]
337+
for i, eKey := range tc.keys {
338+
eTyp := tc.typs[i]
339+
eVal := tc.vals[i]
306340

307-
keyErrF := tc.keyEFs[i]
308-
valErrF := tc.valEFs[i]
341+
keyErrF := tc.keyEFs[i]
342+
valErrF := tc.valEFs[i]
309343

310-
k, typ, err := ejp.readKey()
311-
readKeyDiff(t, eKey, k, eTyp, typ, err, keyErrF, tc.desc)
344+
k, typ, err := ejp.readKey()
345+
readKeyDiff(t, eKey, k, eTyp, typ, err, keyErrF, tc.desc)
312346

313-
v, err := ejp.readValue(typ)
314-
readValueDiff(t, eVal, v, err, valErrF, tc.desc)
315-
}
347+
v, err := ejp.readValue(typ)
348+
readValueDiff(t, eVal, v, err, valErrF, tc.desc)
349+
}
350+
})
316351
}
317352
}
318353

0 commit comments

Comments
 (0)