mirror of
https://github.com/golang/go
synced 2024-11-18 15:44:41 -07:00
math/big: Rat.SetString to report error if input is not consumed entirely
Also, document behavior explicitly for all SetString implementations. Fixes #17001. Change-Id: Iccc882b4bc7f8b61b6092f330e405c146a80dc98 Reviewed-on: https://go-review.googlesource.com/30472 Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
4103fedf19
commit
95a6572b2b
@ -14,7 +14,9 @@ import (
|
||||
|
||||
// SetString sets z to the value of s and returns z and a boolean indicating
|
||||
// success. s must be a floating-point number of the same format as accepted
|
||||
// by Parse, with base argument 0.
|
||||
// by Parse, with base argument 0. The entire string (not just a prefix) must
|
||||
// be valid for success. If the operation failed, the value of z is undefined
|
||||
// but the returned value is nil.
|
||||
func (z *Float) SetString(s string) (*Float, bool) {
|
||||
if f, _, err := z.Parse(s, 0); err == nil {
|
||||
return f, true
|
||||
@ -212,6 +214,7 @@ func (z *Float) pow5(n uint64) *Float {
|
||||
//
|
||||
// It sets z to the (possibly rounded) value of the corresponding floating-
|
||||
// point value, and returns z, the actual base b, and an error err, if any.
|
||||
// The entire string (not just a prefix) must be consumed for success.
|
||||
// If z's precision is 0, it is changed to 64 before rounding takes effect.
|
||||
// The number must be of the form:
|
||||
//
|
||||
|
@ -361,7 +361,8 @@ func (x *Int) Uint64() uint64 {
|
||||
}
|
||||
|
||||
// SetString sets z to the value of s, interpreted in the given base,
|
||||
// and returns z and a boolean indicating success. If SetString fails,
|
||||
// and returns z and a boolean indicating success. The entire string
|
||||
// (not just a prefix) must be valid for success. If SetString fails,
|
||||
// the value of z is undefined but the returned value is nil.
|
||||
//
|
||||
// The base argument must be 0 or a value between 2 and MaxBase. If the base
|
||||
@ -371,12 +372,11 @@ func (x *Int) Uint64() uint64 {
|
||||
//
|
||||
func (z *Int) SetString(s string, base int) (*Int, bool) {
|
||||
r := strings.NewReader(s)
|
||||
_, _, err := z.scan(r, base)
|
||||
if err != nil {
|
||||
if _, _, err := z.scan(r, base); err != nil {
|
||||
return nil, false
|
||||
}
|
||||
_, err = r.ReadByte()
|
||||
if err != io.EOF {
|
||||
// entire string must have been consumed
|
||||
if _, err := r.ReadByte(); err != io.EOF {
|
||||
return nil, false
|
||||
}
|
||||
return z, true // err == io.EOF => scan consumed all of s
|
||||
|
@ -36,8 +36,9 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
|
||||
|
||||
// SetString sets z to the value of s and returns z and a boolean indicating
|
||||
// success. s can be given as a fraction "a/b" or as a floating-point number
|
||||
// optionally followed by an exponent. If the operation failed, the value of
|
||||
// z is undefined but the returned value is nil.
|
||||
// optionally followed by an exponent. The entire string (not just a prefix)
|
||||
// must be valid for success. If the operation failed, the value of z is un-
|
||||
// defined but the returned value is nil.
|
||||
func (z *Rat) SetString(s string) (*Rat, bool) {
|
||||
if len(s) == 0 {
|
||||
return nil, false
|
||||
@ -49,9 +50,13 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
|
||||
if _, ok := z.a.SetString(s[:sep], 0); !ok {
|
||||
return nil, false
|
||||
}
|
||||
s = s[sep+1:]
|
||||
r := strings.NewReader(s[sep+1:])
|
||||
var err error
|
||||
if z.b.abs, _, _, err = z.b.abs.scan(strings.NewReader(s), 0, false); err != nil {
|
||||
if z.b.abs, _, _, err = z.b.abs.scan(r, 0, false); err != nil {
|
||||
return nil, false
|
||||
}
|
||||
// entire string must have been consumed
|
||||
if _, err = r.ReadByte(); err != io.EOF {
|
||||
return nil, false
|
||||
}
|
||||
if len(z.b.abs) == 0 {
|
||||
|
@ -50,6 +50,10 @@ var setStringTests = []StringTest{
|
||||
{"204211327800791583.81095", "4084226556015831676219/20000", true},
|
||||
{"0e9999999999", "0", true}, // issue #16176
|
||||
{in: "1/0"},
|
||||
{in: "4/3/2"}, // issue 17001
|
||||
{in: "4/3/"},
|
||||
{in: "4/3."},
|
||||
{in: "4/"},
|
||||
}
|
||||
|
||||
// These are not supported by fmt.Fscanf.
|
||||
@ -59,6 +63,7 @@ var setStringTests2 = []StringTest{
|
||||
{"-010.", "-10", true},
|
||||
{"0x10/0x20", "1/2", true},
|
||||
{"0b1000/3", "8/3", true},
|
||||
{in: "4/3x"},
|
||||
// TODO(gri) add more tests
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user