[GODRIVER-2427] Unmarshal Failing With Custom UnmarshalBSON Function and Mismatched pointer/non-pointer typing Created: 18/May/22  Updated: 28/Oct/23  Resolved: 01/Jun/22

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: None
Fix Version/s: 1.10.0

Type: Bug Priority: Unknown
Reporter: Anthony Phelps Assignee: Preston Vasquez
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File main.go    
Issue Links:
Related
is related to GODRIVER-2252 Unmarshalling null into a pointer fie... Closed

 Description   

Summary

Given a custom type whose underlying type is a map and an attached UnmarshalBSON method with a pointer receiver:

type MyMap map[string]interface{}
 
func (m *MyMap) UnmarshalBSON(byts []byte) error {
	//Implementaion not relevant
	return nil
}

Then creating a struct with a field the type of which is the custom type (importantly not a pointer to the type)

type MyStruct struct {
	MyMap MyMap
}

Any attempt to unmarshal a BSON document into an instance of *MyStruct where the MyMap field in the BSON document is null will cause a panic in bson.DefaultValueDecoders#ValueUnmarshalerDecodeValue

panic: reflect: reflect.Value.Set using unaddressable value

Prior to v1.9.0, this code would run through bson.Unmarshal without error.

Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

Driver Version: 1.9.0+

MongoDB version: N/A

How to Reproduce

package mainimport (	"fmt"	"go.mongodb.org/mongo-driver/bson")type MyMap map[string]interface{}func (m *MyMap) UnmarshalBSON(byts []byte) error {	// Implementation not relevant	return nil}type MyStruct struct {	MyMap MyMap}func main() {	// Making some BSON so I don't have to craft it by hand	x := &MyStruct{}	byts, err := bson.Marshal(x)	if err != nil {		panic(err)	}	// Immediately unmarshal to show the panic	y := &MyStruct{}	err = bson.Unmarshal(byts, y) // Panic will occur in here	if err != nil {		panic(err)	}}

Additional Background

N/A



 Comments   
Comment by Anthony Phelps [ 01/Jun/22 ]

Awesome! Thank you!

Comment by Preston Vasquez [ 01/Jun/22 ]

aphelps@vailsys.com We've implemented a patch for this bug fix, it is expected to be released in v1.10.0.  Thank you again!

Comment by Preston Vasquez [ 25/May/22 ]

aphelps@vailsys.com Thank you for bringing this to our attention, we are looking into it.

Comment by Anthony Phelps [ 19/May/22 ]

Jira really mangled that How to Reproduce section. Trying again here:

package main
 
import (
	"fmt"
 
	"go.mongodb.org/mongo-driver/bson"
)
 
type MyMap map[string]interface{}
 
func (m *MyMap) UnmarshalBSON(byts []byte) error {
	//Implementation not relevant
	return nil
}
 
type MyStruct struct {
	MyMap MyMap
}
 
func main() {
	// Making some BSON so I don't have to craft it by hand
	x := &MyStruct{}
	byts, err := bson.Marshal(x)
	if err != nil {
		panic(err)
	}
 
	// Immediately unmarshal to show the panic
	y := &MyStruct{}
	err = bson.Unmarshal(byts, y)
	if err != nil {
		panic(err)
	}
 
	fmt.Printf("%#v\n", y)
}

And here as a file for good measure: main.go

Generated at Thu Feb 08 08:38:34 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.