common: using `ParseUint` instead of `ParseInt` (#30020)

Since Decimal is defined as unsiged `uint64`, we should use `strconv.ParseUint` instead of `strconv.ParseInt` during unmarshalling.

---------

Co-authored-by: Martin Holst Swende <martin@swende.se>
pull/30026/head
Halimao 5 months ago committed by GitHub
parent 0e3a0a693c
commit c11aac249d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      common/types.go
  2. 27
      common/types_test.go

@ -468,7 +468,7 @@ func (d *Decimal) UnmarshalJSON(input []byte) error {
if !isString(input) { if !isString(input) {
return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))} return &json.UnmarshalTypeError{Value: "non-string", Type: reflect.TypeOf(uint64(0))}
} }
if i, err := strconv.ParseInt(string(input[1:len(input)-1]), 10, 64); err == nil { if i, err := strconv.ParseUint(string(input[1:len(input)-1]), 10, 64); err == nil {
*d = Decimal(i) *d = Decimal(i)
return nil return nil
} else { } else {

@ -21,6 +21,7 @@ import (
"database/sql/driver" "database/sql/driver"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"math/big" "math/big"
"reflect" "reflect"
"strings" "strings"
@ -595,3 +596,29 @@ func BenchmarkPrettyDuration(b *testing.B) {
} }
b.Logf("Post %s", a) b.Logf("Post %s", a)
} }
func TestDecimalUnmarshalJSON(t *testing.T) {
// These should error
for _, tc := range []string{``, `"`, `""`, `"-1"`} {
if err := new(Decimal).UnmarshalJSON([]byte(tc)); err == nil {
t.Errorf("input %s should cause error", tc)
}
}
// These should succeed
for _, tc := range []struct {
input string
want uint64
}{
{`"0"`, 0},
{`"9223372036854775807"`, math.MaxInt64},
{`"18446744073709551615"`, math.MaxUint64},
} {
have := new(Decimal)
if err := have.UnmarshalJSON([]byte(tc.input)); err != nil {
t.Errorf("input %q triggered error: %v", tc.input, err)
}
if uint64(*have) != tc.want {
t.Errorf("input %q, have %d want %d", tc.input, *have, tc.want)
}
}
}

Loading…
Cancel
Save