Skip to content

Commit

Permalink
Fix panic on private embedded interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Feresey committed Aug 28, 2020
1 parent eeeca48 commit 12f4fa6
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 2 deletions.
7 changes: 6 additions & 1 deletion decode.go
Expand Up @@ -549,9 +549,14 @@ func resetMap(out reflect.Value) {
func (d *decoder) null(out reflect.Value) bool {
if out.CanAddr() {
switch out.Kind() {
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
case reflect.Ptr, reflect.Map, reflect.Slice:
out.Set(reflect.Zero(out.Type()))
return true
case reflect.Interface:
if out.CanSet() {
out.Set(reflect.Zero(out.Type()))
return true
}
}
}
return false
Expand Down
10 changes: 10 additions & 0 deletions decode_test.go
Expand Up @@ -314,6 +314,16 @@ var unmarshalTests = []struct {
"a: YES",
&struct{ A bool }{true},
},
// Inlined interface
{
"a: 1\nb:\n privateinterface: null\n",
&struct {
A int
B struct {
privateInterface
}
}{A: 1},
},

// Some cross type conversions
{
Expand Down
2 changes: 1 addition & 1 deletion encode.go
Expand Up @@ -110,7 +110,7 @@ func (e *encoder) marshalDoc(tag string, in reflect.Value) {

func (e *encoder) marshal(tag string, in reflect.Value) {
tag = shortTag(tag)
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() || !in.CanInterface() {
e.nilv()
return
}
Expand Down
13 changes: 13 additions & 0 deletions encode_test.go
Expand Up @@ -30,6 +30,8 @@ import (
"gopkg.in/yaml.v3"
)

type privateInterface interface{}

var marshalIntTest = 123

var marshalTests = []struct {
Expand Down Expand Up @@ -292,6 +294,17 @@ var marshalTests = []struct {
"a: 1\n",
},

// Inlined interface
{
&struct {
A int
B struct {
privateInterface
}
}{A: 1},
"a: 1\nb:\n privateinterface: null\n",
},

// Struct inlining
{
&struct {
Expand Down

0 comments on commit 12f4fa6

Please sign in to comment.