Fix panic unmarshalling bencode dict into unsupported type
This commit is contained in:
parent
d03de7669b
commit
a76fad32eb
|
@ -211,9 +211,9 @@ type dictField struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns specifics for parsing a dict field value.
|
// Returns specifics for parsing a dict field value.
|
||||||
func getDictField(dict reflect.Type, key string) dictField {
|
func getDictField(dict reflect.Type, key string) (_ dictField, err error) {
|
||||||
// get valuev as a map value or as a struct field
|
// get valuev as a map value or as a struct field
|
||||||
switch dict.Kind() {
|
switch k := dict.Kind(); k {
|
||||||
case reflect.Map:
|
case reflect.Map:
|
||||||
return dictField{
|
return dictField{
|
||||||
Type: dict.Elem(),
|
Type: dict.Elem(),
|
||||||
|
@ -227,9 +227,9 @@ func getDictField(dict reflect.Type, key string) dictField {
|
||||||
mapValue.SetMapIndex(reflect.ValueOf(key).Convert(dict.Key()), value)
|
mapValue.SetMapIndex(reflect.ValueOf(key).Convert(dict.Key()), value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}, nil
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return getStructFieldForKey(dict, key)
|
return getStructFieldForKey(dict, key), nil
|
||||||
//if sf.r.PkgPath != "" {
|
//if sf.r.PkgPath != "" {
|
||||||
// panic(&UnmarshalFieldError{
|
// panic(&UnmarshalFieldError{
|
||||||
// Key: key,
|
// Key: key,
|
||||||
|
@ -238,8 +238,8 @@ func getDictField(dict reflect.Type, key string) dictField {
|
||||||
// })
|
// })
|
||||||
//}
|
//}
|
||||||
default:
|
default:
|
||||||
panic("unimplemented")
|
err = fmt.Errorf("can't parse bencode dict items into %v", k)
|
||||||
return dictField{}
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,20 +313,22 @@ func getStructFieldForKey(struct_ reflect.Type, key string) (f dictField) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseDict(v reflect.Value) error {
|
func (d *Decoder) parseDict(v reflect.Value) error {
|
||||||
// so, at this point 'd' byte was consumed, let's just read key/value
|
// At this point 'd' byte was consumed, now read key/value pairs
|
||||||
// pairs one by one
|
|
||||||
for {
|
for {
|
||||||
var keyStr string
|
var keyStr string
|
||||||
keyValue := reflect.ValueOf(&keyStr).Elem()
|
keyValue := reflect.ValueOf(&keyStr).Elem()
|
||||||
ok, err := d.parseValue(keyValue)
|
ok, err := d.parseValue(keyValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing dict key: %s", err)
|
return fmt.Errorf("error parsing dict key: %w", err)
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
df := getDictField(v.Type(), keyStr)
|
df, err := getDictField(v.Type(), keyStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("parsing bencode dict into %v: %w", v.Type(), err)
|
||||||
|
}
|
||||||
|
|
||||||
// now we need to actually parse it
|
// now we need to actually parse it
|
||||||
if df.Type == nil {
|
if df.Type == nil {
|
||||||
|
|
|
@ -174,3 +174,12 @@ func TestUnmarshalByteArray(t *testing.T) {
|
||||||
assert.NoError(t, Unmarshal([]byte("2:hi"), &ba))
|
assert.NoError(t, Unmarshal([]byte("2:hi"), &ba))
|
||||||
assert.EqualValues(t, "hi", ba[:])
|
assert.EqualValues(t, "hi", ba[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDecodeDictIntoUnsupported(t *testing.T) {
|
||||||
|
// Any type that a dict shouldn't be unmarshallable into.
|
||||||
|
var i int
|
||||||
|
c := qt.New(t)
|
||||||
|
err := Unmarshal([]byte("d1:a1:be"), &i)
|
||||||
|
t.Log(err)
|
||||||
|
c.Check(err, qt.Not(qt.IsNil))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue