From 408827d87641247d5da13b60afcf36c8a1842bbc Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sat, 13 Jan 2024 23:48:50 +0800 Subject: [PATCH] fix: issue 3840 (#3845) --- core/mapping/unmarshaler.go | 7 ++++++- core/mapping/unmarshaler_test.go | 16 ++++++++++++++-- rest/httpx/requests_test.go | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go index 277edc5e0..6da3b3c36 100644 --- a/core/mapping/unmarshaler.go +++ b/core/mapping/unmarshaler.go @@ -625,7 +625,12 @@ func (u *Unmarshaler) processFieldPrimitiveWithJSONNumber(fieldType reflect.Type return err } - if value.OverflowFloat(fValue) { + // if value is a pointer, we need to check overflow with the pointer's value. + overflowValidator := value + if overflowValidator.Type().Kind() == reflect.Ptr { + overflowValidator = overflowValidator.Elem() + } + if overflowValidator.OverflowFloat(fValue) { return fmt.Errorf("parsing %q as float32: value out of range", v.String()) } diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go index d783670bf..2eca5228f 100644 --- a/core/mapping/unmarshaler_test.go +++ b/core/mapping/unmarshaler_test.go @@ -1339,8 +1339,20 @@ func TestUnmarshalNullableSlice(t *testing.T) { "slice": `[null,2]`, } - ast := assert.New(t) - ast.Equal(UnmarshalKey(m, &v), errNilSliceElement) + assert.New(t).Equal(UnmarshalKey(m, &v), errNilSliceElement) +} + +func TestUnmarshalWithFloatPtr(t *testing.T) { + var v struct { + WeightFloat32 *float32 `key:"weightFloat32,optional"` + } + m := map[string]any{ + "weightFloat32": json.Number("3.2"), + } + + if assert.NoError(t, UnmarshalKey(m, &v)) { + assert.Equal(t, float32(3.2), *v.WeightFloat32) + } } func TestUnmarshalIntSlice(t *testing.T) { diff --git a/rest/httpx/requests_test.go b/rest/httpx/requests_test.go index 04b6f21cf..57fe136f7 100644 --- a/rest/httpx/requests_test.go +++ b/rest/httpx/requests_test.go @@ -395,6 +395,21 @@ func TestParsePathWithDot(t *testing.T) { assert.Equal(t, 18, v.Age) } +func TestParseWithFloatPtr(t *testing.T) { + t.Run("has float32 pointer", func(t *testing.T) { + var v struct { + WeightFloat32 *float32 `json:"weightFloat32,optional"` + } + body := `{"weightFloat32": 3.2}` + r := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(body)) + r.Header.Set(ContentType, header.JsonContentType) + + if assert.NoError(t, Parse(r, &v)) { + assert.Equal(t, float32(3.2), *v.WeightFloat32) + } + }) +} + func BenchmarkParseRaw(b *testing.B) { r, err := http.NewRequest(http.MethodGet, "http://hello.com/a?name=hello&age=18&percent=3.4", http.NoBody) if err != nil {