diff options
author | Robert Griesemer <gri@golang.org> | 2020-05-08 12:13:11 -0700 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2020-05-08 20:34:23 +0000 |
commit | 65126c588e5c3ea73cd6721f831b01957f7ecbe0 (patch) | |
tree | 35d3712a5b6816997cc95ba4ee165e701ed13459 /src/strconv | |
parent | 26de581a709428d55ffc38cc0dbc7ddfc96b9443 (diff) | |
download | go-65126c588e5c3ea73cd6721f831b01957f7ecbe0.tar.gz go-65126c588e5c3ea73cd6721f831b01957f7ecbe0.zip |
strconv: fix ParseComplex for strings with separators
The recently added function parseFloatPrefix tested the entire
string for correct placement of separators rather than just the
consumed part. The 4-char fix is in readFloat (atof.go:303).
Added more tests. Also added some white space for nicer
grouping of the test cases.
While at it, removed the need for calling testing.Run.
Fixes #38962.
Change-Id: Ifce84f362bb4ede559103f8d535556d3de9325f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/233017
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/strconv')
-rw-r--r-- | src/strconv/atoc_test.go | 39 | ||||
-rw-r--r-- | src/strconv/atof.go | 2 | ||||
-rw-r--r-- | src/strconv/atof_test.go | 2 |
3 files changed, 25 insertions, 18 deletions
diff --git a/src/strconv/atoc_test.go b/src/strconv/atoc_test.go index 5c817a2e44..3aa421dd03 100644 --- a/src/strconv/atoc_test.go +++ b/src/strconv/atoc_test.go @@ -17,6 +17,7 @@ var ( infm0 = complex(math.Inf(-1), 0) inf0p = complex(0, math.Inf(+1)) inf0m = complex(0, math.Inf(-1)) + infpp = complex(math.Inf(+1), math.Inf(+1)) infpm = complex(math.Inf(+1), math.Inf(-1)) infmp = complex(math.Inf(-1), math.Inf(+1)) @@ -30,7 +31,6 @@ type atocTest struct { } func TestParseComplex(t *testing.T) { - tests := []atocTest{ // Clearly invalid {"", 0, ErrSyntax}, @@ -45,6 +45,7 @@ func TestParseComplex(t *testing.T) { {"3+", 0, ErrSyntax}, {"3+5", 0, ErrSyntax}, {"3+5+5i", 0, ErrSyntax}, + // Parentheses {"()", 0, ErrSyntax}, {"(i)", 0, ErrSyntax}, @@ -54,6 +55,7 @@ func TestParseComplex(t *testing.T) { {"(1)+1i", 0, ErrSyntax}, {"(3.0+5.5i", 0, ErrSyntax}, {"3.0+5.5i)", 0, ErrSyntax}, + // NaNs {"NaN", complex(math.NaN(), 0), nil}, {"NANi", complex(0, math.NaN()), nil}, @@ -61,6 +63,7 @@ func TestParseComplex(t *testing.T) { {"+NaN", 0, ErrSyntax}, {"-NaN", 0, ErrSyntax}, {"NaN-NaNi", 0, ErrSyntax}, + // Infs {"Inf", infp0, nil}, {"+inf", infp0, nil}, @@ -74,6 +77,7 @@ func TestParseComplex(t *testing.T) { {"+Inf-Infi", infpm, nil}, {"-Infinity+Infi", infmp, nil}, {"inf-inf", 0, ErrSyntax}, + // Zeros {"0", 0, nil}, {"0i", 0, nil}, @@ -88,6 +92,7 @@ func TestParseComplex(t *testing.T) { {"+0e-0+0e-0i", 0, nil}, {"0e+0+0e+0i", 0, nil}, {"-0e+0-0e+0i", 0, nil}, + // Regular non-zeroes {"0.1", 0.1, nil}, {"0.1i", 0 + 0.1i, nil}, @@ -104,14 +109,17 @@ func TestParseComplex(t *testing.T) { {"+3e+3-3e+3i", 3e+3 - 3e+3i, nil}, {"+3e+3+3e+3i", 3e+3 + 3e+3i, nil}, {"+3e+3+3e+3i+", 0, ErrSyntax}, + // Separators {"0.1", 0.1, nil}, {"0.1i", 0 + 0.1i, nil}, {"0.1_2_3", 0.123, nil}, {"+0x_3p3i", 0x3p3i, nil}, + {"0_0+0x_0p0i", 0, nil}, {"0x_10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, - {"+0x_1_0.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, - {"0x10.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil}, + {"+0x_1_0.3p-8+0x_3_0p3i", 0x10.3p-8 + 0x30p3i, nil}, + {"0x1_0.3p+8-0x_3p3i", 0x10.3p+8 - 0x3p3i, nil}, + // Hexadecimals {"0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, {"+0x10.3p-8+0x3p3i", 0x10.3p-8 + 0x3p3i, nil}, @@ -125,6 +133,7 @@ func TestParseComplex(t *testing.T) { {"0x1e2", 0, ErrSyntax}, {"1p2", 0, ErrSyntax}, {"0x1e2i", 0, ErrSyntax}, + // ErrRange // next float64 - too large {"+0x1p1024", infp0, ErrRange}, @@ -177,19 +186,17 @@ func TestParseComplex(t *testing.T) { {"1e+4294967296+1e+4294967296i", infpp, ErrRange}, {"1e+4294967296-1e+4294967296i", infpm, ErrRange}, } - for _, tt := range tests { - tt := tt // for capture in Run closures below - if tt.err != nil { - tt.err = &NumError{Func: "ParseComplex", Num: tt.in, Err: tt.err} + for i := range tests { + test := &tests[i] + if test.err != nil { + test.err = &NumError{Func: "ParseComplex", Num: test.in, Err: test.err} + } + got, err := ParseComplex(test.in, 128) + if !reflect.DeepEqual(err, test.err) { + t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err) + } + if !(cmplx.IsNaN(test.out) && cmplx.IsNaN(got)) && got != test.out { + t.Fatalf("ParseComplex(%q, 128) = %v, %v; want %v, %v", test.in, got, err, test.out, test.err) } - t.Run(tt.in, func(t *testing.T) { - got, err := ParseComplex(tt.in, 128) - if !reflect.DeepEqual(err, tt.err) { - t.Fatalf("ParseComplex(%q, 128) = %v, %v want %v, %v", tt.in, got, err, tt.out, tt.err) - } - if !(cmplx.IsNaN(tt.out) && cmplx.IsNaN(got)) && got != tt.out { - t.Fatalf("ParseComplex(%q, 128) = %v, %v want %v, %v", tt.in, got, err, tt.out, tt.err) - } - }) } } diff --git a/src/strconv/atof.go b/src/strconv/atof.go index f20ae4af09..901f27afff 100644 --- a/src/strconv/atof.go +++ b/src/strconv/atof.go @@ -300,7 +300,7 @@ loop: exp = dp - ndMant } - if underscores && !underscoreOK(s) { + if underscores && !underscoreOK(s[:i]) { return } diff --git a/src/strconv/atof_test.go b/src/strconv/atof_test.go index c30cb2e0fe..545d989c41 100644 --- a/src/strconv/atof_test.go +++ b/src/strconv/atof_test.go @@ -480,7 +480,7 @@ func initAtofOnce() { } func TestParseFloatPrefix(t *testing.T) { - for i := 0; i < len(atoftests); i++ { + for i := range atoftests { test := &atoftests[i] if test.err != nil { continue |