diff --git a/rlp/decode.go b/rlp/decode.go index 0fde0a9473..3b5617475b 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -99,6 +99,8 @@ func (err *decodeError) Error() string { func wrapStreamError(err error, typ reflect.Type) error { switch err { + case ErrCanonInt: + return &decodeError{msg: "canon int error appends zero's", typ: typ} case ErrExpectedList: return &decodeError{msg: "expected input list", typ: typ} case ErrExpectedString: @@ -184,6 +186,12 @@ func decodeBigInt(s *Stream, val reflect.Value) error { i = new(big.Int) val.Set(reflect.ValueOf(i)) } + + // Reject big integers which are zero appended + if len(b) > 0 && b[0] == 0 { + return wrapStreamError(ErrCanonInt, val.Type()) + } + i.SetBytes(b) return nil } @@ -460,6 +468,7 @@ var ( // Other errors ErrExpectedString = errors.New("rlp: expected String or Byte") ErrExpectedList = errors.New("rlp: expected List") + ErrCanonInt = errors.New("rlp: expected Int") ErrElemTooLarge = errors.New("rlp: element is larger than containing list") // internal errors diff --git a/rlp/decode_test.go b/rlp/decode_test.go index a18ff1d080..73a31c67f5 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -312,6 +312,7 @@ var decodeTests = []decodeTest{ // big ints {input: "01", ptr: new(*big.Int), value: big.NewInt(1)}, {input: "89FFFFFFFFFFFFFFFFFF", ptr: new(*big.Int), value: veryBigInt}, + {input: "820001", ptr: new(big.Int), error: "rlp: canon int error appends zero's for *big.Int"}, {input: "10", ptr: new(big.Int), value: *big.NewInt(16)}, // non-pointer also works {input: "C0", ptr: new(*big.Int), error: "rlp: expected input string or byte for *big.Int"},