diff options
author | Ben Hoyt <benhoyt@gmail.com> | 2020-11-04 10:13:42 +1300 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-11-03 23:05:51 +0000 |
commit | e1b305af028544e00a22c905e68049c98c10a1cc (patch) | |
tree | ed2e0e3dd0246c5eb3ec91703e983bbaeb93c267 /src/strconv | |
parent | da7aa86917811a571e6634b45a457f918b8e6561 (diff) | |
download | go-e1b305af028544e00a22c905e68049c98c10a1cc.tar.gz go-e1b305af028544e00a22c905e68049c98c10a1cc.zip |
strconv: revert ParseFloat/ParseComplex error on incorrect bitSize
This is a partial revert of https://go-review.googlesource.com/c/go/+/248219
because we found that a non-trivial amount of code erroneously calls
ParseFloat(s, 10) or even ParseFloat(s, 0) and expects it to work --
before that change was merged, ParseFloat accepted a bitSize of
anything other than 32 or 64 to mean 64 (and ParseComplex was similar).
So revert that behavior to avoid breaking people's code, and add tests
for this.
I may add a vet check to flag ParseFloat(s, not_32_or_64) in a later
change.
See #42297 for more details.
Change-Id: I4bc0156bd74f67a39d5561b6e5fde3f2d20bd622
Reviewed-on: https://go-review.googlesource.com/c/go/+/267319
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/strconv')
-rw-r--r-- | src/strconv/atoc.go | 6 | ||||
-rw-r--r-- | src/strconv/atoc_test.go | 21 | ||||
-rw-r--r-- | src/strconv/atof.go | 3 | ||||
-rw-r--r-- | src/strconv/atof_test.go | 22 |
4 files changed, 30 insertions, 22 deletions
diff --git a/src/strconv/atoc.go b/src/strconv/atoc.go index 52cb5908b2..85c7bafefa 100644 --- a/src/strconv/atoc.go +++ b/src/strconv/atoc.go @@ -40,10 +40,10 @@ func convErr(err error, s string) (syntax, range_ error) { // away from the largest floating point number of the given component's size, // ParseComplex returns err.Err = ErrRange and c = ±Inf for the respective component. func ParseComplex(s string, bitSize int) (complex128, error) { - if bitSize != 64 && bitSize != 128 { - return 0, bitSizeError(fnParseComplex, s, bitSize) + size := 64 + if bitSize == 64 { + size = 32 // complex64 uses float32 parts } - size := bitSize >> 1 orig := s diff --git a/src/strconv/atoc_test.go b/src/strconv/atoc_test.go index aecc09d247..4c1aad0900 100644 --- a/src/strconv/atoc_test.go +++ b/src/strconv/atoc_test.go @@ -212,13 +212,18 @@ func TestParseComplex(t *testing.T) { } } -func TestParseComplexInvalidBitSize(t *testing.T) { - _, err := ParseComplex("1+2i", 100) - const want = `strconv.ParseComplex: parsing "1+2i": invalid bit size 100` - if err == nil { - t.Fatalf("got nil error, want %q", want) - } - if err.Error() != want { - t.Fatalf("got error %q, want %q", err, want) +// Issue 42297: allow ParseComplex(s, not_32_or_64) for legacy reasons +func TestParseComplexIncorrectBitSize(t *testing.T) { + const s = "1.5e308+1.0e307i" + const want = 1.5e308 + 1.0e307i + + for _, bitSize := range []int{0, 10, 100, 256} { + c, err := ParseComplex(s, bitSize) + if err != nil { + t.Fatalf("ParseComplex(%q, %d) gave error %s", s, bitSize, err) + } + if c != want { + t.Fatalf("ParseComplex(%q, %d) = %g (expected %g)", s, bitSize, c, want) + } } } diff --git a/src/strconv/atof.go b/src/strconv/atof.go index a04f5621f6..9010a66ca8 100644 --- a/src/strconv/atof.go +++ b/src/strconv/atof.go @@ -688,9 +688,6 @@ func atof64(s string) (f float64, n int, err error) { // ParseFloat recognizes the strings "NaN", and the (possibly signed) strings "Inf" and "Infinity" // as their respective special floating point values. It ignores case when matching. func ParseFloat(s string, bitSize int) (float64, error) { - if bitSize != 32 && bitSize != 64 { - return 0, bitSizeError(fnParseFloat, s, bitSize) - } f, n, err := parseFloatPrefix(s, bitSize) if err == nil && n != len(s) { return 0, syntaxError(fnParseFloat, s) diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go index cf43903506..3c058b9be5 100644 --- a/src/strconv/atof_test.go +++ b/src/strconv/atof_test.go @@ -634,14 +634,20 @@ func TestRoundTrip32(t *testing.T) { t.Logf("tested %d float32's", count) } -func TestParseFloatInvalidBitSize(t *testing.T) { - _, err := ParseFloat("3.14", 100) - const want = `strconv.ParseFloat: parsing "3.14": invalid bit size 100` - if err == nil { - t.Fatalf("got nil error, want %q", want) - } - if err.Error() != want { - t.Fatalf("got error %q, want %q", err, want) +// Issue 42297: a lot of code in the wild accidentally calls ParseFloat(s, 10) +// or ParseFloat(s, 0), so allow bitSize values other than 32 and 64. +func TestParseFloatIncorrectBitSize(t *testing.T) { + const s = "1.5e308" + const want = 1.5e308 + + for _, bitSize := range []int{0, 10, 100, 128} { + f, err := ParseFloat(s, bitSize) + if err != nil { + t.Fatalf("ParseFloat(%q, %d) gave error %s", s, bitSize, err) + } + if f != want { + t.Fatalf("ParseFloat(%q, %d) = %g (expected %g)", s, bitSize, f, want) + } } } |