diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-03-26 00:00:25 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-03-26 00:00:25 +0800 |
commit | 65ea55bccd8afb94bed540c89e9ce77acbfa3b31 (patch) | |
tree | 3c38cb00b62e8d1c68edab40b013f7972e4f5723 | |
parent | ff5578fc715262cd8ae62e7d0f961a6e977a8727 (diff) | |
parent | 181a21c67c8dafe027cd7fb43fe3f68eaf2a52ea (diff) | |
download | dexon-65ea55bccd8afb94bed540c89e9ce77acbfa3b31.tar.gz dexon-65ea55bccd8afb94bed540c89e9ce77acbfa3b31.tar.zst dexon-65ea55bccd8afb94bed540c89e9ce77acbfa3b31.zip |
Merge pull request #564 from fjl/rlp-nil-array
rlp: encode nil array pointers as empty list or string
-rw-r--r-- | rlp/encode.go | 34 | ||||
-rw-r--r-- | 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"}, |