Jelajahi Sumber

fix #365, return error for +inf -inf and NaN

Tao Wen 6 tahun lalu
induk
melakukan
08047c174c
2 mengubah file dengan 38 tambahan dan 0 penghapusan
  1. 21 0
      misc_tests/jsoniter_float_test.go
  2. 17 0
      stream_float.go

+ 21 - 0
misc_tests/jsoniter_float_test.go

@@ -2,6 +2,7 @@ package misc_tests
 
 import (
 	"encoding/json"
+	"math"
 	"testing"
 
 	"github.com/json-iterator/go"
@@ -77,6 +78,26 @@ func Test_read_number(t *testing.T) {
 	should.Equal(`92233720368547758079223372036854775807`, string(val))
 }
 
+func Test_encode_inf(t *testing.T) {
+	should := require.New(t)
+	_, err := json.Marshal(math.Inf(1))
+	should.Error(err)
+	_, err = jsoniter.Marshal(float32(math.Inf(1)))
+	should.Error(err)
+	_, err = jsoniter.Marshal(math.Inf(-1))
+	should.Error(err)
+}
+
+func Test_encode_nan(t *testing.T) {
+	should := require.New(t)
+	_, err := json.Marshal(math.NaN())
+	should.Error(err)
+	_, err = jsoniter.Marshal(float32(math.NaN()))
+	should.Error(err)
+	_, err = jsoniter.Marshal(math.NaN())
+	should.Error(err)
+}
+
 func Benchmark_jsoniter_float(b *testing.B) {
 	b.ReportAllocs()
 	input := []byte(`1.1123,`)

+ 17 - 0
stream_float.go

@@ -1,6 +1,7 @@
 package jsoniter
 
 import (
+	"fmt"
 	"math"
 	"strconv"
 )
@@ -13,6 +14,10 @@ func init() {
 
 // WriteFloat32 write float32 to stream
 func (stream *Stream) WriteFloat32(val float32) {
+	if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) {
+		stream.Error = fmt.Errorf("unsupported value: %f", val)
+		return
+	}
 	abs := math.Abs(float64(val))
 	fmt := byte('f')
 	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
@@ -26,6 +31,10 @@ func (stream *Stream) WriteFloat32(val float32) {
 
 // WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
 func (stream *Stream) WriteFloat32Lossy(val float32) {
+	if math.IsInf(float64(val), 0) || math.IsNaN(float64(val)) {
+		stream.Error = fmt.Errorf("unsupported value: %f", val)
+		return
+	}
 	if val < 0 {
 		stream.writeByte('-')
 		val = -val
@@ -54,6 +63,10 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
 
 // WriteFloat64 write float64 to stream
 func (stream *Stream) WriteFloat64(val float64) {
+	if math.IsInf(val, 0) || math.IsNaN(val) {
+		stream.Error = fmt.Errorf("unsupported value: %f", val)
+		return
+	}
 	abs := math.Abs(val)
 	fmt := byte('f')
 	// Note: Must use float32 comparisons for underlying float32 value to get precise cutoffs right.
@@ -67,6 +80,10 @@ func (stream *Stream) WriteFloat64(val float64) {
 
 // WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
 func (stream *Stream) WriteFloat64Lossy(val float64) {
+	if math.IsInf(val, 0) || math.IsNaN(val) {
+		stream.Error = fmt.Errorf("unsupported value: %f", val)
+		return
+	}
 	if val < 0 {
 		stream.writeByte('-')
 		val = -val