Fix bugs in error reporting when parsing bad bencode data.

Discovered when trying to parse a truncated torrent file.
This commit is contained in:
Jack Palevich 2010-01-23 15:48:21 +08:00
parent d48a378005
commit bd0555a835

View file

@ -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
} }