Skip to content

Commit 5a0f697

Browse files
vranacybrcodr
authored andcommitted
Deserialize JSON NaN, Infinity and -Infinity to corresponding Go values (golang#363)
Deserialize JSON NaN, Infinity and -Infinity to corresponding Go values
1 parent 6e4cc92 commit 5a0f697

File tree

2 files changed

+18
-0
lines changed

2 files changed

+18
-0
lines changed

jsonpb/jsonpb.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
108108

109109
type int32Slice []int32
110110

111+
var nonFinite = map[string]float64{
112+
`"NaN"`: math.NaN(),
113+
`"Infinity"`: math.Inf(1),
114+
`"-Infinity"`: math.Inf(-1),
115+
}
116+
111117
// For sorting extensions ids to ensure stable output.
112118
func (s int32Slice) Len() int { return len(s) }
113119
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
@@ -981,6 +987,15 @@ func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMe
981987
inputValue = inputValue[1 : len(inputValue)-1]
982988
}
983989

990+
// Non-finite numbers can be encoded as strings.
991+
isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
992+
if isFloat {
993+
if num, ok := nonFinite[string(inputValue)]; ok {
994+
target.SetFloat(num)
995+
return nil
996+
}
997+
}
998+
984999
// Use the encoding/json for parsing other value types.
9851000
return json.Unmarshal(inputValue, target.Addr().Interface())
9861001
}

jsonpb/jsonpb_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,9 @@ var unmarshalingTests = []struct {
530530
}}},
531531
{"unquoted int64 object", Unmarshaler{}, `{"oInt64":-314}`, &pb.Simple{OInt64: proto.Int64(-314)}},
532532
{"unquoted uint64 object", Unmarshaler{}, `{"oUint64":123}`, &pb.Simple{OUint64: proto.Uint64(123)}},
533+
{"NaN", Unmarshaler{}, `{"oDouble":"NaN"}`, &pb.Simple{ODouble: proto.Float64(math.NaN())}},
534+
{"Inf", Unmarshaler{}, `{"oFloat":"Infinity"}`, &pb.Simple{OFloat: proto.Float32(float32(math.Inf(1)))}},
535+
{"-Inf", Unmarshaler{}, `{"oDouble":"-Infinity"}`, &pb.Simple{ODouble: proto.Float64(math.Inf(-1))}},
533536
{"map<int64, int32>", Unmarshaler{}, `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}},
534537
{"map<string, string>", Unmarshaler{}, `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}},
535538
{"map<int32, Object>", Unmarshaler{}, `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}},

0 commit comments

Comments
 (0)