diff options
author | Felix Lange <fjl@twurst.com> | 2015-04-16 16:15:14 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2015-04-17 20:45:09 +0800 |
commit | 1e2c93aa2da453ef9548b9957b5ed453f60ce5ca (patch) | |
tree | ed49cd3774448122fdc5ceac49eb800139cf0c55 /rlp/decode.go | |
parent | 6e9f8035a1a49ac096bc2eae6ec4637b48e29048 (diff) | |
download | dexon-1e2c93aa2da453ef9548b9957b5ed453f60ce5ca.tar.gz dexon-1e2c93aa2da453ef9548b9957b5ed453f60ce5ca.tar.zst dexon-1e2c93aa2da453ef9548b9957b5ed453f60ce5ca.zip |
rlp: reject non-minimal input strings
Input strings of length 1 containing a byte < 56 are non-minimal and
should be encoded as a single byte instead. Reject such strings.
Diffstat (limited to 'rlp/decode.go')
-rw-r--r-- | rlp/decode.go | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/rlp/decode.go b/rlp/decode.go index 6bd13aa8f..43dd716b5 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -305,10 +305,11 @@ func decodeByteSlice(s *Stream, val reflect.Value) error { return decodeListSlice(s, val, decodeUint) } b, err := s.Bytes() - if err == nil { - val.SetBytes(b) + if err != nil { + return wrapStreamError(err, val.Type()) } - return err + val.SetBytes(b) + return nil } func decodeByteArray(s *Stream, val reflect.Value) error { @@ -333,6 +334,10 @@ func decodeByteArray(s *Stream, val reflect.Value) error { return err } zero(val, int(size)) + // Reject cases where single byte encoding should have been used. + if size == 1 && slice[0] < 56 { + return wrapStreamError(ErrCanonSize, val.Type()) + } case List: return decodeListArray(s, val, decodeUint) } @@ -477,7 +482,7 @@ var ( // Actual Errors ErrExpectedString = errors.New("rlp: expected String or Byte") ErrExpectedList = errors.New("rlp: expected List") - ErrCanonInt = errors.New("rlp: non-canonical (leading zero bytes) integer") + ErrCanonInt = errors.New("rlp: non-canonical integer format") ErrCanonSize = errors.New("rlp: non-canonical size information") ErrElemTooLarge = errors.New("rlp: element is larger than containing list") ErrValueTooLarge = errors.New("rlp: value size exceeds available input length") @@ -576,6 +581,9 @@ func (s *Stream) Bytes() ([]byte, error) { if err = s.readFull(b); err != nil { return nil, err } + if size == 1 && b[0] < 56 { + return nil, ErrCanonSize + } return b, nil default: return nil, ErrExpectedString @@ -631,11 +639,17 @@ func (s *Stream) uint(maxbits int) (uint64, error) { return 0, errUintOverflow } v, err := s.readUint(byte(size)) - if err == ErrCanonSize { + switch { + case err == ErrCanonSize: // Adjust error because we're not reading a size right now. - err = ErrCanonInt + return 0, ErrCanonInt + case err != nil: + return 0, err + case size > 0 && v < 56: + return 0, ErrCanonSize + default: + return v, nil } - return v, err default: return 0, ErrExpectedString } |