diff options
Diffstat (limited to 'rlp')
-rw-r--r-- | rlp/decode.go | 59 | ||||
-rw-r--r-- | rlp/decode_test.go | 38 | ||||
-rw-r--r-- | rlp/doc.go | 10 | ||||
-rw-r--r-- | rlp/encode.go | 21 | ||||
-rw-r--r-- | rlp/encode_test.go | 14 | ||||
-rw-r--r-- | rlp/encoder_example_test.go | 10 | ||||
-rw-r--r-- | rlp/typecache.go | 10 |
7 files changed, 117 insertions, 45 deletions
diff --git a/rlp/decode.go b/rlp/decode.go index 4462d4be4..1381f5274 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp @@ -110,9 +110,17 @@ func Decode(r io.Reader, val interface{}) error { // DecodeBytes parses RLP data from b into val. // Please see the documentation of Decode for the decoding rules. +// The input must contain exactly one value and no trailing data. func DecodeBytes(b []byte, val interface{}) error { // TODO: this could use a Stream from a pool. - return NewStream(bytes.NewReader(b), uint64(len(b))).Decode(val) + r := bytes.NewReader(b) + if err := NewStream(r, uint64(len(b))).Decode(val); err != nil { + return err + } + if r.Len() > 0 { + return ErrMoreThanOneValue + } + return nil } type decodeError struct { @@ -175,6 +183,8 @@ func makeDecoder(typ reflect.Type, tags tags) (dec decoder, err error) { return decodeBigIntNoPtr, nil case isUint(kind): return decodeUint, nil + case kind == reflect.Bool: + return decodeBool, nil case kind == reflect.String: return decodeString, nil case kind == reflect.Slice || kind == reflect.Array: @@ -203,6 +213,15 @@ func decodeUint(s *Stream, val reflect.Value) error { return nil } +func decodeBool(s *Stream, val reflect.Value) error { + b, err := s.Bool() + if err != nil { + return wrapStreamError(err, val.Type()) + } + val.SetBool(b) + return nil +} + func decodeString(s *Stream, val reflect.Value) error { b, err := s.Bytes() if err != nil { @@ -353,7 +372,7 @@ func decodeByteArray(s *Stream, val reflect.Value) error { return err } // Reject cases where single byte encoding should have been used. - if size == 1 && slice[0] < 56 { + if size == 1 && slice[0] < 128 { return wrapStreamError(ErrCanonSize, val.Type()) } case List: @@ -517,6 +536,10 @@ var ( ErrElemTooLarge = errors.New("rlp: element is larger than containing list") ErrValueTooLarge = errors.New("rlp: value size exceeds available input length") + // This error is reported by DecodeBytes if the slice contains + // additional data after the first RLP value. + ErrMoreThanOneValue = errors.New("rlp: input contains more than one value") + // internal errors errNotInList = errors.New("rlp: call of ListEnd outside of any list") errNotAtEOL = errors.New("rlp: call of ListEnd not positioned at EOL") @@ -611,7 +634,7 @@ func (s *Stream) Bytes() ([]byte, error) { if err = s.readFull(b); err != nil { return nil, err } - if size == 1 && b[0] < 56 { + if size == 1 && b[0] < 128 { return nil, ErrCanonSize } return b, nil @@ -675,7 +698,7 @@ func (s *Stream) uint(maxbits int) (uint64, error) { return 0, ErrCanonInt case err != nil: return 0, err - case size > 0 && v < 56: + case size > 0 && v < 128: return 0, ErrCanonSize default: return v, nil @@ -685,6 +708,24 @@ func (s *Stream) uint(maxbits int) (uint64, error) { } } +// Bool reads an RLP string of up to 1 byte and returns its contents +// as an boolean. If the input does not contain an RLP string, the +// returned error will be ErrExpectedString. +func (s *Stream) Bool() (bool, error) { + num, err := s.uint(8) + if err != nil { + return false, err + } + switch num { + case 0: + return false, nil + case 1: + return true, nil + default: + return false, fmt.Errorf("rlp: invalid boolean value: %d", num) + } +} + // List starts decoding an RLP list. If the input does not contain a // list, the returned error will be ErrExpectedList. When the list's // end has been reached, any Stream operation will return EOL. diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 71dacaba4..d6b0611dd 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -1,24 +1,25 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp import ( "bytes" "encoding/hex" + "errors" "fmt" "io" "math/big" @@ -113,12 +114,19 @@ func TestStreamErrors(t *testing.T) { {"00", calls{"Uint"}, nil, ErrCanonInt}, {"820002", calls{"Uint"}, nil, ErrCanonInt}, {"8133", calls{"Uint"}, nil, ErrCanonSize}, - {"8156", calls{"Uint"}, nil, nil}, + {"817F", calls{"Uint"}, nil, ErrCanonSize}, + {"8180", calls{"Uint"}, nil, nil}, + + // Non-valid boolean + {"02", calls{"Bool"}, nil, errors.New("rlp: invalid boolean value: 2")}, // Size tags must use the smallest possible encoding. // Leading zero bytes in the size tag are also rejected. {"8100", calls{"Uint"}, nil, ErrCanonSize}, {"8100", calls{"Bytes"}, nil, ErrCanonSize}, + {"8101", calls{"Bytes"}, nil, ErrCanonSize}, + {"817F", calls{"Bytes"}, nil, ErrCanonSize}, + {"8180", calls{"Bytes"}, nil, nil}, {"B800", calls{"Kind"}, withoutInputLimit, ErrCanonSize}, {"B90000", calls{"Kind"}, withoutInputLimit, ErrCanonSize}, {"B90055", calls{"Kind"}, withoutInputLimit, ErrCanonSize}, @@ -132,11 +140,11 @@ func TestStreamErrors(t *testing.T) { {"", calls{"Kind"}, nil, io.EOF}, {"", calls{"Uint"}, nil, io.EOF}, {"", calls{"List"}, nil, io.EOF}, - {"8158", calls{"Uint", "Uint"}, nil, io.EOF}, + {"8180", calls{"Uint", "Uint"}, nil, io.EOF}, {"C0", calls{"List", "ListEnd", "List"}, nil, io.EOF}, {"", calls{"List"}, withoutInputLimit, io.EOF}, - {"8158", calls{"Uint", "Uint"}, withoutInputLimit, io.EOF}, + {"8180", calls{"Uint", "Uint"}, withoutInputLimit, io.EOF}, {"C0", calls{"List", "ListEnd", "List"}, withoutInputLimit, io.EOF}, // Input limit errors. @@ -153,11 +161,11 @@ func TestStreamErrors(t *testing.T) { // down toward zero in Stream.remaining, reading too far can overflow // remaining to a large value, effectively disabling the limit. {"C40102030401", calls{"Raw", "Uint"}, withCustomInputLimit(5), io.EOF}, - {"C4010203048158", calls{"Raw", "Uint"}, withCustomInputLimit(6), ErrValueTooLarge}, + {"C4010203048180", calls{"Raw", "Uint"}, withCustomInputLimit(6), ErrValueTooLarge}, // Check that the same calls are fine without a limit. {"C40102030401", calls{"Raw", "Uint"}, withoutInputLimit, nil}, - {"C4010203048158", calls{"Raw", "Uint"}, withoutInputLimit, nil}, + {"C4010203048180", calls{"Raw", "Uint"}, withoutInputLimit, nil}, // Unexpected EOF. This only happens when there is // no input limit, so the reader needs to be 'dumbed down'. @@ -311,6 +319,11 @@ var ( ) var decodeTests = []decodeTest{ + // booleans + {input: "01", ptr: new(bool), value: true}, + {input: "80", ptr: new(bool), value: false}, + {input: "02", ptr: new(bool), error: "rlp: invalid boolean value: 2"}, + // integers {input: "05", ptr: new(uint32), value: uint32(5)}, {input: "80", ptr: new(uint32), value: uint32(0)}, @@ -349,6 +362,7 @@ var decodeTests = []decodeTest{ // byte arrays {input: "02", ptr: new([1]byte), value: [1]byte{2}}, + {input: "8180", ptr: new([1]byte), value: [1]byte{128}}, {input: "850102030405", ptr: new([5]byte), value: [5]byte{1, 2, 3, 4, 5}}, // byte array errors @@ -359,6 +373,7 @@ var decodeTests = []decodeTest{ {input: "C3010203", ptr: new([5]byte), error: "rlp: expected input string or byte for [5]uint8"}, {input: "86010203040506", ptr: new([5]byte), error: "rlp: input string too long for [5]uint8"}, {input: "8105", ptr: new([1]byte), error: "rlp: non-canonical size information for [1]uint8"}, + {input: "817F", ptr: new([1]byte), error: "rlp: non-canonical size information for [1]uint8"}, // zero sized byte arrays {input: "80", ptr: new([0]byte), value: [0]byte{}}, @@ -427,7 +442,8 @@ var decodeTests = []decodeTest{ {input: "80", ptr: new(*uint), value: uintp(0)}, {input: "C0", ptr: new(*uint), error: "rlp: expected input string or byte for uint"}, {input: "07", ptr: new(*uint), value: uintp(7)}, - {input: "8158", ptr: new(*uint), value: uintp(0x58)}, + {input: "817F", ptr: new(*uint), error: "rlp: non-canonical size information for uint"}, + {input: "8180", ptr: new(*uint), value: uintp(0x80)}, {input: "C109", ptr: new(*[]uint), value: &[]uint{9}}, {input: "C58403030303", ptr: new(*[][]byte), value: &[][]byte{{3, 3, 3, 3}}}, diff --git a/rlp/doc.go b/rlp/doc.go index e274b104e..72667416c 100644 --- a/rlp/doc.go +++ b/rlp/doc.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. /* Package rlp implements the RLP serialization format. diff --git a/rlp/encode.go b/rlp/encode.go index 1fef36078..b525ae4e7 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp @@ -361,6 +361,8 @@ func makeWriter(typ reflect.Type) (writer, error) { return writeBigIntNoPtr, nil case isUint(kind): return writeUint, nil + case kind == reflect.Bool: + return writeBool, nil case kind == reflect.String: return writeString, nil case kind == reflect.Slice && isByte(typ.Elem()): @@ -398,6 +400,15 @@ func writeUint(val reflect.Value, w *encbuf) error { return nil } +func writeBool(val reflect.Value, w *encbuf) error { + if val.Bool() { + w.str = append(w.str, 0x01) + } else { + w.str = append(w.str, 0x80) + } + return nil +} + func writeBigIntPtr(val reflect.Value, w *encbuf) error { ptr := val.Interface().(*big.Int) if ptr == nil { diff --git a/rlp/encode_test.go b/rlp/encode_test.go index ce32c942b..60bd95692 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp @@ -71,6 +71,10 @@ type encTest struct { } var encTests = []encTest{ + // booleans + {val: true, output: "01"}, + {val: false, output: "80"}, + // integers {val: uint32(0), output: "80"}, {val: uint32(127), output: "7F"}, diff --git a/rlp/encoder_example_test.go b/rlp/encoder_example_test.go index e1473ec8b..1cffa241c 100644 --- a/rlp/encoder_example_test.go +++ b/rlp/encoder_example_test.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp diff --git a/rlp/typecache.go b/rlp/typecache.go index 2abbf9f9e..0ab096695 100644 --- a/rlp/typecache.go +++ b/rlp/typecache.go @@ -1,18 +1,18 @@ // Copyright 2014 The go-ethereum Authors -// This file is part of go-ethereum. +// This file is part of the go-ethereum library. // -// go-ethereum is free software: you can redistribute it and/or modify +// The go-ethereum library is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // -// go-ethereum is distributed in the hope that it will be useful, +// The go-ethereum library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. package rlp |