Skip to content

Commit a484ec6

Browse files
authored
Merge pull request #5 from dumim/develop
Fixed panicing on uninitialised nested structs
2 parents 3e7c8cf + 4f3efdb commit a484ec6

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

map.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ func getMapOfAllKeyValues(s interface{}) *map[string]interface{} {
5555
// only check if the value can be obtained without panicking (eg: for unexported fields)
5656
if t.Field(i).CanInterface() {
5757
qVars := getMapOfAllKeyValues(t.Field(i).Interface()) //recursive call
58-
for k, v := range *qVars {
59-
vars[k] = v
58+
if qVars != nil {
59+
for k, v := range *qVars {
60+
vars[k] = v
61+
}
6062
}
6163
}
6264
} else {
@@ -68,8 +70,10 @@ func getMapOfAllKeyValues(s interface{}) *map[string]interface{} {
6870
// only check if the value can be obtained without panicking (eg: for unexported fields)
6971
if t.Field(i).CanInterface() {
7072
qVars := getMapOfAllKeyValues(t.Field(i).Interface()) //recursive call
71-
for k, v := range *qVars {
72-
vars[fmt.Sprintf("%s.%s", tag, k)] = v // prepend the parent tag name
73+
if qVars != nil {
74+
for k, v := range *qVars {
75+
vars[fmt.Sprintf("%s.%s", tag, k)] = v // prepend the parent tag name
76+
}
7377
}
7478
}
7579
} else {

map_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,40 @@ func TestMultipleTagsStructToMap(t *testing.T) {
160160
require.JSONEqf(t, expectedJSONOne, string(actualJSONOne), "JSON mismatch for foo tags")
161161
require.JSONEqf(t, expectedJSONTwo, string(actualJSONTwo), "JSON mismatch for bar tags")
162162
}
163+
164+
// TestNilAndUnexportedFields calls ToMap function and checks against the expected result
165+
// The struct used tries to use nil/empty fields and unexported fields which should not cause the test to panic
166+
func TestNilAndUnexportedFields(t *testing.T) {
167+
type MyStruct struct {
168+
f1 string `custom:"f1"`
169+
F2 struct {
170+
F21 string `custom:"f21"`
171+
} `custom:"age"`
172+
F3 *string `custom:"f3"`
173+
F4 int `custom:"f4"`
174+
}
175+
176+
obj := MyStruct{
177+
F4: 666,
178+
}
179+
180+
// expected response
181+
expectedJSON := `{
182+
"f3": null,
183+
"f4": 666
184+
}
185+
`
186+
187+
// get the map from custom tags
188+
actual, err := ToMap(obj, "custom")
189+
if err != nil {
190+
t.Fail()
191+
}
192+
actualJSON, err := json.Marshal(actual)
193+
if err != nil {
194+
t.Fail()
195+
}
196+
197+
// compare
198+
require.JSONEqf(t, expectedJSON, string(actualJSON), "JSON mismatch")
199+
}

0 commit comments

Comments
 (0)