goccy / go-yaml

YAML support for the Go language

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Marshaler interfaces not checked against addressable non-pointers

exodustx0 opened this issue · comments

Consider the following:

import "github.com/goccy/go-yaml"

type foo string

func (f *foo) MarshalYAML() ([]byte, error) {
	println("BytesMarshaler hit")
	return []byte(string(*f) + "quux"), nil
}

func main() {
	f := foo("foobar")
	in := []*foo{&f}
	_, err := yaml.MarshalWithOptions(&in)
	if err != nil {
		println(err.Error())
		return
	}
}

This faithfully prints BytesMarshaler hit. However, if you change in into []foo{f}, it doesn't. This is because (*Encoder).canEncodeByMarshaler() doesn't test against v.Addr(), and foo's MarshalYAML method has a pointer receiver.

Though only related and not directly relevant to this issue, I'll add that there's no reason for (*Encoder).canEncodeByMarshaler() to use the expensive v.Interface(), as v.Implements() should suffice.