]> Cypherpunks.ru repositories - gostls13.git/commitdiff
math/big: don't scan past a binary exponent if not accepted syntactically
authorRobert Griesemer <gri@golang.org>
Thu, 12 Feb 2015 23:09:56 +0000 (15:09 -0800)
committerRobert Griesemer <gri@golang.org>
Sat, 14 Feb 2015 01:01:19 +0000 (01:01 +0000)
TBR adonovan

Change-Id: I842cbc855dbd560f65e76c9a557dff1a22c5d610
Reviewed-on: https://go-review.googlesource.com/4882
Reviewed-by: Robert Griesemer <gri@golang.org>
src/math/big/floatconv.go
src/math/big/ratconv.go

index 04f9a4e1b412a7c23be6e55092aa85147af1757c..a857fa651378cf718ae312c6186d96fb3641af22 100644 (file)
@@ -46,11 +46,12 @@ func (z *Float) SetString(s string) (*Float, bool) {
 //     digits   = digit { digit } .
 //     digit    = "0" ... "9" | "a" ... "z" | "A" ... "Z" .
 //
-// The base argument must be 0 or a value between 2 through MaxBase.
+// The base argument must be 0, 2, 10, or 16. Providing an invalid base
+// argument will lead to a run-time panic.
 //
 // For base 0, the number prefix determines the actual base: A prefix of
 // ``0x'' or ``0X'' selects base 16, and a ``0b'' or ``0B'' prefix selects
-// base 2; otherwise, the actual base is 10 and no prefix is permitted.
+// base 2; otherwise, the actual base is 10 and no prefix is accepted.
 // The octal prefix ``0'' is not supported.
 //
 // A "p" exponent indicates power of 2 for the exponent; for instance "1.2p3"
@@ -75,7 +76,7 @@ func (z *Float) Scan(r io.ByteScanner, base int) (f *Float, b int, err error) {
        // exponent
        var exp int64
        var ebase int
-       exp, ebase, err = scanExponent(r)
+       exp, ebase, err = scanExponent(r, true)
        if err != nil {
                return
        }
index da4915e74db6026f3ababd934e07803f23381dbd..778077b96ecb56a863ff05793991ef80620e8afc 100644 (file)
@@ -78,9 +78,8 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
 
        // exponent
        var exp int64
-       var ebase int
-       exp, ebase, err = scanExponent(r)
-       if ebase == 2 || err != nil {
+       exp, _, err = scanExponent(r, false)
+       if err != nil {
                return nil, false
        }
 
@@ -115,7 +114,17 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
        return z, true
 }
 
-func scanExponent(r io.ByteScanner) (exp int64, base int, err error) {
+// scanExponent scans the longest possible prefix of r representing a decimal
+// ('e', 'E') or binary ('p') exponent, if any. It returns the exponent, the
+// exponent base (10 or 2), or a read or syntax error, if any.
+//
+//     exponent = ( "E" | "e" | "p" ) [ sign ] digits .
+//     sign     = "+" | "-" .
+//     digits   = digit { digit } .
+//     digit    = "0" ... "9" .
+//
+// A binary exponent is only permitted if binExpOk is set.
+func scanExponent(r io.ByteScanner, binExpOk bool) (exp int64, base int, err error) {
        base = 10
 
        var ch byte
@@ -130,7 +139,11 @@ func scanExponent(r io.ByteScanner) (exp int64, base int, err error) {
        case 'e', 'E':
                // ok
        case 'p':
-               base = 2
+               if binExpOk {
+                       base = 2
+                       break // ok
+               }
+               fallthrough // binary exponent not permitted
        default:
                r.UnreadByte()
                return // no exponent; same as e0