Skip to content

Commit

Permalink
graphql/uint: Fix unmarshalling of negative numbers
Browse files Browse the repository at this point in the history
Converting a negative number to uint directly returns a really big number. For
example,

	v := -5
	fmt.Println(uint(v)) // 18446744073709551611

So we should handle this cases explicitly and return an error.
  • Loading branch information
mnPanic committed Feb 8, 2024
1 parent e223f1d commit 74c910c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
25 changes: 25 additions & 0 deletions graphql/uint.go
Expand Up @@ -2,6 +2,7 @@ package graphql

import (
"encoding/json"
"errors"
"fmt"
"io"
"strconv"
Expand All @@ -19,8 +20,16 @@ func UnmarshalUint(v interface{}) (uint, error) {
u64, err := strconv.ParseUint(v, 10, 64)
return uint(u64), err
case int:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint")
}

return uint(v), nil
case int64:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint")
}

return uint(v), nil
case json.Number:
u64, err := strconv.ParseUint(string(v), 10, 64)
Expand All @@ -41,8 +50,16 @@ func UnmarshalUint64(v interface{}) (uint64, error) {
case string:
return strconv.ParseUint(v, 10, 64)
case int:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint64")
}

return uint64(v), nil
case int64:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint64")
}

return uint64(v), nil
case json.Number:
return strconv.ParseUint(string(v), 10, 64)
Expand All @@ -66,8 +83,16 @@ func UnmarshalUint32(v interface{}) (uint32, error) {
}
return uint32(iv), nil
case int:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint32")
}

return uint32(v), nil
case int64:
if v < 0 {
return 0, errors.New("cannot convert negative numbers to uint32")
}

return uint32(v), nil
case json.Number:
iv, err := strconv.ParseUint(string(v), 10, 32)
Expand Down
15 changes: 15 additions & 0 deletions graphql/uint_test.go
Expand Up @@ -19,6 +19,11 @@ func TestUint(t *testing.T) {
assert.Equal(t, uint(123), mustUnmarshalUint(json.Number("123")))
assert.Equal(t, uint(123), mustUnmarshalUint("123"))
})

t.Run("can't unmarshal negative numbers", func(t *testing.T) {
_, err := UnmarshalUint(-123)
assert.EqualError(t, err, "cannot convert negative numbers to uint")
})
}

func mustUnmarshalUint(v interface{}) uint {
Expand All @@ -42,6 +47,11 @@ func TestUint32(t *testing.T) {
assert.Equal(t, uint32(123), mustUnmarshalUint32("123"))
assert.Equal(t, uint32(4294967295), mustUnmarshalUint32("4294967295"))
})

t.Run("can't unmarshal negative numbers", func(t *testing.T) {
_, err := UnmarshalUint32(-123)
assert.EqualError(t, err, "cannot convert negative numbers to uint32")
})
}

func mustUnmarshalUint32(v interface{}) uint32 {
Expand All @@ -63,6 +73,11 @@ func TestUint64(t *testing.T) {
assert.Equal(t, uint64(123), mustUnmarshalUint64(json.Number("123")))
assert.Equal(t, uint64(123), mustUnmarshalUint64("123"))
})

t.Run("can't unmarshal negative numbers", func(t *testing.T) {
_, err := UnmarshalUint64(-123)
assert.EqualError(t, err, "cannot convert negative numbers to uint64")
})
}

func mustUnmarshalUint64(v interface{}) uint64 {
Expand Down

0 comments on commit 74c910c

Please sign in to comment.