From ca258d6fbd941455c0d462dd46d5a3cb5b389553 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 22 Jan 2021 18:48:24 +0300 Subject: [PATCH] fixedn: always correctly unmarshal Fixed8 values Quoted or not, they should be unmarshalled without going through float64. --- pkg/encoding/fixedn/fixed8.go | 37 +++++++++++++----------------- pkg/encoding/fixedn/fixed8_test.go | 13 +++++++++++ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/pkg/encoding/fixedn/fixed8.go b/pkg/encoding/fixedn/fixed8.go index 014a6e888..ff92e6b6d 100644 --- a/pkg/encoding/fixedn/fixed8.go +++ b/pkg/encoding/fixedn/fixed8.go @@ -1,7 +1,6 @@ package fixedn import ( - "encoding/json" "errors" "strconv" "strings" @@ -80,34 +79,30 @@ func Fixed8FromString(s string) (Fixed8, error) { // UnmarshalJSON implements the json unmarshaller interface. func (f *Fixed8) UnmarshalJSON(data []byte) error { - return f.unmarshalHelper(func(v interface{}) error { - return json.Unmarshal(data, v) - }) + if len(data) > 2 { + if data[0] == '"' && data[len(data)-1] == '"' { + data = data[1 : len(data)-1] + } + } + return f.setFromString(string(data)) } // UnmarshalYAML implements the yaml unmarshaler interface. func (f *Fixed8) UnmarshalYAML(unmarshal func(interface{}) error) error { - return f.unmarshalHelper(unmarshal) -} - -// unmarshalHelper is an underlying unmarshaller func for JSON and YAML. -func (f *Fixed8) unmarshalHelper(unmarshal func(interface{}) error) error { var s string - if err := unmarshal(&s); err == nil { - p, err := Fixed8FromString(s) - if err != nil { - return err - } - *f = p - return nil - } - - var fl float64 - if err := unmarshal(&fl); err != nil { + err := unmarshal(&s) + if err != nil { return err } + return f.setFromString(s) +} - *f = Fixed8(decimals * fl) +func (f *Fixed8) setFromString(s string) error { + p, err := Fixed8FromString(s) + if err != nil { + return err + } + *f = p return nil } diff --git a/pkg/encoding/fixedn/fixed8_test.go b/pkg/encoding/fixedn/fixed8_test.go index 4bbaf2af2..99ef0d74e 100644 --- a/pkg/encoding/fixedn/fixed8_test.go +++ b/pkg/encoding/fixedn/fixed8_test.go @@ -123,6 +123,19 @@ func TestFixed8UnmarshalJSON(t *testing.T) { } } +func TestFixed8_Unmarshal(t *testing.T) { + var expected = Fixed8(223719420) + var cases = []string{"2.2371942", `"2.2371942"`} // this easily gives 223719419 if interpreted as float + + for _, c := range cases { + var u1, u2 Fixed8 + assert.Nil(t, json.Unmarshal([]byte(c), &u1)) + assert.Equal(t, expected, u1) + assert.Nil(t, yaml.Unmarshal([]byte(c), &u2)) + assert.Equal(t, expected, u2) + } +} + func TestFixed8_MarshalJSON(t *testing.T) { u, err := Fixed8FromString("123.4") assert.NoError(t, err)