diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go index 1c57dc5010..2d6c1dec35 100644 --- a/src/strconv/atoi.go +++ b/src/strconv/atoi.go @@ -46,18 +46,16 @@ const maxUint64 = (1<<64 - 1) func ParseUint(s string, base int, bitSize int) (uint64, error) { const fnParseUint = "ParseUint" - var n uint64 - var cutoff, maxVal uint64 - if bitSize == 0 { bitSize = int(IntSize) } - i := 0 - switch { - case len(s) == 0: + if len(s) == 0 { return 0, syntaxError(fnParseUint, s) + } + s0 := s + switch { case 2 <= base && base <= 36: // valid base; nothing to do @@ -66,23 +64,24 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) { switch { case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'): if len(s) < 3 { - return 0, syntaxError(fnParseUint, s) + return 0, syntaxError(fnParseUint, s0) } base = 16 - i = 2 + s = s[2:] case s[0] == '0': base = 8 - i = 1 + s = s[1:] default: base = 10 } default: - return 0, baseError(fnParseUint, s, base) + return 0, baseError(fnParseUint, s0, base) } // Cutoff is the smallest number such that cutoff*base > maxUint64. // Use compile-time constants for common cases. + var cutoff uint64 switch base { case 10: cutoff = maxUint64/10 + 1 @@ -92,35 +91,36 @@ func ParseUint(s string, base int, bitSize int) (uint64, error) { cutoff = maxUint64/uint64(base) + 1 } - maxVal = 1<= byte(base) { - return 0, syntaxError(fnParseUint, s) + + if d >= byte(base) { + return 0, syntaxError(fnParseUint, s0) } if n >= cutoff { // n*base overflows - return maxVal, rangeError(fnParseUint, s) + return maxVal, rangeError(fnParseUint, s0) } n *= uint64(base) - n1 := n + uint64(v) + n1 := n + uint64(d) if n1 < n || n1 > maxVal { // n+v overflows - return maxVal, rangeError(fnParseUint, s) + return maxVal, rangeError(fnParseUint, s0) } n = n1 }