Skip to content

Commit 5dd971d

Browse files
wwqgtxxJoeingarm
authored andcommitted
fix: handle invalid values in Decoder's decode method
1 parent 30be102 commit 5dd971d

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

common/structure/structure.go

+20
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,27 @@ func (d *Decoder) Decode(src map[string]any, dst any) error {
8686
return nil
8787
}
8888

89+
// isNil returns true if the input is nil or a typed nil pointer.
90+
func isNil(input any) bool {
91+
if input == nil {
92+
return true
93+
}
94+
val := reflect.ValueOf(input)
95+
return val.Kind() == reflect.Pointer && val.IsNil()
96+
}
97+
8998
func (d *Decoder) decode(name string, data any, val reflect.Value) error {
99+
if isNil(data) {
100+
// If the data is nil, then we don't set anything
101+
// Maybe we should set to zero value?
102+
return nil
103+
}
104+
if !reflect.ValueOf(data).IsValid() {
105+
// If the input value is invalid, then we just set the value
106+
// to be the zero value.
107+
val.Set(reflect.Zero(val.Type()))
108+
return nil
109+
}
90110
for {
91111
kind := val.Kind()
92112
if kind == reflect.Pointer && val.IsNil() {

common/structure/structure_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,21 @@ func TestStructure_TextUnmarshaller(t *testing.T) {
267267
err = decoder.Decode(rawMap, s)
268268
assert.NotNilf(t, err, "should throw error: %#v", s)
269269
}
270+
271+
func TestStructure_Null(t *testing.T) {
272+
rawMap := map[string]any{
273+
"opt": map[string]any{
274+
"bar": nil,
275+
},
276+
}
277+
278+
s := struct {
279+
Opt struct {
280+
Bar string `test:"bar,optional"`
281+
} `test:"opt,optional"`
282+
}{}
283+
284+
err := decoder.Decode(rawMap, &s)
285+
assert.Nil(t, err)
286+
assert.Equal(t, s.Opt.Bar, "")
287+
}

0 commit comments

Comments
 (0)