]> Cypherpunks.ru repositories - gostls13.git/commitdiff
math/big: special-case a 0 mantissa during Rat parsing
authorNathan VanBenschoten <nvanbenschoten@gmail.com>
Thu, 23 Jun 2016 23:46:13 +0000 (19:46 -0400)
committerRobert Griesemer <gri@golang.org>
Fri, 24 Jun 2016 20:51:06 +0000 (20:51 +0000)
Previously, a 0 mantissa was special-cased during big.Float
parsing, but not during big.Rat parsing. This meant that a value
like 0e9999999999 would parse successfully in big.Float.SetString,
but would hang in big.Rat.SetString. This discrepancy became an
issue in https://golang.org/src/go/constant/value.go?#L250,
where the big.Float would report an exponent of 0, so
big.Rat.SetString would be used and would subsequently hang.

A Go Playground example of this is https://play.golang.org/p/3fy28eUJuF

The solution is to special-case a zero mantissa during big.Rat
parsing as well, so that neither big.Rat nor big.Float will hang when
parsing a value with 0 mantissa but a large exponent.

This was discovered using go-fuzz on CockroachDB:
https://github.com/cockroachdb/go-fuzz/blob/master/examples/parser/main.go

Fixes #16176

Change-Id: I775558a8682adbeba1cc9d20ba10f8ed26259c56
Reviewed-on: https://go-review.googlesource.com/24430
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/go/constant/value_test.go
src/math/big/ratconv.go
src/math/big/ratconv_test.go

index dbd96c07a310b8795339c9cd7f3ec55d161967d8..8a8a08eaaa18b82d14b4a5deef0d09ef27a953d8 100644 (file)
@@ -244,6 +244,7 @@ var stringTests = []struct {
        {"1e9999", "1e+9999", "0x.f8d4a9da224650a8cb2959e10d985ad92adbd44c62917e608b1f24c0e1b76b6f61edffeb15c135a4b601637315f7662f325f82325422b244286a07663c9415d2p+33216"},
        {"1e-9999", "1e-9999", "0x.83b01ba6d8c0425eec1b21e96f7742d63c2653ed0a024cf8a2f9686df578d7b07d7a83d84df6a2ec70a921d1f6cd5574893a7eda4d28ee719e13a5dce2700759p-33215"},
        {"2.71828182845904523536028747135266249775724709369995957496696763", "2.71828", "271828182845904523536028747135266249775724709369995957496696763/100000000000000000000000000000000000000000000000000000000000000"},
+       {"0e9999999999", "0", "0"}, // issue #16176
 
        // Complex
        {"0i", "(0 + 0i)", "(0 + 0i)"},
index 7c127f8585751e09c334c044a31d00e95f7ab49b..ef2b6750d0c0c4e3e68cc35602c5df4113013c51 100644 (file)
@@ -88,6 +88,12 @@ func (z *Rat) SetString(s string) (*Rat, bool) {
                return nil, false
        }
 
+       // special-case 0 (see also issue #16176)
+       if len(z.a.abs) == 0 {
+               return z, true
+       }
+       // len(z.a.abs) > 0
+
        // correct exponent
        if ecorr < 0 {
                exp += int64(ecorr)
index 17bda4763713d731fcfec1282efe7d4b631e0480..35ad6ccea773a873391e8e64ea154804abe55659 100644 (file)
@@ -48,6 +48,7 @@ var setStringTests = []StringTest{
        {"53/70893980658822810696", "53/70893980658822810696", true},
        {"106/141787961317645621392", "53/70893980658822810696", true},
        {"204211327800791583.81095", "4084226556015831676219/20000", true},
+       {"0e9999999999", "0", true}, // issue #16176
        {in: "1/0"},
 }