import (
"errors"
"fmt"
+ "math"
"math/big"
"reflect"
"strconv"
// given byte slice. It returns the value and the new offset.
func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
offset = initOffset
+ var ret64 int64
for shifted := 0; offset < len(bytes); shifted++ {
- if shifted == 4 {
+ // 5 * 7 bits per byte == 35 bits of data
+ // Thus the representation is either non-minimal or too large for an int32
+ if shifted == 5 {
err = StructuralError{"base 128 integer too large"}
return
}
- ret <<= 7
+ ret64 <<= 7
b := bytes[offset]
- ret |= int(b & 0x7f)
+ ret64 |= int64(b & 0x7f)
offset++
if b&0x80 == 0 {
+ ret = int(ret64)
+ // Ensure that the returned value fits in an int on all platforms
+ if ret64 > math.MaxInt32 {
+ err = StructuralError{"base 128 integer too large"}
+ }
return
}
}
import (
"bytes"
"fmt"
+ "math"
"math/big"
"reflect"
"strings"
{[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
// Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
{[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
+ // Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
+ {[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
// Long tag number form may not be used for tags that fit in short form.
{[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
}