Skip to content

Commit ef3d2c5

Browse files
author
Divjot Arora
committed
Disallow decoding BSON to nil pointer.
GODRIVER-1005 Change-Id: I52ea2e1c2b200abfae82baa58b6dc954228e9e2a
1 parent 975716b commit ef3d2c5

File tree

4 files changed

+20
-2
lines changed

4 files changed

+20
-2
lines changed

bson/decoder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import (
1616
"go.mongodb.org/mongo-driver/bson/bsonrw"
1717
)
1818

19+
// ErrDecodeToNil is the error returned when trying to decode to a nil value
20+
var ErrDecodeToNil = errors.New("cannot Decode to nil value")
21+
1922
// This pool is used to keep the allocations of Decoders down. This is only used for the Marshal*
2023
// methods and is not consumable from outside of this package. The Decoders retrieved from this pool
2124
// must have both Reset and SetRegistry called on them.
@@ -78,6 +81,9 @@ func (d *Decoder) Decode(val interface{}) error {
7881
if rval.Kind() != reflect.Ptr {
7982
return fmt.Errorf("argument to Decode must be a pointer to a type, but got %v", rval)
8083
}
84+
if rval.IsNil() {
85+
return ErrDecodeToNil
86+
}
8187
rval = rval.Elem()
8288
decoder, err := d.dc.LookupDecoder(rval.Type())
8389
if err != nil {

bson/decoder_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,18 @@ func TestDecoderv2(t *testing.T) {
235235
t.Errorf("Decoder should use the Registry provided. got %v; want %v", dec.dc, dc2)
236236
}
237237
})
238+
t.Run("DecodeToNil", func(t *testing.T) {
239+
data := docToBytes(D{{"item", "canvas"}, {"qty", 4}})
240+
vr := bsonrw.NewBSONDocumentReader(data)
241+
dec, err := NewDecoder(vr)
242+
noerr(t, err)
243+
244+
var got *D
245+
err = dec.Decode(got)
246+
if err != ErrDecodeToNil {
247+
t.Fatalf("Decode error mismatch; expected %v, got %v", ErrDecodeToNil, err)
248+
}
249+
})
238250
}
239251

240252
type testDecoderCodec struct {

mongo/cursor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (c *Cursor) Next(ctx context.Context) bool {
118118
}
119119
}
120120

121-
// Decode will decode the current document into val.
121+
// Decode will decode the current document into val. If val is nil or is a typed nil, an error will be returned.
122122
func (c *Cursor) Decode(val interface{}) error {
123123
return bson.UnmarshalWithRegistry(c.registry, c.Current, val)
124124
}

mongo/single_result.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type SingleResult struct {
3131
// Decode will attempt to decode the first document into v. If there was an
3232
// error from the operation that created this SingleResult then the error
3333
// will be returned. If there were no returned documents, ErrNoDocuments is
34-
// returned.
34+
// returned. If v is nil or is a typed nil, an error will be returned.
3535
func (sr *SingleResult) Decode(v interface{}) error {
3636
if sr.err != nil {
3737
return sr.err

0 commit comments

Comments
 (0)