Repository: zeromicro/go-zero (go)

Issue:
httpx.Parse will panic when parsing *float32
**Describe the bug**
httpx.Parse will panic when parsing *float32

**To Reproduce**
Steps to reproduce the behavior, if applicable:

1. The code is

   ```go
   	t.Run("has *float32", func(t *testing.T) {
		var v struct {
			// WeightFloat32
			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)
		}
	})
   ```

2. The error is

   ```
   panic: reflect: call of reflect.Value.OverflowFloat on ptr Value
   ```

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Environments (please complete the following information):**
 - OS: [e.g. Linux]
 - go-zero version [e.g. 1.2.1]
 - goctl version [e.g. 1.2.1, optional]

**More description**
Add any other context about the problem here.

https://github.com/zeromicro/go-zero/blob/6ec38ec05689d858ed55608268806fe353e2f348/core/mapping/unmarshaler.go#L624
This time the call.overflowfloat will be reported to panic, which can modify the method of detection overflow

Pull request:
fix: issue 3840
fix #3840 

Patch:
diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go
index 277edc5e..6da3b3c3 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())
 		}
 


Test patch:
diff --git a/core/mapping/unmarshaler_test.go b/core/mapping/unmarshaler_test.go
index d783670b..2eca5228 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 04b6f21c..57fe136f 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 {