Skip to content

Commit

Permalink
Protect against nil options in bundles
Browse files Browse the repository at this point in the history
GODRIVER-493

Change-Id: I25d861227f95b7016cd78c35f389b7b04a962a72
  • Loading branch information
rfblue2 committed Jul 24, 2018
1 parent eecffe0 commit 5a1987f
Show file tree
Hide file tree
Showing 37 changed files with 551 additions and 56 deletions.
11 changes: 9 additions & 2 deletions mongo/aggregateopt/aggregateopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ func (ab *AggregateBundle) bundleLength() int {
}

bundleLen := 0
for ; ab != nil && ab.option != nil; ab = ab.next {
for ; ab != nil; ab = ab.next {
if ab.option == nil {
continue
}
if converted, ok := ab.option.(*AggregateBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
Expand Down Expand Up @@ -197,7 +200,11 @@ func (ab *AggregateBundle) unbundle() ([]option.AggregateOptioner, *session.Clie
options := make([]option.AggregateOptioner, listLen)
index := listLen - 1

for listHead := ab; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := ab; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*AggregateBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/aggregateopt/aggregateopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,23 @@ func TestAggregateOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := AggregateSessionOpt{}
opts, _, err := BundleAggregate(AllowDiskUse(true), BundleAggregate(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleAggregate(nil, sess, BundleAggregate(nil), AllowDiskUse(true)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
15 changes: 12 additions & 3 deletions mongo/changestreamopt/changestreamopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,19 @@ func (csb *ChangeStreamBundle) bundleLength() int {
}

bundleLen := 0
for ; csb != nil && csb.option != nil; csb = csb.next {
for ; csb != nil; csb = csb.next {
if csb.option == nil {
continue
}
if converted, ok := csb.option.(*ChangeStreamBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := csb.option.(ChangeStreamSessionOpt); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -172,7 +177,11 @@ func (csb *ChangeStreamBundle) unbundle() ([]option.ChangeStreamOptioner, *sessi
options := make([]option.ChangeStreamOptioner, listLen)
index := listLen - 1

for listHead := csb; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := csb; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*ChangeStreamBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/changestreamopt/changestreamopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,23 @@ func TestChangeStreamOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := ChangeStreamSessionOpt{}
opts, _, err := BundleChangeStream(BatchSize(1), BundleChangeStream(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleChangeStream(nil, sess, BundleChangeStream(nil), BatchSize(1)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
15 changes: 12 additions & 3 deletions mongo/countopt/countopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,19 @@ func (cb *CountBundle) bundleLength() int {
}

bundleLen := 0
for ; cb != nil && cb.option != nil; cb = cb.next {
for ; cb != nil; cb = cb.next {
if cb.option == nil {
continue
}
if converted, ok := cb.option.(*CountBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := cb.option.(CountSessionOpt); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -175,7 +180,11 @@ func (cb *CountBundle) unbundle() ([]option.CountOptioner, *session.Client, erro
options := make([]option.CountOptioner, listLen)
index := listLen - 1

for listHead := cb; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := cb; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*CountBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/countopt/countopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,23 @@ func TestCountOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := CountSessionOpt{}
opts, _, err := BundleCount(Skip(1), BundleCount(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleCount(nil, sess, BundleCount(nil), Skip(1)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
15 changes: 12 additions & 3 deletions mongo/deleteopt/deleteopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,19 @@ func (db *DeleteBundle) bundleLength() int {
}

bundleLen := 0
for ; db != nil && db.option != nil; db = db.next {
for ; db != nil; db = db.next {
if db.option == nil {
continue
}
if converted, ok := db.option.(*DeleteBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := db.option.(DeleteSessionOpt); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -135,7 +140,11 @@ func (db *DeleteBundle) unbundle() ([]option.DeleteOptioner, *session.Client, er
options := make([]option.DeleteOptioner, listLen)
index := listLen - 1

for listHead := db; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := db; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*DeleteBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/deleteopt/deleteopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,23 @@ func TestDeleteOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := DeleteSessionOpt{}
opts, _, err := BundleDelete(Collation(c), BundleDelete(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleDelete(nil, sess, BundleDelete(nil), Collation(c)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
15 changes: 12 additions & 3 deletions mongo/distinctopt/distinctopt.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,19 @@ func (db *DistinctBundle) bundleLength() int {
}

bundleLen := 0
for ; db != nil && db.option != nil; db = db.next {
for ; db != nil; db = db.next {
if db.option == nil {
continue
}
if converted, ok := db.option.(*DistinctBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := db.option.(DistinctSessionOpt); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -141,7 +146,11 @@ func (db *DistinctBundle) unbundle() ([]option.DistinctOptioner, *session.Client
options := make([]option.DistinctOptioner, listLen)
index := listLen - 1

for listHead := db; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := db; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*DistinctBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/distinctopt/distinctopt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,23 @@ func TestDistinctOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := DistinctSessionOpt{}
opts, _, err := BundleDistinct(MaxTime(1), BundleDistinct(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleDistinct(nil, sess, BundleDistinct(nil), MaxTime(1)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
15 changes: 12 additions & 3 deletions mongo/findopt/deleteone.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,19 @@ func (dob *DeleteOneBundle) bundleLength() int {
}

bundleLen := 0
for ; dob != nil && dob.option != nil; dob = dob.next {
for ; dob != nil; dob = dob.next {
if dob.option == nil {
continue
}
if converted, ok := dob.option.(*DeleteOneBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := dob.option.(DeleteOneSession); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -169,7 +174,11 @@ func (dob *DeleteOneBundle) unbundle() ([]option.FindOneAndDeleteOptioner, *sess
options := make([]option.FindOneAndDeleteOptioner, listLen)
index := listLen - 1

for listHead := dob; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := dob; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*DeleteOneBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
15 changes: 12 additions & 3 deletions mongo/findopt/find.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,19 @@ func (fb *FindBundle) bundleLength() int {
}

bundleLen := 0
for ; fb != nil && fb.option != nil; fb = fb.next {
for ; fb != nil; fb = fb.next {
if fb.option == nil {
continue
}
if converted, ok := fb.option.(*FindBundle); ok {
// nested bundle
bundleLen += converted.bundleLength()
continue
}

bundleLen++
if _, ok := fb.option.(FindSessionOpt); !ok {
bundleLen++
}
}

return bundleLen
Expand All @@ -330,7 +335,11 @@ func (fb *FindBundle) unbundle() ([]option.FindOptioner, *session.Client, error)
options := make([]option.FindOptioner, listLen)
index := listLen - 1

for listHead := fb; listHead != nil && listHead.option != nil; listHead = listHead.next {
for listHead := fb; listHead != nil; listHead = listHead.next {
if listHead.option == nil {
continue
}

// if the current option is a nested bundle, Unbundle it and add its options to the current array
if converted, ok := listHead.option.(*FindBundle); ok {
nestedOptions, s, err := converted.unbundle()
Expand Down
17 changes: 17 additions & 0 deletions mongo/findopt/findopt_deleteone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,23 @@ func TestFindAndDeleteOneOpt(t *testing.T) {
}
})

t.Run("Nil Option Bundle", func(t *testing.T) {
sess := FindSessionOpt{}
opts, _, err := BundleDeleteOne(Sort(true), BundleDeleteOne(nil), sess, nil).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}

opts, _, err = BundleDeleteOne(nil, sess, BundleDeleteOne(nil), Sort(true)).unbundle()
testhelpers.RequireNil(t, err, "got non-nil error from unbundle: %s", err)

if len(opts) != 1 {
t.Errorf("expected bundle length 1. got: %d", len(opts))
}
})

t.Run("MakeOptions", func(t *testing.T) {
head := bundle1

Expand Down
Loading

0 comments on commit 5a1987f

Please sign in to comment.