From 181a21c67c8dafe027cd7fb43fe3f68eaf2a52ea Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Wed, 25 Mar 2015 16:46:29 +0100 Subject: [PATCH] rlp: encode nil array pointers as empty list or string --- rlp/encode.go | 34 ++++++++++++++++++++++++++-------- rlp/encode_test.go | 2 ++ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/rlp/encode.go b/rlp/encode.go index 289bc4eaa..6cf6776d6 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -87,6 +87,8 @@ func (e flatenc) EncodeRLP(out io.Writer) error { // To encode a pointer, the value being pointed to is encoded. For nil // pointers, Encode will encode the zero value of the type. A nil // pointer to a struct type always encodes as an empty RLP list. +// A nil pointer to an array encodes as an empty list (or empty string +// if the array has element type byte). // // Struct values are encoded as an RLP list of all their encoded // public fields. Recursive struct types are supported. @@ -532,21 +534,37 @@ func makePtrWriter(typ reflect.Type) (writer, error) { if err != nil { return nil, err } - zero := reflect.Zero(typ.Elem()) + + // determine nil pointer handler + var nilfunc func(*encbuf) error kind := typ.Elem().Kind() - writer := func(val reflect.Value, w *encbuf) error { - switch { - case !val.IsNil(): - return etypeinfo.writer(val.Elem(), w) - case kind == reflect.Struct: - // encoding the zero value of a struct could trigger + switch { + case kind == reflect.Array && isByte(typ.Elem().Elem()): + nilfunc = func(w *encbuf) error { + w.str = append(w.str, 0x80) + return nil + } + case kind == reflect.Struct || kind == reflect.Array: + nilfunc = func(w *encbuf) error { + // encoding the zero value of a struct/array could trigger // infinite recursion, avoid that. w.listEnd(w.list()) return nil - default: + } + default: + zero := reflect.Zero(typ.Elem()) + nilfunc = func(w *encbuf) error { return etypeinfo.writer(zero, w) } } + + writer := func(val reflect.Value, w *encbuf) error { + if val.IsNil() { + return nilfunc(w) + } else { + return etypeinfo.writer(val.Elem(), w) + } + } return writer, err } diff --git a/rlp/encode_test.go b/rlp/encode_test.go index 611514bda..6eb930d6c 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -202,8 +202,10 @@ var encTests = []encTest{ {val: (*uint)(nil), output: "80"}, {val: (*string)(nil), output: "80"}, {val: (*[]byte)(nil), output: "80"}, + {val: (*[10]byte)(nil), output: "80"}, {val: (*big.Int)(nil), output: "80"}, {val: (*[]string)(nil), output: "C0"}, + {val: (*[10]string)(nil), output: "C0"}, {val: (*[]interface{})(nil), output: "C0"}, {val: (*[]struct{ uint })(nil), output: "C0"}, {val: (*interface{})(nil), output: "C0"},