internal/number: possible out of range error avoiding Case when r.Increment > 0 and r.IncrementScale == len(scales) in *Decimal.ConvertFloat method is taken into account. It led to unexpected out of range panic. fixes golang/go#42147 Change-Id: Ic26e67010b766bdbd322a3853489f6d1ecb0dcfc Reviewed-on: https://go-review.googlesource.com/c/text/+/265021 Reviewed-by: Marcel van Lohuizen <mpvl@golang.org> Trust: Russ Cox <rsc@golang.org>
diff --git a/internal/number/decimal.go b/internal/number/decimal.go index 9b4035e..cb656db 100644 --- a/internal/number/decimal.go +++ b/internal/number/decimal.go
@@ -379,7 +379,7 @@ if r.Increment > 0 { scale := int(r.IncrementScale) mult := 1.0 - if scale > len(scales) { + if scale >= len(scales) { mult = math.Pow(10, float64(scale)) } else { mult = scales[scale]
diff --git a/internal/number/decimal_test.go b/internal/number/decimal_test.go index 97c7e25..670e806 100644 --- a/internal/number/decimal_test.go +++ b/internal/number/decimal_test.go
@@ -248,6 +248,10 @@ inc0_05 := RoundingContext{Increment: 5, IncrementScale: 2} inc0_05.SetScale(2) inc50 := RoundingContext{Increment: 50} + incScaleEqualToScalesLen := RoundingContext{Increment: 1, IncrementScale: 0} + if len(scales) <= math.MaxUint8 { + incScaleEqualToScalesLen.IncrementScale = uint8(len(scales)) + } prec3 := RoundingContext{} prec3.SetPrecision(3) roundShift := RoundingContext{DigitShift: 2, MaxFractionDigits: 2} @@ -309,6 +313,7 @@ {math.Inf(-1), inc50, "-Inf"}, {math.NaN(), inc50, "NaN"}, {"clearly not a number", scale2, "NaN"}, + {0.0, incScaleEqualToScalesLen, "0"}, } for _, tc := range testCases { var d Decimal