mirror of
https://github.com/golang/go.git
synced 2025-11-09 13:11:03 +00:00
encoding/json: ignore embedded fields of pointers to unexported non-structs
https://golang.org/cl/33773 fixes the JSON marshaler to avoid serializing embedded fields on unexported types of non-struct types. However, Go allows embedding pointer to types, so the check for whether the field is a non-struct type must first dereference the pointer to get at the underlying type. Furthermore, due to a edge-case in the behavior of StructField.PkgPath not being a reliable indicator of whether the field is unexported (see #21122), we use our own logic to determine whether the field is exported or not. The logic in this CL may be simplified depending on what happens in #21122. Fixes #21121 Updates #21122 Change-Id: I8dfd1cdfac8a87950df294a566fb96dfd04fd749 Reviewed-on: https://go-review.googlesource.com/50711 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
5f7a03e148
commit
b817359249
2 changed files with 182 additions and 70 deletions
|
|
@ -1093,7 +1093,22 @@ func typeFields(t reflect.Type) []field {
|
|||
// Scan f.typ for fields to include.
|
||||
for i := 0; i < f.typ.NumField(); i++ {
|
||||
sf := f.typ.Field(i)
|
||||
if sf.PkgPath != "" && (!sf.Anonymous || sf.Type.Kind() != reflect.Struct) { // unexported
|
||||
if sf.Anonymous {
|
||||
t := sf.Type
|
||||
if t.Kind() == reflect.Ptr {
|
||||
t = t.Elem()
|
||||
}
|
||||
// If embedded, StructField.PkgPath is not a reliable
|
||||
// indicator of whether the field is exported.
|
||||
// See https://golang.org/issue/21122
|
||||
if !isExported(t.Name()) && t.Kind() != reflect.Struct {
|
||||
// Ignore embedded fields of unexported non-struct types.
|
||||
// Do not ignore embedded fields of unexported struct types
|
||||
// since they may have exported fields.
|
||||
continue
|
||||
}
|
||||
} else if sf.PkgPath != "" {
|
||||
// Ignore unexported non-embedded fields.
|
||||
continue
|
||||
}
|
||||
tag := sf.Tag.Get("json")
|
||||
|
|
@ -1211,6 +1226,12 @@ func typeFields(t reflect.Type) []field {
|
|||
return fields
|
||||
}
|
||||
|
||||
// isExported reports whether the identifier is exported.
|
||||
func isExported(id string) bool {
|
||||
r, _ := utf8.DecodeRuneInString(id)
|
||||
return unicode.IsUpper(r)
|
||||
}
|
||||
|
||||
// dominantField looks through the fields, all of which are known to
|
||||
// have the same name, to find the single field that dominates the
|
||||
// others using Go's embedding rules, modified by the presence of
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue