diff options
| author | Daniel Martí <mvdan@mvdan.cc> | 2019-09-24 13:11:36 +0100 |
|---|---|---|
| committer | Daniel Martí <mvdan@mvdan.cc> | 2019-09-25 09:22:38 +0000 |
| commit | 0f7b4e72a054f974489d8342cdae5a6a7ba7a31b (patch) | |
| tree | 40b54f8ab121c70269e9203ed148771446aeed34 /src/text/template/exec.go | |
| parent | 95cbcc5c1c5db05e659b769784e57db777c4cd6a (diff) | |
| download | go-0f7b4e72a054f974489d8342cdae5a6a7ba7a31b.tar.xz | |
text/template: don't evaluate '.' as a float64
When using a '.' constant literal as a reflect.Value variadic argument,
idealConstant would incorrectly result in a float64. This is because
rune literals can be represented as a float64, and contain a period,
which tricked the logic into thinking the literal must have been a
floating point number.
This also happened with other characters that can be part of a floating
point number, such as 'e' or 'P'.
To fix these edge cases, exit the case sooner if the literal was a rune,
since that should always go to the int case instead.
Finally, add test cases that verify that they behave properly. These
would error before, since eq would receive a mix of int and float64,
which aren't comparable.
Fixes #34483.
Change-Id: Icfcb7803bfa0cf317a1d1adacacad3d69a57eb42
Reviewed-on: https://go-review.googlesource.com/c/go/+/196808
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Tom Payne <tom@airmap.com>
Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/text/template/exec.go')
| -rw-r--r-- | src/text/template/exec.go | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/src/text/template/exec.go b/src/text/template/exec.go index 97c9d1f574..f9bc5d980c 100644 --- a/src/text/template/exec.go +++ b/src/text/template/exec.go @@ -496,20 +496,29 @@ func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value { switch { case constant.IsComplex: return reflect.ValueOf(constant.Complex128) // incontrovertible. - case constant.IsFloat && !isHexInt(constant.Text) && strings.ContainsAny(constant.Text, ".eEpP"): + + case constant.IsFloat && + !isHexInt(constant.Text) && !isRuneInt(constant.Text) && + strings.ContainsAny(constant.Text, ".eEpP"): return reflect.ValueOf(constant.Float64) + case constant.IsInt: n := int(constant.Int64) if int64(n) != constant.Int64 { s.errorf("%s overflows int", constant.Text) } return reflect.ValueOf(n) + case constant.IsUint: s.errorf("%s overflows int", constant.Text) } return zero } +func isRuneInt(s string) bool { + return len(s) > 0 && s[0] == '\'' +} + func isHexInt(s string) bool { return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') && !strings.ContainsAny(s, "pP") } |
