-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
This is not a bug, but a mistake in the code that made me think "how does this work?", and could be a bug waiting to happen. In the code for strconv.ParseComplex() (added in Go 1.15), it sets size to 128 by default (instead of 64), and passes that size to parseFloatPrefix. That function should really receive 64 for this case, but it currently happens to work with anything that's not 32, so this doesn't actually cause a bug. Here's the code for ParseComplex:
func ParseComplex(s string, bitSize int) (complex128, error) {
size := 128
if bitSize == 64 {
size = 32 // complex64 uses float32 parts
}
// ...
re, n, err := parseFloatPrefix(s, size)
// ...
}And parseFloatPrefix is defined as follows -- it handles anything other than bitSize == 32 as 64, so the invalid size of 128 happens to work:
func parseFloatPrefix(s string, bitSize int) (float64, int, error) {
if bitSize == 32 {
f, n, err := atof32(s)
return float64(f), n, err
}
return atof64(s)
}So the minimal change would be to change the size := 128 to size := 64 in ParseComplex. But there were a couple of other things I saw while in there:
- There don't seem to be any tests for
ParseComplexwithbitSize == 64(two float32's): https://golang.org/src/strconv/atoc_test.go -- it doesn't seem good that we're not testing the code paths for each size. many of the bitSize 128 tests should work the same (and we could reuse those), but the range/overflow ones will need to be different. - There don't seem to be any tests at all for
FormatComplex. I know it's pretty trivially defined in terms ofFormatFloat, but there is some logic in it, and we should still have tests to avoid regressions. - It seems to me that
parseFloatPrefix(andParseFloat) should panic if bitSize is anything other than 64 or 128.FormatComplexalready does this (code here), and so it seems for consistency (and to catch issues like this one) the other functions should do similar checks.ParseFloatandFormatFloatare clearly documented to only allow 32 and 64. Alternatively they could return an error for this case, but it seems to me errors should only be returned for bad input, not invalid types, so the panic is the right thing to do.
If folks agree, I'd be happy to put up a CL for these changes.