Fix bugs in error reporting when parsing bad bencode data.
Discovered when trying to parse a truncated torrent file.
This commit is contained in:
parent
d48a378005
commit
bd0555a835
1 changed files with 27 additions and 21 deletions
48
parse.go
48
parse.go
|
@ -107,18 +107,19 @@ func parse(r Reader, build Builder) (err os.Error) {
|
||||||
Switch:
|
Switch:
|
||||||
c, err := r.ReadByte()
|
c, err := r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case c >= '1' && c <= '9':
|
case c >= '1' && c <= '9':
|
||||||
// String
|
// String
|
||||||
err = r.UnreadByte()
|
err = r.UnreadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
str, err := decodeString(r)
|
var str string
|
||||||
|
str, err = decodeString(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
build.String(str)
|
build.String(str)
|
||||||
|
|
||||||
|
@ -127,39 +128,44 @@ Switch:
|
||||||
|
|
||||||
build.Map()
|
build.Map()
|
||||||
for {
|
for {
|
||||||
c, err := r.ReadByte()
|
c, err = r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
if c == 'e' {
|
if c == 'e' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = r.UnreadByte()
|
err = r.UnreadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
key, err := decodeString(r)
|
var key string
|
||||||
|
key, err = decodeString(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
// TODO: in pendantic mode, check for keys in ascending order.
|
// TODO: in pendantic mode, check for keys in ascending order.
|
||||||
err = parse(r, build.Key(key))
|
err = parse(r, build.Key(key))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case c == 'i':
|
case c == 'i':
|
||||||
buf, err := collectInt(r, 'e')
|
var buf []byte
|
||||||
|
buf, err = collectInt(r, 'e')
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
str := string(buf)
|
var str string
|
||||||
|
var i int64
|
||||||
|
var i2 uint64
|
||||||
|
str = string(buf)
|
||||||
// If the number is exactly an integer, use that.
|
// If the number is exactly an integer, use that.
|
||||||
if i, err := strconv.Atoi64(str); err == nil {
|
if i, err = strconv.Atoi64(str); err == nil {
|
||||||
build.Int64(i)
|
build.Int64(i)
|
||||||
} else if i, err := strconv.Atoui64(str); err == nil {
|
} else if i2, err = strconv.Atoui64(str); err == nil {
|
||||||
build.Uint64(i)
|
build.Uint64(i2)
|
||||||
} else {
|
} else {
|
||||||
err = os.NewError("Bad integer")
|
err = os.NewError("Bad integer")
|
||||||
}
|
}
|
||||||
|
@ -169,27 +175,27 @@ Switch:
|
||||||
build.Array()
|
build.Array()
|
||||||
n := 0
|
n := 0
|
||||||
for {
|
for {
|
||||||
c, err := r.ReadByte()
|
c, err = r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
if c == 'e' {
|
if c == 'e' {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = r.UnreadByte()
|
err = r.UnreadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
err = parse(r, build.Elem(n))
|
err = parse(r, build.Elem(n))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
goto exit
|
||||||
}
|
}
|
||||||
n++
|
n++
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
err = os.NewError("Unexpected character")
|
err = os.NewError("Unexpected character")
|
||||||
}
|
}
|
||||||
|
exit:
|
||||||
build.Flush()
|
build.Flush()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue