From f3b7dcc5bdd5b2b02e12133a0d8e16a75844f766 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 22 Feb 2017 17:35:11 +0100 Subject: [PATCH] common/hexutil: reject big integer inputs > 256 bits This follows the change to common/math big integer parsing in PR #3699. --- common/hexutil/hexutil.go | 5 +++++ common/hexutil/hexutil_test.go | 8 ++++++++ common/hexutil/json.go | 12 +++++++++--- common/hexutil/json_test.go | 8 ++++++++ 4 files changed, 30 insertions(+), 3 deletions(-) diff --git a/common/hexutil/hexutil.go b/common/hexutil/hexutil.go index 4ec0ee8e6..16863f6c0 100644 --- a/common/hexutil/hexutil.go +++ b/common/hexutil/hexutil.go @@ -49,6 +49,7 @@ var ( ErrOddLength = errors.New("hex string has odd length") ErrUint64Range = errors.New("hex number does not fit into 64 bits") 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. @@ -126,11 +127,15 @@ func init() { } // 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) { raw, err := checkNumber(input) if err != nil { return nil, err } + if len(raw) > 64 { + return nil, ErrBig256Range + } words := make([]big.Word, len(raw)/bigWordNibbles+1) end := len(raw) for i := range words { diff --git a/common/hexutil/hexutil_test.go b/common/hexutil/hexutil_test.go index 324e9d348..68d8a40e0 100644 --- a/common/hexutil/hexutil_test.go +++ b/common/hexutil/hexutil_test.go @@ -83,6 +83,10 @@ var ( {input: `0x01`, wantErr: ErrLeadingZero}, {input: `0xx`, wantErr: ErrSyntax}, {input: `0x1zz01`, wantErr: ErrSyntax}, + { + input: `0x10000000000000000000000000000000000000000000000000000000000000000`, + wantErr: ErrBig256Range, + }, // valid {input: `0x0`, want: big.NewInt(0)}, {input: `0x2`, want: big.NewInt(0x2)}, @@ -99,6 +103,10 @@ var ( input: `0xffffffffffffffffffffffffffffffffffff`, want: referenceBig("ffffffffffffffffffffffffffffffffffff"), }, + { + input: `0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff`, + want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + }, } decodeUint64Tests = []unmarshalTest{ diff --git a/common/hexutil/json.go b/common/hexutil/json.go index 7e4736dd6..6174d6256 100644 --- a/common/hexutil/json.go +++ b/common/hexutil/json.go @@ -91,9 +91,12 @@ func UnmarshalJSON(typname string, input, out []byte) error { return nil } -// Big marshals/unmarshals as a JSON string with 0x prefix. The zero value marshals as -// "0x0". Negative integers are not supported at this time. Attempting to marshal them -// will return an error. +// Big marshals/unmarshals as a JSON string with 0x prefix. +// The zero value marshals as "0x0". +// +// 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 // MarshalJSON implements json.Marshaler. @@ -119,6 +122,9 @@ func (b *Big) UnmarshalJSON(input []byte) error { if err != nil { return err } + if len(raw) > 64 { + return ErrBig256Range + } words := make([]big.Word, len(raw)/bigWordNibbles+1) end := len(raw) for i := range words { diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index 290bf9ca2..c7fde0adb 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -130,6 +130,10 @@ var unmarshalBigTests = []unmarshalTest{ {input: `"0x01"`, wantErr: ErrLeadingZero}, {input: `"0xx"`, wantErr: ErrSyntax}, {input: `"0x1zz01"`, wantErr: ErrSyntax}, + { + input: `"0x10000000000000000000000000000000000000000000000000000000000000000"`, + wantErr: ErrBig256Range, + }, // valid encoding {input: `""`, want: big.NewInt(0)}, @@ -148,6 +152,10 @@ var unmarshalBigTests = []unmarshalTest{ input: `"0xffffffffffffffffffffffffffffffffffff"`, want: referenceBig("ffffffffffffffffffffffffffffffffffff"), }, + { + input: `"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"`, + want: referenceBig("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), + }, } func TestUnmarshalBig(t *testing.T) {