Skip to content

Commit 3a0c0a5

Browse files
authored
GODRIVER-2133 Error on nonempty semantic single documents as aggregate pipelines (#721)
1 parent 7477257 commit 3a0c0a5

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

mongo/mongo.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,17 @@ func transformAggregatePipeline(registry *bsoncodec.Registry, pipeline interface
228228
aidx, arr := bsoncore.AppendArrayStart(nil)
229229
var hasOutputStage bool
230230
valLen := val.Len()
231+
232+
// Explicitly forbid non-empty pipelines that are semantically single documents
233+
// and are implemented as slices.
234+
switch t := pipeline.(type) {
235+
case bson.D, bson.Raw, bsoncore.Document:
236+
if valLen > 0 {
237+
return nil, false,
238+
fmt.Errorf("%T is not an allowed pipeline type as it represents a single document. Use bson.A or mongo.Pipeline instead", t)
239+
}
240+
}
241+
231242
for idx := 0; idx < valLen; idx++ {
232243
doc, err := transformBsoncoreDocument(registry, val.Index(idx).Interface(), true, fmt.Sprintf("pipeline stage :%v", idx))
233244
if err != nil {

mongo/mongo_test.go

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ func TestMongoHelpers(t *testing.T) {
126126
arr, _ = bsoncore.AppendDocumentEnd(arr, dindex)
127127
arr, _ = bsoncore.AppendArrayEnd(arr, index)
128128

129+
index, doc := bsoncore.AppendDocumentStart(nil)
130+
doc = bsoncore.AppendInt32Element(doc, "x", 1)
131+
doc, _ = bsoncore.AppendDocumentEnd(doc, index)
132+
129133
testCases := []struct {
130134
name string
131135
pipeline interface{}
@@ -342,6 +346,48 @@ func TestMongoHelpers(t *testing.T) {
342346
true,
343347
nil,
344348
},
349+
{
350+
"semantic single document/bson.D",
351+
bson.D{{"x", 1}},
352+
nil,
353+
false,
354+
errors.New("primitive.D is not an allowed pipeline type as it represents a single document. Use bson.A or mongo.Pipeline instead"),
355+
},
356+
{
357+
"semantic single document/bson.Raw",
358+
bson.Raw(doc),
359+
nil,
360+
false,
361+
errors.New("bson.Raw is not an allowed pipeline type as it represents a single document. Use bson.A or mongo.Pipeline instead"),
362+
},
363+
{
364+
"semantic single document/bsoncore.Document",
365+
bsoncore.Document(doc),
366+
nil,
367+
false,
368+
errors.New("bsoncore.Document is not an allowed pipeline type as it represents a single document. Use bson.A or mongo.Pipeline instead"),
369+
},
370+
{
371+
"semantic single document/empty bson.D",
372+
bson.D{},
373+
bson.A{},
374+
false,
375+
nil,
376+
},
377+
{
378+
"semantic single document/empty bson.Raw",
379+
bson.Raw{},
380+
bson.A{},
381+
false,
382+
nil,
383+
},
384+
{
385+
"semantic single document/empty bsoncore.Document",
386+
bsoncore.Document{},
387+
bson.A{},
388+
false,
389+
nil,
390+
},
345391
}
346392

347393
for _, tc := range testCases {

0 commit comments

Comments
 (0)