diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-07 01:24:57 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2015-11-07 01:24:57 +0000 |
commit | 6285b2c805d128dff03b93ff02100731d881018b (patch) | |
tree | fb4d9c89c2c9990d67757f795779aa52ee64305c /libgo/go/encoding | |
parent | c0226d868b773eeba6a0275bab3e7ee319584004 (diff) | |
download | gcc-6285b2c805d128dff03b93ff02100731d881018b.tar.gz |
PR go/66138
reflect, encoding/json, encoding/xml: fix unexported embedded structs
Bring in three changes from the master Go repository. These changes
will be in Go 1.6, but they are appropriate for gccgo now because they
resolve a long-standing discrepancy between how gc and gccgo handle the
PkgPath field for embedded unexported struct fields. The core issue is
described at https://golang.org/cl/7247. This has been reported against
gccgo as https://gcc.gnu.org/PR66138.
The three changes being brought over are:
https://golang.org/cl/14010
reflect: adjust access to unexported embedded structs
This CL changes reflect to allow access to exported fields and
methods in unexported embedded structs for gccgo and after gc
has been adjusted to disallow access to embedded unexported structs.
Adresses #12367, #7363, #11007, and #7247.
https://golang.org/cl/14011
encoding/json: check for exported fields in embedded structs
Addresses issue #12367.
https://golang.org/cl/14012
encoding/xml: check for exported fields in embedded structs
Addresses issue #12367.
Reviewed-on: https://go-review.googlesource.com/16723
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@229907 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go/encoding')
-rw-r--r-- | libgo/go/encoding/json/decode_test.go | 16 | ||||
-rw-r--r-- | libgo/go/encoding/json/encode.go | 2 | ||||
-rw-r--r-- | libgo/go/encoding/xml/marshal_test.go | 10 | ||||
-rw-r--r-- | libgo/go/encoding/xml/typeinfo.go | 2 |
4 files changed, 26 insertions, 4 deletions
diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 8aa158f08cd..51b15ef997c 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -118,6 +118,7 @@ type Top struct { Loop Embed0p // has Point with X, Y, used Embed0q // has Point with Z, used + embed // contains exported field } type Embed0 struct { @@ -148,6 +149,10 @@ type Embed0q struct { Point } +type embed struct { + Q int +} + type Loop struct { Loop1 int `json:",omitempty"` Loop2 int `json:",omitempty"` @@ -331,7 +336,8 @@ var unmarshalTests = []unmarshalTest{ "Loop2": 14, "X": 15, "Y": 16, - "Z": 17 + "Z": 17, + "Q": 18 }`, ptr: new(Top), out: Top{ @@ -361,6 +367,9 @@ var unmarshalTests = []unmarshalTest{ Embed0q: Embed0q{ Point: Point{Z: 17}, }, + embed: embed{ + Q: 18, + }, }, }, { @@ -507,12 +516,15 @@ func TestMarshalEmbeds(t *testing.T) { Embed0q: Embed0q{ Point: Point{Z: 17}, }, + embed: embed{ + Q: 18, + }, } b, err := Marshal(top) if err != nil { t.Fatal(err) } - want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}" + want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17,\"Q\":18}" if string(b) != want { t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want) } diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 90782deb70b..e829a930768 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -1022,7 +1022,7 @@ 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 != "" { // unexported + if sf.PkgPath != "" && !sf.Anonymous { // unexported continue } tag := sf.Tag.Get("json") diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index 66675d7abc4..ef6c20e949b 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -139,6 +139,7 @@ type EmbedA struct { EmbedC EmbedB EmbedB FieldA string + embedD } type EmbedB struct { @@ -153,6 +154,11 @@ type EmbedC struct { FieldC string } +type embedD struct { + fieldD string + FieldE string // Promoted and visible when embedD is embedded. +} + type NameCasing struct { XMLName struct{} `xml:"casing"` Xy string @@ -711,6 +717,9 @@ var marshalTests = []struct { }, }, FieldA: "A.A", + embedD: embedD{ + FieldE: "A.D.E", + }, }, ExpectXML: `<EmbedA>` + `<FieldB>A.C.B</FieldB>` + @@ -724,6 +733,7 @@ var marshalTests = []struct { `<FieldC>A.B.C.C</FieldC>` + `</EmbedB>` + `<FieldA>A.A</FieldA>` + + `<FieldE>A.D.E</FieldE>` + `</EmbedA>`, }, diff --git a/libgo/go/encoding/xml/typeinfo.go b/libgo/go/encoding/xml/typeinfo.go index 22248d20a6d..6766b88f09a 100644 --- a/libgo/go/encoding/xml/typeinfo.go +++ b/libgo/go/encoding/xml/typeinfo.go @@ -60,7 +60,7 @@ func getTypeInfo(typ reflect.Type) (*typeInfo, error) { n := typ.NumField() for i := 0; i < n; i++ { f := typ.Field(i) - if f.PkgPath != "" || f.Tag.Get("xml") == "-" { + if (f.PkgPath != "" && !f.Anonymous) || f.Tag.Get("xml") == "-" { continue // Private field } |