Co-authored-by: Zaphkiel <duambi123@gmail.com>
This commit is contained in:
co-authored by
Zaphkiel
parent
0f6e61f5af
commit
4a559338ae
@@ -15,10 +15,13 @@ import (
|
||||
// - prevents using existing elements of slices, fixing https://github.com/golang/go/issues/21092
|
||||
// - prevents setting slices to nil
|
||||
|
||||
func process(v reflect.Value, raw any) error {
|
||||
func process(v reflect.Value, raw any, path string) error {
|
||||
switch v.Kind() {
|
||||
case reflect.Slice:
|
||||
if raw == nil {
|
||||
if path != "" {
|
||||
return fmt.Errorf("cannot set slice '%s' to nil", path)
|
||||
}
|
||||
return fmt.Errorf("cannot set slice to nil")
|
||||
}
|
||||
|
||||
@@ -41,7 +44,11 @@ func process(v reflect.Value, raw any) error {
|
||||
jsonKey = strings.Split(jsonKey, ",")[0]
|
||||
|
||||
if rawVal, ok2 := rawMap[jsonKey]; ok2 {
|
||||
err := process(field, rawVal)
|
||||
fieldPath := jsonKey
|
||||
if path != "" {
|
||||
fieldPath = path + "." + jsonKey
|
||||
}
|
||||
err := process(field, rawVal, fieldPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -71,7 +78,7 @@ func Decode(r io.Reader, dest any) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = process(reflect.ValueOf(dest).Elem(), raw)
|
||||
err = process(reflect.ValueOf(dest).Elem(), raw, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -74,21 +74,37 @@ func TestUnmarshalPreventSliceReuse(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestUnmarshalSetSliceToNil(t *testing.T) {
|
||||
type Data struct {
|
||||
Items []string `json:"items"`
|
||||
}
|
||||
t.Run("top level", func(t *testing.T) {
|
||||
type Data struct {
|
||||
Items []string `json:"items"`
|
||||
}
|
||||
|
||||
var data Data
|
||||
var data Data
|
||||
|
||||
json := []byte(`{"items": null}`)
|
||||
err := Unmarshal(json, &data)
|
||||
require.EqualError(t, err, "cannot set slice to nil")
|
||||
json := []byte(`{"items": null}`)
|
||||
err := Unmarshal(json, &data)
|
||||
require.EqualError(t, err, "cannot set slice 'items' to nil")
|
||||
|
||||
data = Data{Items: []string{"a", "b"}}
|
||||
data = Data{Items: []string{"a", "b"}}
|
||||
|
||||
json = []byte(`{"items": null}`)
|
||||
err = Unmarshal(json, &data)
|
||||
require.EqualError(t, err, "cannot set slice to nil")
|
||||
json = []byte(`{"items": null}`)
|
||||
err = Unmarshal(json, &data)
|
||||
require.EqualError(t, err, "cannot set slice 'items' to nil")
|
||||
})
|
||||
|
||||
t.Run("nested", func(t *testing.T) {
|
||||
type Inner struct {
|
||||
Values []int `json:"values"`
|
||||
}
|
||||
type Outer struct {
|
||||
Inner Inner `json:"inner"`
|
||||
}
|
||||
|
||||
var data Outer
|
||||
json := []byte(`{"inner": {"values": null}}`)
|
||||
err := Unmarshal(json, &data)
|
||||
require.EqualError(t, err, "cannot set slice 'inner.values' to nil")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUnmarshalSetNullableSliceToNil(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user