From a809dc7adb8065368c73900a8256048c55cde79b Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 12 Feb 2015 15:09:56 -0800 Subject: [PATCH] math/big: don't scan past a binary exponent if not accepted syntactically TBR adonovan Change-Id: I842cbc855dbd560f65e76c9a557dff1a22c5d610 Reviewed-on: https://go-review.googlesource.com/4882 Reviewed-by: Robert Griesemer --- src/math/big/floatconv.go | 7 ++++--- src/math/big/ratconv.go | 23 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/math/big/floatconv.go b/src/math/big/floatconv.go index 04f9a4e1b41..a857fa65137 100644 --- a/src/math/big/floatconv.go +++ b/src/math/big/floatconv.go @@ -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 } diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go index da4915e74db..778077b96ec 100644 --- a/src/math/big/ratconv.go +++ b/src/math/big/ratconv.go @@ -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