encoding/json: always ignore embedded pointers to unexported struct types

CL 60410 fixes a bug in reflect that allows assignments to an embedded
field of a pointer to an unexported struct type.
This breaks the json package because unmarshal is now unable to assign
a newly allocated struct to such fields.

In order to be consistent in the behavior for marshal and unmarshal,
this CL changes both marshal and unmarshal to always ignore
embedded pointers to unexported structs.

Fixes #21357

Change-Id: If62ea11155555e61115ebb9cfa5305caf101bde5
Reviewed-on: https://go-review.googlesource.com/76851
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Joe Tsai 2017-11-09 20:14:47 -08:00 committed by Joe Tsai
parent 510327012b
commit 0cee4b7b78
3 changed files with 33 additions and 6 deletions

View file

@ -1094,11 +1094,18 @@ func typeFields(t reflect.Type) []field {
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