From: Matt Joiner Date: Thu, 28 Oct 2021 05:21:23 +0000 (+1100) Subject: bencode: Encode arrays of bytes as strings X-Git-Tag: v1.35.0~12 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=446016cb270c35038387d9447cc4f80f8012ba1d;p=btrtrc.git bencode: Encode arrays of bytes as strings This looks appropriate with the use of byte arrays in DHT for BEP44. --- diff --git a/bencode/encode.go b/bencode/encode.go index 4c7c8602..3f6c4bb4 100644 --- a/bencode/encode.go +++ b/bencode/encode.go @@ -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 diff --git a/bencode/encode_test.go b/bencode/encode_test.go index 7fc3234a..b0fabc45 100644 --- a/bencode/encode_test.go +++ b/bencode/encode_test.go @@ -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:"},