Skip to content

Commit 9837bb9

Browse files
committed
Fix case sensitivity for nested fields
1 parent 7cceb6c commit 9837bb9

File tree

2 files changed

+86
-4
lines changed

2 files changed

+86
-4
lines changed

api_tests/config_test.go

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package test
22

33
import (
44
"encoding/json"
5+
"testing"
6+
57
"github.com/json-iterator/go"
68
"github.com/stretchr/testify/require"
7-
"testing"
89
)
910

1011
func Test_use_number_for_unmarshal(t *testing.T) {
@@ -45,3 +46,79 @@ func Test_read_large_number_as_interface(t *testing.T) {
4546
should.Nil(err)
4647
should.Equal(`123456789123456789123456789`, output)
4748
}
49+
50+
type caseSensitiveStruct struct {
51+
A string `json:"a"`
52+
B string `json:"b,omitempty"`
53+
C *C `json:"C,omitempty"`
54+
}
55+
56+
type C struct {
57+
D int64 `json:"D,omitempty"`
58+
E *E `json:"e,omitempty"`
59+
}
60+
61+
type E struct {
62+
F string `json:"F,omitempty"`
63+
}
64+
65+
func Test_CaseSensitive(t *testing.T) {
66+
should := require.New(t)
67+
68+
testCases := []struct {
69+
input string
70+
expectedOutput string
71+
caseSensitive bool
72+
}{
73+
{
74+
input: `{"A":"foo","B":"bar"}`,
75+
expectedOutput: `{"a":"foo","b":"bar"}`,
76+
caseSensitive: false,
77+
},
78+
{
79+
input: `{"a":"foo","b":"bar"}`,
80+
expectedOutput: `{"a":"foo","b":"bar"}`,
81+
caseSensitive: true,
82+
},
83+
{
84+
input: `{"a":"foo","b":"bar","C":{"D":10}}`,
85+
expectedOutput: `{"a":"foo","b":"bar","C":{"D":10}}`,
86+
caseSensitive: true,
87+
},
88+
{
89+
input: `{"a":"foo","B":"bar","c":{"d":10}}`,
90+
expectedOutput: `{"a":"foo"}`,
91+
caseSensitive: true,
92+
},
93+
{
94+
input: `{"a":"foo","C":{"d":10}}`,
95+
expectedOutput: `{"a":"foo","C":{}}`,
96+
caseSensitive: true,
97+
},
98+
{
99+
input: `{"a":"foo","C":{"D":10,"e":{"f":"baz"}}}`,
100+
expectedOutput: `{"a":"foo","C":{"D":10,"e":{}}}`,
101+
caseSensitive: true,
102+
},
103+
{
104+
input: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
105+
expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
106+
caseSensitive: true,
107+
},
108+
{
109+
input: `{"A":"foo","c":{"d":10,"E":{"f":"baz"}}}`,
110+
expectedOutput: `{"a":"foo","C":{"D":10,"e":{"F":"baz"}}}`,
111+
caseSensitive: false,
112+
},
113+
}
114+
115+
for _, tc := range testCases {
116+
val := caseSensitiveStruct{}
117+
err := jsoniter.Config{CaseSensitive: tc.caseSensitive}.Froze().UnmarshalFromString(tc.input, &val)
118+
should.Nil(err)
119+
120+
output, err := jsoniter.MarshalToString(val)
121+
should.Nil(err)
122+
should.Equal(tc.expectedOutput, output)
123+
}
124+
}

reflect_struct_decoder.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@ func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
3232
for k, binding := range bindings {
3333
fields[k] = binding.Decoder.(*structFieldDecoder)
3434
}
35-
for k, binding := range bindings {
36-
if _, found := fields[strings.ToLower(k)]; !found {
37-
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
35+
36+
if !ctx.caseSensitive() {
37+
for k, binding := range bindings {
38+
if _, found := fields[strings.ToLower(k)]; !found {
39+
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
40+
}
3841
}
3942
}
43+
4044
return createStructDecoder(ctx, typ, fields)
4145
}
4246

@@ -47,6 +51,7 @@ func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structF
4751
knownHash := map[int64]struct{}{
4852
0: {},
4953
}
54+
5055
switch len(fields) {
5156
case 0:
5257
return &skipObjectDecoder{typ}

0 commit comments

Comments
 (0)