From f0e6a549f2f868b6ecbb5e05aa80b52d9baf9aee Mon Sep 17 00:00:00 2001 From: Nao Yonashiro Date: Mon, 4 Jul 2022 14:46:17 +0900 Subject: [PATCH 1/3] fix: support for embedding alias of primitive types fix #372 --- decode_test.go | 17 +++++++++++++++++ internal/decoder/compile.go | 9 +++++++++ 2 files changed, 26 insertions(+) diff --git a/decode_test.go b/decode_test.go index f5e2563..c276a32 100644 --- a/decode_test.go +++ b/decode_test.go @@ -3968,3 +3968,20 @@ func TestIssue335(t *testing.T) { t.Errorf("unexpected success") } } + +func TestIssue372(t *testing.T) { + type A int + type T struct { + _ int + *A + } + var v T + err := json.Unmarshal([]byte(`{"A":7}`), &v) + assertErr(t, err) + + got := *v.A + expected := A(7) + if got != expected { + t.Errorf("unexpected result: %v != %v", got, expected) + } +} diff --git a/internal/decoder/compile.go b/internal/decoder/compile.go index f13b43b..48b0217 100644 --- a/internal/decoder/compile.go +++ b/internal/decoder/compile.go @@ -393,6 +393,15 @@ func compileStruct(typ *runtime.Type, structName, fieldName string, structTypeTo } allFields = append(allFields, fieldSet) } + } else { + fieldSet := &structFieldSet{ + dec: pdec, + offset: field.Offset, + isTaggedKey: tag.IsTaggedKey, + key: field.Name, + keyLen: int64(len(field.Name)), + } + allFields = append(allFields, fieldSet) } } else { fieldSet := &structFieldSet{ From 565e07e45c3fff959ae82cfeff814309fe185928 Mon Sep 17 00:00:00 2001 From: Nao Yonashiro Date: Tue, 5 Jul 2022 01:15:08 +0900 Subject: [PATCH 2/3] fix: change isPtr to true on listElemCode fix #370 --- encode_test.go | 29 +++++++++++++++++++++++++++++ internal/encoder/compiler.go | 3 ++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/encode_test.go b/encode_test.go index 1c0de3c..480ec78 100644 --- a/encode_test.go +++ b/encode_test.go @@ -2424,3 +2424,32 @@ func TestIssue376(t *testing.T) { t.Errorf("unexpected result: %v != %v", got, expected) } } + +type Issue370 struct { + String string + Valid bool +} + +func (i *Issue370) MarshalJSON() ([]byte, error) { + if !i.Valid { + return json.Marshal(nil) + } + return json.Marshal(i.String) +} + +func TestIssue370(t *testing.T) { + v := []struct { + V Issue370 + }{ + {V: Issue370{String: "test", Valid: true}}, + } + b, err := json.Marshal(v) + if err != nil { + t.Fatal(err) + } + got := string(b) + expected := `[{"V":"test"}]` + if got != expected { + t.Errorf("unexpected result: %v != %v", got, expected) + } +} diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go index de7323c..83eab57 100644 --- a/internal/encoder/compiler.go +++ b/internal/encoder/compiler.go @@ -487,7 +487,8 @@ func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) { case typ.Kind() == reflect.Map: return c.ptrCode(runtime.PtrTo(typ)) default: - code, err := c.typeToCodeWithPtr(typ, false) + // Strictly not isPtr == true, but reflect.ValueOf().Index() is canAddr, so set isPtr == true. + code, err := c.typeToCodeWithPtr(typ, true) if err != nil { return nil, err } From 88aa13e3006fb5de4fa8c800778b4c671853e399 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Thu, 7 Jul 2022 14:52:28 +0900 Subject: [PATCH 3/3] Fix comment for #379 --- internal/encoder/compiler.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/encoder/compiler.go b/internal/encoder/compiler.go index 83eab57..64533f4 100644 --- a/internal/encoder/compiler.go +++ b/internal/encoder/compiler.go @@ -487,7 +487,9 @@ func (c *Compiler) listElemCode(typ *runtime.Type) (Code, error) { case typ.Kind() == reflect.Map: return c.ptrCode(runtime.PtrTo(typ)) default: - // Strictly not isPtr == true, but reflect.ValueOf().Index() is canAddr, so set isPtr == true. + // isPtr was originally used to indicate whether the type of top level is pointer. + // However, since the slice/array element is a specification that can get the pointer address, explicitly set isPtr to true. + // See here for related issues: https://github.com/goccy/go-json/issues/370 code, err := c.typeToCodeWithPtr(typ, true) if err != nil { return nil, err