bencode incorrectly parsed integers with leading zeroes
This commit is contained in:
parent
42dca16753
commit
78e48f71dd
|
@ -101,17 +101,29 @@ func (d *Decoder) throwSyntaxError(offset int64, err error) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// called when 'i' was consumed
|
// Assume the 'i' is already consumed. Read and validate the rest of an int into the buffer.
|
||||||
|
func (d *Decoder) readInt() error {
|
||||||
|
// start := d.Offset - 1
|
||||||
|
d.readUntil('e')
|
||||||
|
if err := d.bufLeadingZero(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// if d.buf.Len() == 0 {
|
||||||
|
// panic(&SyntaxError{
|
||||||
|
// Offset: start,
|
||||||
|
// What: errors.New("empty integer value"),
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// called when 'i' was consumed, for the integer type in v.
|
||||||
func (d *Decoder) parseInt(v reflect.Value) error {
|
func (d *Decoder) parseInt(v reflect.Value) error {
|
||||||
start := d.Offset - 1
|
start := d.Offset - 1
|
||||||
d.readUntil('e')
|
|
||||||
if d.buf.Len() == 0 {
|
|
||||||
panic(&SyntaxError{
|
|
||||||
Offset: start,
|
|
||||||
What: errors.New("empty integer value"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if err := d.readInt(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
s := bytesAsString(d.buf.Bytes())
|
s := bytesAsString(d.buf.Bytes())
|
||||||
|
|
||||||
switch v.Kind() {
|
switch v.Kind() {
|
||||||
|
@ -149,16 +161,33 @@ func (d *Decoder) parseInt(v reflect.Value) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseString(v reflect.Value) error {
|
func (d *Decoder) bufLeadingZero() error {
|
||||||
|
b := d.buf.Bytes()
|
||||||
|
if len(b) > 1 && b[0] == '0' {
|
||||||
|
return fmt.Errorf("non-zero integer has leading zeroes: %q", b)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) parseStringLength() (uint64, error) {
|
||||||
|
// We should have already consumed the first byte of the length into the Decoder buf.
|
||||||
start := d.Offset - 1
|
start := d.Offset - 1
|
||||||
|
|
||||||
// read the string length first
|
|
||||||
d.readUntil(':')
|
d.readUntil(':')
|
||||||
length, err := strconv.ParseInt(bytesAsString(d.buf.Bytes()), 10, 32)
|
if err := d.bufLeadingZero(); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
length, err := strconv.ParseUint(bytesAsString(d.buf.Bytes()), 10, 32)
|
||||||
checkForIntParseError(err, start)
|
checkForIntParseError(err, start)
|
||||||
|
d.buf.Reset()
|
||||||
|
return length, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Decoder) parseString(v reflect.Value) error {
|
||||||
|
length, err := d.parseStringLength()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer d.buf.Reset()
|
defer d.buf.Reset()
|
||||||
|
|
||||||
read := func(b []byte) {
|
read := func(b []byte) {
|
||||||
n, err := io.ReadFull(d.r, b)
|
n, err := io.ReadFull(d.r, b)
|
||||||
d.Offset += int64(n)
|
d.Offset += int64(n)
|
||||||
|
@ -231,13 +260,13 @@ func getDictField(dict reflect.Type, key string) (_ dictField, err error) {
|
||||||
}, nil
|
}, nil
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
return getStructFieldForKey(dict, key), nil
|
return getStructFieldForKey(dict, key), nil
|
||||||
//if sf.r.PkgPath != "" {
|
// if sf.r.PkgPath != "" {
|
||||||
// panic(&UnmarshalFieldError{
|
// panic(&UnmarshalFieldError{
|
||||||
// Key: key,
|
// Key: key,
|
||||||
// Type: dict.Type(),
|
// Type: dict.Type(),
|
||||||
// Field: sf.r,
|
// Field: sf.r,
|
||||||
// })
|
// })
|
||||||
//}
|
// }
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("can't assign bencode dict items into a %v", k)
|
err = fmt.Errorf("can't assign bencode dict items into a %v", k)
|
||||||
return
|
return
|
||||||
|
@ -580,16 +609,13 @@ func (d *Decoder) parseValueInterface() (interface{}, bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called after 'i', for an arbitrary integer size.
|
||||||
func (d *Decoder) parseIntInterface() (ret interface{}) {
|
func (d *Decoder) parseIntInterface() (ret interface{}) {
|
||||||
start := d.Offset - 1
|
start := d.Offset - 1
|
||||||
d.readUntil('e')
|
|
||||||
if d.buf.Len() == 0 {
|
|
||||||
panic(&SyntaxError{
|
|
||||||
Offset: start,
|
|
||||||
What: errors.New("empty integer value"),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if err := d.readInt(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
n, err := strconv.ParseInt(d.buf.String(), 10, 64)
|
n, err := strconv.ParseInt(d.buf.String(), 10, 64)
|
||||||
if ne, ok := err.(*strconv.NumError); ok && ne.Err == strconv.ErrRange {
|
if ne, ok := err.(*strconv.NumError); ok && ne.Err == strconv.ErrRange {
|
||||||
i := new(big.Int)
|
i := new(big.Int)
|
||||||
|
@ -611,13 +637,10 @@ func (d *Decoder) parseIntInterface() (ret interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Decoder) parseStringInterface() string {
|
func (d *Decoder) parseStringInterface() string {
|
||||||
// read the string length first
|
length, err := d.parseStringLength()
|
||||||
d.readUntil(':')
|
|
||||||
length, err := strconv.ParseInt(bytesAsString(d.buf.Bytes()), 10, 32)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(&SyntaxError{Offset: d.Offset - 1, What: err})
|
panic(err)
|
||||||
}
|
}
|
||||||
d.buf.Reset()
|
|
||||||
b := make([]byte, length)
|
b := make([]byte, length)
|
||||||
n, err := io.ReadFull(d.r, b)
|
n, err := io.ReadFull(d.r, b)
|
||||||
d.Offset += int64(n)
|
d.Offset += int64(n)
|
||||||
|
|
Loading…
Reference in New Issue