Q int
}
+type Issue21357 struct {
+ *embed
+ R int
+}
+
type Loop struct {
Loop1 int `json:",omitempty"`
Loop2 int `json:",omitempty"`
err: fmt.Errorf("json: unknown field \"extra\""),
disallowUnknownFields: true,
},
+
+ // Issue 21357.
+ // Ignore any embedded fields that are pointers to unexported structs.
+ {
+ in: `{"Q":1,"R":2}`,
+ ptr: new(Issue21357),
+ out: Issue21357{R: 2},
+ },
+ {
+ in: `{"Q":1,"R":2}`,
+ ptr: new(Issue21357),
+ err: fmt.Errorf("json: unknown field \"Q\""),
+ disallowUnknownFields: true,
+ },
}
func TestMarshal(t *testing.T) {
isUnexported := sf.PkgPath != ""
if sf.Anonymous {
t := sf.Type
- if t.Kind() == reflect.Ptr {
+ isPointer := t.Kind() == reflect.Ptr
+ if isPointer {
t = t.Elem()
}
- if isUnexported && t.Kind() != reflect.Struct {
- // Ignore embedded fields of unexported non-struct types.
+ isStruct := t.Kind() == reflect.Struct
+ if isUnexported && (!isStruct || isPointer) {
+ // Ignore embedded fields of unexported non-struct types
+ // or pointers to unexported struct types.
+ //
+ // The latter is forbidden because unmarshal is unable
+ // to assign a new struct to the unexported field.
+ // See https://golang.org/issue/21357
continue
}
// Do not ignore embedded fields of unexported struct types
want: `{"X":2,"Y":4}`,
}, {
// Exported fields of pointers to embedded structs should have their
- // exported fields be serialized regardless of whether the struct types
- // themselves are exported.
+ // exported fields be serialized only for exported struct types.
+ // Pointers to unexported structs are not allowed since the decoder
+ // is unable to allocate a struct for that field
label: "EmbeddedStructPointer",
makeInput: func() interface{} {
type (
)
return S{&s1{1, 2}, &S2{3, 4}}
},
- want: `{"X":2,"Y":4}`,
+ want: `{"Y":4}`,
}, {
// Exported fields on embedded unexported structs at multiple levels
// of nesting should still be serialized.