From 4b5203851a782bdd7d30d9491b38d26834f9068a Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Tue, 13 Feb 2018 00:44:05 +1100
Subject: [PATCH] bencode: Support unmarshalling strings into slices of kind
 Uint8

---
 bencode/decode.go      |  4 +---
 bencode/decode_test.go | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/bencode/decode.go b/bencode/decode.go
index 074db675..b07ae580 100644
--- a/bencode/decode.go
+++ b/bencode/decode.go
@@ -171,9 +171,7 @@ func (d *Decoder) parseString(v reflect.Value) error {
 				Type:  v.Type(),
 			})
 		}
-		sl := make([]byte, len(d.buf.Bytes()))
-		copy(sl, d.buf.Bytes())
-		v.Set(reflect.ValueOf(sl))
+		v.SetBytes(append([]byte(nil), d.buf.Bytes()...))
 	default:
 		return &UnmarshalTypeError{
 			Value: "string",
diff --git a/bencode/decode_test.go b/bencode/decode_test.go
index fa5212b9..7366102d 100644
--- a/bencode/decode_test.go
+++ b/bencode/decode_test.go
@@ -147,3 +147,23 @@ func TestIgnoreUnmarshalTypeError(t *testing.T) {
 	require.Nil(t, Unmarshal([]byte("d6:Ignorei42ee"), &s))
 	assert.EqualValues(t, 42, s.Ignore)
 }
+
+// Test unmarshalling []byte into something that has the same kind but
+// different type.
+func TestDecodeCustomSlice(t *testing.T) {
+	type flag byte
+	var fs3, fs2 []flag
+	// We do a longer slice then a shorter slice to see if the buffers are
+	// shared.
+	d := NewDecoder(bytes.NewBufferString("3:\x01\x10\xff2:\x04\x0f"))
+	require.NoError(t, d.Decode(&fs3))
+	require.NoError(t, d.Decode(&fs2))
+	assert.EqualValues(t, []flag{1, 16, 255}, fs3)
+	assert.EqualValues(t, []flag{4, 15}, fs2)
+}
+
+func TestUnmarshalUnusedBytes(t *testing.T) {
+	var i int
+	require.EqualValues(t, ErrUnusedTrailingBytes{1}, Unmarshal([]byte("i42ee"), &i))
+	assert.EqualValues(t, 42, i)
+}
-- 
2.51.0