Skip to content

Commit

Permalink
fix #365, return error for +inf -inf and NaN
Browse files Browse the repository at this point in the history
  • Loading branch information
Tao Wen committed May 23, 2019
1 parent 68347ec commit 08047c1
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
21 changes: 21 additions & 0 deletions misc_tests/jsoniter_float_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package misc_tests

import (
"encoding/json"
"math"
"testing"

"github.com/json-iterator/go"
Expand Down Expand Up @@ -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,`)
Expand Down
17 changes: 17 additions & 0 deletions stream_float.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package jsoniter

import (
"fmt"
"math"
"strconv"
)
Expand All @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down

0 comments on commit 08047c1

Please sign in to comment.