From ac32f52ca6e620556e7a875f0d52ddef72215532 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 3 Sep 2015 01:37:00 +0200 Subject: rlp: fix encReader returning nil buffers to the pool The bug can cause crashes if Read is called after EOF has been returned. No code performs such calls right now, but hitting the bug gets more likely as rlp.EncodeToReader gets used in more places. --- rlp/encode.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'rlp/encode.go') diff --git a/rlp/encode.go b/rlp/encode.go index b525ae4e7..a0531af01 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -90,8 +90,8 @@ func Encode(w io.Writer, val interface{}) error { return outer.encode(val) } eb := encbufPool.Get().(*encbuf) - eb.reset() defer encbufPool.Put(eb) + eb.reset() if err := eb.encode(val); err != nil { return err } @@ -102,8 +102,8 @@ func Encode(w io.Writer, val interface{}) error { // Please see the documentation of Encode for the encoding rules. func EncodeToBytes(val interface{}) ([]byte, error) { eb := encbufPool.Get().(*encbuf) - eb.reset() defer encbufPool.Put(eb) + eb.reset() if err := eb.encode(val); err != nil { return nil, err } @@ -288,8 +288,13 @@ type encReader struct { func (r *encReader) Read(b []byte) (n int, err error) { for { if r.piece = r.next(); r.piece == nil { - encbufPool.Put(r.buf) - r.buf = nil + // Put the encode buffer back into the pool at EOF when it + // is first encountered. Subsequent calls still return EOF + // as the error but the buffer is no longer valid. + if r.buf != nil { + encbufPool.Put(r.buf) + r.buf = nil + } return n, io.EOF } nn := copy(b[n:], r.piece) -- cgit v1.2.3 From 24bb68e7cf546153436f1d38a7227fdf75d73343 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 9 Sep 2015 03:34:15 +0200 Subject: rlp: add RawValue --- rlp/encode.go | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'rlp/encode.go') diff --git a/rlp/encode.go b/rlp/encode.go index a0531af01..2aeee4721 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -354,6 +354,8 @@ var ( func makeWriter(typ reflect.Type) (writer, error) { kind := typ.Kind() switch { + case typ == rawValueType: + return writeRawValue, nil case typ.Implements(encoderInterface): return writeEncoder, nil case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface): @@ -389,6 +391,11 @@ func isByte(typ reflect.Type) bool { return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) } +func writeRawValue(val reflect.Value, w *encbuf) error { + w.str = append(w.str, val.Bytes()...) + return nil +} + func writeUint(val reflect.Value, w *encbuf) error { i := val.Uint() if i == 0 { -- cgit v1.2.3 From fc8b246109760714a838f4be163cca1dbb998163 Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Thu, 10 Sep 2015 14:48:19 +0200 Subject: rlp: move ListSize to raw.go --- rlp/encode.go | 6 ------ 1 file changed, 6 deletions(-) (limited to 'rlp/encode.go') diff --git a/rlp/encode.go b/rlp/encode.go index 2aeee4721..d73b17c28 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -45,12 +45,6 @@ type Encoder interface { EncodeRLP(io.Writer) error } -// ListSize returns the encoded size of an RLP list with the given -// content size. -func ListSize(contentSize uint64) uint64 { - return uint64(headsize(contentSize)) + contentSize -} - // Encode writes the RLP encoding of val to w. Note that Encode may // perform many small writes in some cases. Consider making w // buffered. -- cgit v1.2.3