From 305da72387dee5313eca46df90087abcbeb3f520 Mon Sep 17 00:00:00 2001 From: "igor.bolotnikov" Date: Mon, 26 Oct 2020 17:55:30 +0300 Subject: [PATCH] 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 Trust: Russ Cox --- internal/number/decimal.go | 2 +- internal/number/decimal_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/number/decimal.go b/internal/number/decimal.go index 9b4035ec4..cb656db6c 100644 --- a/internal/number/decimal.go +++ b/internal/number/decimal.go @@ -379,7 +379,7 @@ func (d *Decimal) ConvertFloat(r RoundingContext, x float64, size int) { 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 97c7e25b6..670e806e5 100644 --- a/internal/number/decimal_test.go +++ b/internal/number/decimal_test.go @@ -248,6 +248,10 @@ func TestConvert(t *testing.T) { 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 @@ func TestConvert(t *testing.T) { {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