]> Sergey Matveev's repositories - btrtrc.git/commitdiff
bencode: Decode very large integers as big.Int if they overflow int64
authorMatt Joiner <anacrolix@gmail.com>
Sun, 20 Sep 2015 11:08:42 +0000 (21:08 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 20 Sep 2015 11:08:42 +0000 (21:08 +1000)
bencode/decode.go
bencode/decode_test.go

index 27ff898c0da81f016844f0fc4bc9411b4af475e8..2d27d683aa9b07834690a335b69f4b3f4e6b5230 100644 (file)
@@ -5,6 +5,7 @@ import (
        "bytes"
        "errors"
        "io"
+       "math/big"
        "reflect"
        "runtime"
        "strconv"
@@ -503,7 +504,7 @@ func (d *decoder) parse_value_interface() (interface{}, bool) {
        }
 }
 
-func (d *decoder) parse_int_interface() interface{} {
+func (d *decoder) parse_int_interface() (ret interface{}) {
        start := d.offset - 1
        d.read_until('e')
        if d.buf.Len() == 0 {
@@ -514,9 +515,23 @@ func (d *decoder) parse_int_interface() interface{} {
        }
 
        n, err := strconv.ParseInt(d.buf.String(), 10, 64)
-       check_for_int_parse_error(err, start)
+       if ne, ok := err.(*strconv.NumError); ok && ne.Err == strconv.ErrRange {
+               i := new(big.Int)
+               _, ok := i.SetString(d.buf.String(), 10)
+               if !ok {
+                       panic(&SyntaxError{
+                               Offset: start,
+                               What:   errors.New("failed to parse integer"),
+                       })
+               }
+               ret = i
+       } else {
+               check_for_int_parse_error(err, start)
+               ret = n
+       }
+
        d.buf.Reset()
-       return n
+       return
 }
 
 func (d *decoder) parse_string_interface() interface{} {
index d5aa8e9c57cc3783924fd0715e9d1c82a54ecc8c..396fa06237da715fe0fdb4e2cb8b6e290608b440 100644 (file)
@@ -3,6 +3,8 @@ package bencode
 import (
        "bytes"
        "io"
+       "log"
+       "math/big"
        "reflect"
        "testing"
 
@@ -24,6 +26,10 @@ var random_decode_tests = []random_decode_test{
                []interface{}{int64(5), int64(10), int64(15), int64(20), "bencode"}},
        {"ldedee", []interface{}{map[string]interface{}{}, map[string]interface{}{}}},
        {"le", []interface{}{}},
+       {"i604919719469385652980544193299329427705624352086e", func() *big.Int {
+               ret, _ := big.NewInt(-1).SetString("604919719469385652980544193299329427705624352086", 10)
+               return ret
+       }()},
 }
 
 func TestRandomDecode(t *testing.T) {