aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder/noder.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-02-02 13:20:03 -0800
committerRobert Griesemer <gri@golang.org>2021-02-03 20:22:34 +0000
commitc910fd7b771cfbfc1b11a6eef750f835bf66c96c (patch)
treeaf1361479316deaf3d4141034652ec423c576a51 /src/cmd/compile/internal/noder/noder.go
parent3db6e18468d9e5c8f5fcfece26b5b666f86e9742 (diff)
downloadgo-c910fd7b771cfbfc1b11a6eef750f835bf66c96c.tar.gz
go-c910fd7b771cfbfc1b11a6eef750f835bf66c96c.zip
[dev.typeparams] cmd/compile: refuse excessively long constants
The compiler uses 512 bit of precision for untyped constant arithmetic but didn't restrict the length of incoming constant literals in any way, possibly opening the door for excessively long constants that could bring compilation to a crawl. Add a simple check that refuses excessively long constants. Add test. Change-Id: I797cb2a8e677b8da2864eb92d686d271ab8a004d Reviewed-on: https://go-review.googlesource.com/c/go/+/289049 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/noder.go')
-rw-r--r--src/cmd/compile/internal/noder/noder.go14
1 files changed, 14 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go
index 1c38f1a934..d692bf97aa 100644
--- a/src/cmd/compile/internal/noder/noder.go
+++ b/src/cmd/compile/internal/noder/noder.go
@@ -1455,6 +1455,20 @@ func (p *noder) basicLit(lit *syntax.BasicLit) constant.Value {
switch lit.Kind {
case syntax.IntLit, syntax.FloatLit, syntax.ImagLit:
checkLangCompat(lit)
+ // The max. mantissa precision for untyped numeric values
+ // is 512 bits, or 4048 bits for each of the two integer
+ // parts of a fraction for floating-point numbers that are
+ // represented accurately in the go/constant package.
+ // Constant literals that are longer than this many bits
+ // are not meaningful; and excessively long constants may
+ // consume a lot of space and time for a useless conversion.
+ // Cap constant length with a generous upper limit that also
+ // allows for separators between all digits.
+ const limit = 10000
+ if len(lit.Value) > limit {
+ p.errorAt(lit.Pos(), "excessively long constant: %s... (%d chars)", lit.Value[:10], len(lit.Value))
+ return constant.MakeUnknown()
+ }
}
v := constant.MakeFromLiteral(lit.Value, tokenForLitKind[lit.Kind], 0)