diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 8a1927a39ca..dc21e285a3d 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -3,3 +3,4 @@ ### SDK Enhancements ### SDK Bugs +* Fix an issue where `jsonutil.UnmarshalJSON()` is called with an insufficient size slice. diff --git a/private/protocol/json/jsonutil/unmarshal.go b/private/protocol/json/jsonutil/unmarshal.go index f9334879b80..f7357cb804b 100644 --- a/private/protocol/json/jsonutil/unmarshal.go +++ b/private/protocol/json/jsonutil/unmarshal.go @@ -187,9 +187,12 @@ func (u unmarshaler) unmarshalList(value reflect.Value, data interface{}, tag re return fmt.Errorf("JSON value is not a list (%#v)", data) } - if value.IsNil() { - l := len(listData) + if l := len(listData); value.IsNil() { value.Set(reflect.MakeSlice(value.Type(), l, l)) + } else { + if value.Kind() != reflect.Slice || value.Len() < len(listData) { + return fmt.Errorf("existing slice not big enough to hold list data (%#v)", data) + } } for i, c := range listData { diff --git a/private/protocol/json/jsonutil/unmarshal_test.go b/private/protocol/json/jsonutil/unmarshal_test.go index 1e7ec3615ef..df03aa4c152 100644 --- a/private/protocol/json/jsonutil/unmarshal_test.go +++ b/private/protocol/json/jsonutil/unmarshal_test.go @@ -149,3 +149,17 @@ func TestUnmarshalJSON_JSONNumber(t *testing.T) { }) } } + +func TestUnmarshalJSON_SliceNotBigEnough(t *testing.T) { + type input struct { + ListField []*int64 `locationName:"listField" type:"list"` + } + JSON := `{"listField": [1]}` + value := input{ + ListField: make([]*int64, 0), + } + err := jsonutil.UnmarshalJSON(&value, bytes.NewReader([]byte(JSON))) + if err == nil { + t.Error("expect error, got nil") + } +}