Skip to content

Commit 0f4dd65

Browse files
author
Divjot Arora
committed
Filter out index names for legacy list collections operations.
GODRIVER-1132 Change-Id: Ia55ea07f52436895a830ad511ea5ebf64b41dc08
1 parent e64ebe3 commit 0f4dd65

File tree

3 files changed

+80
-10
lines changed

3 files changed

+80
-10
lines changed

mongo/database_internal_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package mongo
99
import (
1010
"context"
1111
"errors"
12+
"strings"
1213
"testing"
1314

1415
"fmt"
@@ -381,3 +382,50 @@ func TestDatabase_ListCollections(t *testing.T) {
381382
})
382383
}
383384
}
385+
386+
func TestDatabase_LegacyListCollections(t *testing.T) {
387+
db := createTestDatabase(t, nil, nil)
388+
version, err := getServerVersion(db)
389+
noerr(t, err)
390+
if compareVersions(t, version, "2.6") > 0 {
391+
t.Skip("skipping for server versions > 2.6")
392+
}
393+
394+
coll := db.Collection("bar", options.Collection().SetWriteConcern(writeconcern.New(writeconcern.WMajority())))
395+
initCollection(t, coll)
396+
397+
t.Run("ignore indexes", func(t *testing.T) {
398+
// legacy list collections should not return any collections containing a $
399+
c, err := db.ListCollections(ctx, bson.D{})
400+
noerr(t, err)
401+
defer func() {
402+
_ = c.Close(ctx)
403+
}()
404+
405+
for c.Next(ctx) {
406+
name := c.Current.Lookup("name").StringValue()
407+
if strings.Contains(name, "$") {
408+
t.Fatalf("index %s returned from ListCollections", name)
409+
}
410+
}
411+
})
412+
t.Run("filter name", func(t *testing.T) {
413+
c, err := db.ListCollections(ctx, bson.D{{"name", "bar"}})
414+
noerr(t, err)
415+
defer func() {
416+
_ = c.Close(ctx)
417+
}()
418+
419+
var foundBar bool
420+
for c.Next(ctx) {
421+
name := c.Current.Lookup("name").StringValue()
422+
if name == "bar" {
423+
foundBar = true
424+
break
425+
}
426+
}
427+
if !foundBar {
428+
t.Fatalf("collection bar not returned from ListCollections")
429+
}
430+
})
431+
}

x/mongo/driver/list_collections.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,27 @@ func legacyListCollections(
115115
// modify the user-supplied filter to prefix the "name" field with the database name.
116116
// returns the original filter if the name field is not present or a copy with the modified name field if it is
117117
func transformFilter(filter bsonx.Doc, dbName string) (bsonx.Doc, error) {
118+
regexFilter := bsonx.Doc{
119+
{"name", bsonx.Regex("^[^$]*$", "")},
120+
}
121+
118122
if filter == nil {
119-
return filter, nil
123+
return regexFilter, nil
120124
}
121125

122-
if nameVal, err := filter.LookupErr("name"); err == nil {
123-
name, ok := nameVal.StringValueOK()
126+
converted := filter
127+
if nameIdx := filter.IndexOf("name"); nameIdx != -1 {
128+
name, ok := filter[nameIdx].Value.StringValueOK()
124129
if !ok {
125130
return nil, ErrFilterType
126131
}
127132

128-
filterCopy := filter.Copy()
129-
filterCopy.Set("name", bsonx.String(dbName+"."+name))
130-
return filterCopy, nil
133+
converted = filter.Copy()
134+
converted[nameIdx].Value = bsonx.String(dbName + "." + name)
131135
}
132-
return filter, nil
136+
137+
filterArr := bsonx.Arr{bsonx.Document(regexFilter), bsonx.Document(converted)}
138+
return bsonx.Doc{
139+
{"$and", bsonx.Array(filterArr)},
140+
}, nil
133141
}

x/mongo/driver/list_collections_test.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@ import (
1212
"testing"
1313
)
1414

15+
func addRegexFitler(filter bsonx.Doc) bsonx.Doc {
16+
regexFilter := bsonx.Doc{
17+
{"name", bsonx.Regex("^[^$]*$", "")},
18+
}
19+
if filter == nil {
20+
return regexFilter
21+
}
22+
23+
arr := bsonx.Arr{bsonx.Document(regexFilter), bsonx.Document(filter)}
24+
return bsonx.Doc{
25+
{"$and", bsonx.Array(arr)},
26+
}
27+
}
28+
1529
func TestListCollections(t *testing.T) {
1630
dbName := "db"
1731
noNameFilter := bsonx.Doc{
@@ -34,10 +48,10 @@ func TestListCollections(t *testing.T) {
3448
expectedFilter bsonx.Doc
3549
err error
3650
}{
37-
{"TestNilFilter", nil, nil, nil},
38-
{"TestNoName", noNameFilter, noNameFilter, nil},
51+
{"TestNilFilter", nil, addRegexFitler(nil), nil},
52+
{"TestNoName", noNameFilter, addRegexFitler(noNameFilter), nil},
3953
{"TestNonStringName", nonStringFilter, nil, ErrFilterType},
40-
{"TestName", nameFilter, modifiedFilter, nil},
54+
{"TestName", nameFilter, addRegexFitler(modifiedFilter), nil},
4155
}
4256

4357
for _, tc := range testCases {

0 commit comments

Comments
 (0)