]> Sergey Matveev's repositories - btrtrc.git/commitdiff
bencode: Encode arrays of bytes as strings
authorMatt Joiner <anacrolix@gmail.com>
Thu, 28 Oct 2021 05:21:23 +0000 (16:21 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 28 Oct 2021 05:21:23 +0000 (16:21 +1100)
This looks appropriate with the use of byte arrays in DHT for BEP44.

bencode/encode.go
bencode/encode_test.go

index 4c7c860254bb8e72dc4e066f34908137c8d0ace5..3f6c4bb42c8cb337ba7727a93daf904fa8438c31 100644 (file)
@@ -162,22 +162,9 @@ func (e *Encoder) reflectValue(v reflect.Value) {
                }
                e.writeString("e")
        case reflect.Slice:
-               if v.Type().Elem().Kind() == reflect.Uint8 {
-                       s := v.Bytes()
-                       e.reflectByteSlice(s)
-                       break
-               }
-               if v.IsNil() {
-                       e.writeString("le")
-                       break
-               }
-               fallthrough
+               e.reflectSlice(v)
        case reflect.Array:
-               e.writeString("l")
-               for i, n := 0, v.Len(); i < n; i++ {
-                       e.reflectValue(v.Index(i))
-               }
-               e.writeString("e")
+               e.reflectSlice(v.Slice(0, v.Len()))
        case reflect.Interface:
                e.reflectValue(v.Elem())
        case reflect.Ptr:
@@ -192,6 +179,26 @@ func (e *Encoder) reflectValue(v reflect.Value) {
        }
 }
 
+func (e *Encoder) reflectSlice(v reflect.Value) {
+       if v.Type().Elem().Kind() == reflect.Uint8 {
+               // This can panic if v is not addressable, such as by passing an array of bytes by value. We
+               // could copy them and make a slice to the copy, or the user could just avoid doing this. It
+               // remains to be seen.
+               s := v.Bytes()
+               e.reflectByteSlice(s)
+               return
+       }
+       if v.IsNil() {
+               e.writeString("le")
+               return
+       }
+       e.writeString("l")
+       for i, n := 0, v.Len(); i < n; i++ {
+               e.reflectValue(v.Index(i))
+       }
+       e.writeString("e")
+}
+
 type encodeField struct {
        i         func(v reflect.Value) reflect.Value
        tag       string
index 7fc3234ad48c4da9c40d138487032efc324cf4b9..b0fabc45b4947a2ea4524b5be94950acf20e2eae 100644 (file)
@@ -50,7 +50,7 @@ var random_encode_tests = []random_encode_test{
        {random_struct{123, "nono", "hello"}, "d3:CDE5:hello3:abci123ee"},
        {map[string]string{"a": "b", "c": "d"}, "d1:a1:b1:c1:de"},
        {[]byte{1, 2, 3, 4}, "4:\x01\x02\x03\x04"},
-       {[4]byte{1, 2, 3, 4}, "li1ei2ei3ei4ee"},
+       {&[4]byte{1, 2, 3, 4}, "4:\x01\x02\x03\x04"},
        {nil, ""},
        {[]byte{}, "0:"},
        {[]byte(nil), "0:"},