Commit c20c0925 authored by Evan Shaw's avatar Evan Shaw Committed by Andrew Gerrand

encoding/json: don't marshal special float values

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/5500084
parent 38ff98b4
...@@ -12,6 +12,7 @@ package json ...@@ -12,6 +12,7 @@ package json
import ( import (
"bytes" "bytes"
"encoding/base64" "encoding/base64"
"math"
"reflect" "reflect"
"runtime" "runtime"
"sort" "sort"
...@@ -170,6 +171,15 @@ func (e *UnsupportedTypeError) Error() string { ...@@ -170,6 +171,15 @@ func (e *UnsupportedTypeError) Error() string {
return "json: unsupported type: " + e.Type.String() return "json: unsupported type: " + e.Type.String()
} }
type UnsupportedValueError struct {
Value reflect.Value
Str string
}
func (e *UnsupportedValueError) Error() string {
return "json: unsupported value: " + e.Str
}
type InvalidUTF8Error struct { type InvalidUTF8Error struct {
S string S string
} }
...@@ -290,7 +300,11 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) { ...@@ -290,7 +300,11 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
e.Write(b) e.Write(b)
} }
case reflect.Float32, reflect.Float64: case reflect.Float32, reflect.Float64:
b := strconv.AppendFloat(e.scratch[:0], v.Float(), 'g', -1, v.Type().Bits()) f := v.Float()
if math.IsInf(f, 0) || math.IsNaN(f) {
e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, v.Type().Bits())})
}
b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, v.Type().Bits())
if quoted { if quoted {
writeString(e, string(b)) writeString(e, string(b))
} else { } else {
......
...@@ -6,6 +6,7 @@ package json ...@@ -6,6 +6,7 @@ package json
import ( import (
"bytes" "bytes"
"math"
"reflect" "reflect"
"testing" "testing"
) )
...@@ -107,3 +108,21 @@ func TestEncodeRenamedByteSlice(t *testing.T) { ...@@ -107,3 +108,21 @@ func TestEncodeRenamedByteSlice(t *testing.T) {
t.Errorf(" got %s want %s", result, expect) t.Errorf(" got %s want %s", result, expect)
} }
} }
var unsupportedValues = []interface{}{
math.NaN(),
math.Inf(-1),
math.Inf(1),
}
func TestUnsupportedValues(t *testing.T) {
for _, v := range unsupportedValues {
if _, err := Marshal(v); err != nil {
if _, ok := err.(*UnsupportedValueError); !ok {
t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
}
} else {
t.Errorf("for %v, expected error", v)
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment