2
0
mirror of synced 2025-02-23 22:28:11 +00:00

bencode: Fix marshalling of unaddressable array of bytes

This commit is contained in:
Matt Joiner 2021-11-04 20:01:25 +11:00
parent c7ff32f01c
commit 59d5e17ace

View File

@ -64,16 +64,18 @@ func (e *Encoder) writeString(s string) {
} }
func (e *Encoder) reflectString(s string) { func (e *Encoder) reflectString(s string) {
b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10) e.writeStringPrefix(int64(len(s)))
e.write(b)
e.writeString(":")
e.writeString(s) e.writeString(s)
} }
func (e *Encoder) reflectByteSlice(s []byte) { func (e *Encoder) writeStringPrefix(l int64) {
b := strconv.AppendInt(e.scratch[:0], int64(len(s)), 10) b := strconv.AppendInt(e.scratch[:0], l, 10)
e.write(b) e.write(b)
e.writeString(":") e.writeString(":")
}
func (e *Encoder) reflectByteSlice(s []byte) {
e.writeStringPrefix(int64(len(s)))
e.write(s) e.write(s)
} }
@ -161,10 +163,8 @@ func (e *Encoder) reflectValue(v reflect.Value) {
e.reflectValue(v.MapIndex(key)) e.reflectValue(v.MapIndex(key))
} }
e.writeString("e") e.writeString("e")
case reflect.Slice: case reflect.Slice, reflect.Array:
e.reflectSlice(v) e.reflectSequence(v)
case reflect.Array:
e.reflectSlice(v.Slice(0, v.Len()))
case reflect.Interface: case reflect.Interface:
e.reflectValue(v.Elem()) e.reflectValue(v.Elem())
case reflect.Ptr: case reflect.Ptr:
@ -179,11 +179,22 @@ func (e *Encoder) reflectValue(v reflect.Value) {
} }
} }
func (e *Encoder) reflectSlice(v reflect.Value) { func (e *Encoder) reflectSequence(v reflect.Value) {
// Use bencode string-type
if v.Type().Elem().Kind() == reflect.Uint8 { 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 if v.Kind() != reflect.Slice {
// could copy them and make a slice to the copy, or the user could just avoid doing this. It // Can't use []byte optimization
// remains to be seen. if !v.CanAddr() {
e.writeStringPrefix(int64(v.Len()))
for i := 0; i < v.Len(); i++ {
var b [1]byte
b[0] = byte(v.Index(i).Uint())
e.write(b[:])
}
return
}
v = v.Slice(0, v.Len())
}
s := v.Bytes() s := v.Bytes()
e.reflectByteSlice(s) e.reflectByteSlice(s)
return return