common/hexutil: reject big integer inputs > 256 bits

This follows the change to common/math big integer parsing in PR #3699.
This commit is contained in:
Felix Lange 2017-02-22 17:35:11 +01:00
parent c52ab932e6
commit f3b7dcc5bd
4 changed files with 30 additions and 3 deletions

View File

@ -49,6 +49,7 @@ var (
ErrOddLength = errors.New("hex string has odd length") ErrOddLength = errors.New("hex string has odd length")
ErrUint64Range = errors.New("hex number does not fit into 64 bits") ErrUint64Range = errors.New("hex number does not fit into 64 bits")
ErrUintRange = fmt.Errorf("hex number does not fit into %d bits", uintBits) ErrUintRange = fmt.Errorf("hex number does not fit into %d bits", uintBits)
ErrBig256Range = errors.New("hex number does not fit into 256 bits")
) )
// Decode decodes a hex string with 0x prefix. // Decode decodes a hex string with 0x prefix.
@ -126,11 +127,15 @@ func init() {
} }
// DecodeBig decodes a hex string with 0x prefix as a quantity. // DecodeBig decodes a hex string with 0x prefix as a quantity.
// Numbers larger than 256 bits are not accepted.
func DecodeBig(input string) (*big.Int, error) { func DecodeBig(input string) (*big.Int, error) {
raw, err := checkNumber(input) raw, err := checkNumber(input)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(raw) > 64 {
return nil, ErrBig256Range
}
words := make([]big.Word, len(raw)/bigWordNibbles+1) words := make([]big.Word, len(raw)/bigWordNibbles+1)
end := len(raw) end := len(raw)
for i := range words { for i := range words {

View File

@ -83,6 +83,10 @@ var (
{input: `0x01`, wantErr: ErrLeadingZero}, {input: `0x01`, wantErr: ErrLeadingZero},
{input: `0xx`, wantErr: ErrSyntax}, {input: `0xx`, wantErr: ErrSyntax},
{input: `0x1zz01`, wantErr: ErrSyntax}, {input: `0x1zz01`, wantErr: ErrSyntax},
{
input: `0x10000000000000000000000000000000000000000000000000000000000000000`,
wantErr: ErrBig256Range,
},
// valid // valid
{input: `0x0`, want: big.NewInt(0)}, {input: `0x0`, want: big.NewInt(0)},
{input: `0x2`, want: big.NewInt(0x2)}, {input: `0x2`, want: big.NewInt(0x2)},
@ -99,6 +103,10 @@ var (
input: `0xffffffffffffffffffffffffffffffffffff`, input: `0xffffffffffffffffffffffffffffffffffff`,
want: referenceBig("ffffffffffffffffffffffffffffffffffff"), want: referenceBig("ffffffffffffffffffffffffffffffffffff"),
}, },
{
input: `0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`,
want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
},
} }
decodeUint64Tests = []unmarshalTest{ decodeUint64Tests = []unmarshalTest{

View File

@ -91,9 +91,12 @@ func UnmarshalJSON(typname string, input, out []byte) error {
return nil return nil
} }
// Big marshals/unmarshals as a JSON string with 0x prefix. The zero value marshals as // Big marshals/unmarshals as a JSON string with 0x prefix.
// "0x0". Negative integers are not supported at this time. Attempting to marshal them // The zero value marshals as "0x0".
// will return an error. //
// Negative integers are not supported at this time. Attempting to marshal them will
// return an error. Values larger than 256bits are rejected by Unmarshal but will be
// marshaled without error.
type Big big.Int type Big big.Int
// MarshalJSON implements json.Marshaler. // MarshalJSON implements json.Marshaler.
@ -119,6 +122,9 @@ func (b *Big) UnmarshalJSON(input []byte) error {
if err != nil { if err != nil {
return err return err
} }
if len(raw) > 64 {
return ErrBig256Range
}
words := make([]big.Word, len(raw)/bigWordNibbles+1) words := make([]big.Word, len(raw)/bigWordNibbles+1)
end := len(raw) end := len(raw)
for i := range words { for i := range words {

View File

@ -130,6 +130,10 @@ var unmarshalBigTests = []unmarshalTest{
{input: `"0x01"`, wantErr: ErrLeadingZero}, {input: `"0x01"`, wantErr: ErrLeadingZero},
{input: `"0xx"`, wantErr: ErrSyntax}, {input: `"0xx"`, wantErr: ErrSyntax},
{input: `"0x1zz01"`, wantErr: ErrSyntax}, {input: `"0x1zz01"`, wantErr: ErrSyntax},
{
input: `"0x10000000000000000000000000000000000000000000000000000000000000000"`,
wantErr: ErrBig256Range,
},
// valid encoding // valid encoding
{input: `""`, want: big.NewInt(0)}, {input: `""`, want: big.NewInt(0)},
@ -148,6 +152,10 @@ var unmarshalBigTests = []unmarshalTest{
input: `"0xffffffffffffffffffffffffffffffffffff"`, input: `"0xffffffffffffffffffffffffffffffffffff"`,
want: referenceBig("ffffffffffffffffffffffffffffffffffff"), want: referenceBig("ffffffffffffffffffffffffffffffffffff"),
}, },
{
input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`,
want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
},
} }
func TestUnmarshalBig(t *testing.T) { func TestUnmarshalBig(t *testing.T) {