From 8c3095faf03fb6c8138e6b8691df49be4a6fffae Mon Sep 17 00:00:00 2001
From: Felix Lange <fjl@twurst.com>
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"},
 	{
-- 
GitLab