Skip to content

Commit 107d1db

Browse files
Return error if trying to marshal +Inf, -Inf or NaN
1 parent fe2707c commit 107d1db

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

jwriter/writer.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
package jwriter
33

44
import (
5+
"fmt"
56
"io"
7+
"math"
68
"strconv"
79
"unicode/utf8"
810

@@ -248,23 +250,39 @@ func (w *Writer) Int64Str(n int64) {
248250
}
249251

250252
func (w *Writer) Float32(n float32) {
253+
if w.checkIsUnsupportedFloat(float64(n)) {
254+
return
255+
}
256+
251257
w.Buffer.EnsureSpace(20)
252258
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
253259
}
254260

255261
func (w *Writer) Float32Str(n float32) {
262+
if w.checkIsUnsupportedFloat(float64(n)) {
263+
return
264+
}
265+
256266
w.Buffer.EnsureSpace(20)
257267
w.Buffer.Buf = append(w.Buffer.Buf, '"')
258268
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 32)
259269
w.Buffer.Buf = append(w.Buffer.Buf, '"')
260270
}
261271

262272
func (w *Writer) Float64(n float64) {
273+
if w.checkIsUnsupportedFloat(n) {
274+
return
275+
}
276+
263277
w.Buffer.EnsureSpace(20)
264278
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, n, 'g', -1, 64)
265279
}
266280

267281
func (w *Writer) Float64Str(n float64) {
282+
if w.checkIsUnsupportedFloat(n) {
283+
return
284+
}
285+
268286
w.Buffer.EnsureSpace(20)
269287
w.Buffer.Buf = append(w.Buffer.Buf, '"')
270288
w.Buffer.Buf = strconv.AppendFloat(w.Buffer.Buf, float64(n), 'g', -1, 64)
@@ -415,3 +433,16 @@ func (w *Writer) base64(in []byte) {
415433
w.Buffer.Buf = append(w.Buffer.Buf, byte(padChar), byte(padChar))
416434
}
417435
}
436+
437+
func (w *Writer) checkIsUnsupportedFloat(val float64) bool {
438+
isUnsupported := math.IsNaN(val) || math.IsInf(val, 0)
439+
if isUnsupported && w.Error == nil {
440+
w.Error = newUnsupportedValueError(val)
441+
}
442+
443+
return isUnsupported
444+
}
445+
446+
func newUnsupportedValueError(value any) error {
447+
return fmt.Errorf("json: unsupported value: %v", value)
448+
}

tests/errors.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@ type ErrorNestedStruct struct {
2424

2525
//easyjson:json
2626
type ErrorIntMap map[uint32]string
27+
28+
//easyjson:json
29+
type ErrorFloatTypes struct {
30+
Float64 float64 `json:"float64"`
31+
Float32 float32 `json:"float32"`
32+
}

tests/errors_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package tests
22

33
import (
4+
"math"
45
"testing"
56

67
"github.com/mailru/easyjson/jlexer"
@@ -283,3 +284,40 @@ func TestMultipleErrorsIntMap(t *testing.T) {
283284
}
284285
}
285286
}
287+
288+
func TestUnsupportedFloatValues(t *testing.T) {
289+
for i, test := range []struct {
290+
Value ErrorFloatTypes
291+
ExpectedErr string
292+
}{
293+
{
294+
Value: ErrorFloatTypes{Float64: math.NaN()},
295+
ExpectedErr: "json: unsupported value: NaN",
296+
},
297+
{
298+
Value: ErrorFloatTypes{Float64: math.Inf(1)},
299+
ExpectedErr: "json: unsupported value: +Inf",
300+
},
301+
{
302+
Value: ErrorFloatTypes{Float64: math.Inf(-1)},
303+
ExpectedErr: "json: unsupported value: -Inf",
304+
},
305+
{
306+
Value: ErrorFloatTypes{Float32: float32(math.NaN())},
307+
ExpectedErr: "json: unsupported value: NaN",
308+
},
309+
{
310+
Value: ErrorFloatTypes{Float32: float32(math.Inf(1))},
311+
ExpectedErr: "json: unsupported value: +Inf",
312+
},
313+
{
314+
Value: ErrorFloatTypes{Float32: float32(math.Inf(-1))},
315+
ExpectedErr: "json: unsupported value: -Inf",
316+
},
317+
} {
318+
_, err := test.Value.MarshalJSON()
319+
if err == nil || err.Error() != test.ExpectedErr {
320+
t.Errorf("[%d] TestUnsupportedFloatValues(): error: want %s, got %v", i, test.ExpectedErr, err)
321+
}
322+
}
323+
}

0 commit comments

Comments
 (0)