Repository: zeromicro/go-zero
Pull request #3811 (2023-12-23 14:23:34)

fix:  negative float32 overflow when unmarshalling
When unmarshalling, if a negative float32 number is out of range,  the error  "out of range" would be returned.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zeromicro/go-zero/pull/3811?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`28c742a`)](https://app.codecov.io/gh/zeromicro/go-zero/commit/28c742a1e10fed78c2f173bc620093db80db1e0a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) 94.68% compared to head [(`e0d535f`)](https://app.codecov.io/gh/zeromicro/go-zero/pull/3811?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) 94.68%.

<details><summary>Additional details and impacted files</summary>



| [Files](https://app.codecov.io/gh/zeromicro/go-zero/pull/3811?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro) | Coverage Δ | |
|---|---|---|
| [core/mapping/unmarshaler.go](https://app.codecov.io/gh/zeromicro/go-zero/pull/3811?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zeromicro#diff-Y29yZS9tYXBwaW5nL3VubWFyc2hhbGVyLmdv) | `96.43% <100.00%> (ø)` | |

</details>

Patch:
diff --git a/core/mapping/unmarshaler.go b/core/mapping/unmarshaler.go
index 15215693..7df118e9 100644
--- a/core/mapping/unmarshaler.go
+++ b/core/mapping/unmarshaler.go
@@ -5,7 +5,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"math"
 	"reflect"
 	"strconv"
 	"strings"
@@ -622,7 +621,7 @@ func (u *Unmarshaler) processFieldPrimitiveWithJSONNumber(fieldType reflect.Type
 			return err
 		}
 
-		if fValue > math.MaxFloat32 {
+		if value.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 fd02fd6d..e0bd07d3 100644
--- a/core/mapping/unmarshaler_test.go
+++ b/core/mapping/unmarshaler_test.go
@@ -976,6 +976,19 @@ func TestUnmarshalFloat32WithOverflow(t *testing.T) {
 		assert.Error(t, UnmarshalKey(m, &in))
 	})
 
+	t.Run("float32 from string less than float32", func(t *testing.T) {
+		type inner struct {
+			Value float32 `key:"float, string"`
+		}
+
+		m := map[string]any{
+			"float": "-1.79769313486231570814527423731704356798070e+300", // overflow
+		}
+
+		var in inner
+		assert.Error(t, UnmarshalKey(m, &in))
+	})
+
 	t.Run("float32 from json.Number greater than float64", func(t *testing.T) {
 		type inner struct {
 			Value float32 `key:"float"`
@@ -1001,6 +1014,19 @@ func TestUnmarshalFloat32WithOverflow(t *testing.T) {
 		var in inner
 		assert.Error(t, UnmarshalKey(m, &in))
 	})
+
+	t.Run("float32 from json number less than float32", func(t *testing.T) {
+		type inner struct {
+			Value float32 `key:"float"`
+		}
+
+		m := map[string]any{
+			"float": json.Number("-1.79769313486231570814527423731704356798070e+300"), // overflow
+		}
+
+		var in inner
+		assert.Error(t, UnmarshalKey(m, &in))
+	})
 }
 
 func TestUnmarshalFloat64WithOverflow(t *testing.T) {