From 8c3095faf03fb6c8138e6b8691df49be4a6fffae Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 30 Jan 2015 16:52:48 +0100 Subject: [PATCH] rlp: fix encoding of arrays with byte element type --- rlp/encode.go | 22 +++++++++++++++++++++- rlp/encode_test.go | 6 ++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/rlp/encode.go b/rlp/encode.go index d80b66315..b453b5bf4 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -301,8 +301,10 @@ func makeWriter(typ reflect.Type) (writer, error) { return writeUint, nil case kind == reflect.String: return writeString, nil - case kind == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 && !typ.Elem().Implements(encoderInterface): + case kind == reflect.Slice && isByte(typ.Elem()): return writeBytes, nil + case kind == reflect.Array && isByte(typ.Elem()): + return writeByteArray, nil case kind == reflect.Slice || kind == reflect.Array: return makeSliceWriter(typ) case kind == reflect.Struct: @@ -314,6 +316,10 @@ func makeWriter(typ reflect.Type) (writer, error) { } } +func isByte(typ reflect.Type) bool { + return typ.Kind() == reflect.Uint8 && !typ.Implements(encoderInterface) +} + func writeUint(val reflect.Value, w *encbuf) error { i := val.Uint() if i == 0 { @@ -358,6 +364,20 @@ func writeBytes(val reflect.Value, w *encbuf) error { return nil } +func writeByteArray(val reflect.Value, w *encbuf) error { + if !val.CanAddr() { + // Slice requires the value to be addressable. + // Make it addressable by copying. + copy := reflect.New(val.Type()).Elem() + copy.Set(val) + val = copy + } + size := val.Len() + slice := val.Slice(0, size).Bytes() + w.encodeString(slice) + return nil +} + func writeString(val reflect.Value, w *encbuf) error { s := val.String() w.encodeStringHeader(len(s)) diff --git a/rlp/encode_test.go b/rlp/encode_test.go index 18b843737..0309b9258 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -40,6 +40,8 @@ func (e *encodableReader) Read(b []byte) (int, error) { panic("called") } +type namedByteType byte + var ( _ = Encoder(&testEncoder{}) _ = Encoder(byteEncoder(0)) @@ -102,6 +104,10 @@ var encTests = []encTest{ // byte slices, strings {val: []byte{}, output: "80"}, {val: []byte{1, 2, 3}, output: "83010203"}, + + {val: []namedByteType{1, 2, 3}, output: "83010203"}, + {val: [...]namedByteType{1, 2, 3}, output: "83010203"}, + {val: "", output: "80"}, {val: "dog", output: "83646F67"}, {