mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
go/types, types2: check integer constant literal overflow
Fixes #54280. Change-Id: I44a31daaace50bc90c96cd36387bd1a009d6a287 Reviewed-on: https://go-review.googlesource.com/c/go/+/424055 Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
7ec0ec3645
commit
f80b12667c
@ -109,7 +109,11 @@ func (check *Checker) overflow(x *operand) {
|
|||||||
// Untyped integer values must not grow arbitrarily.
|
// Untyped integer values must not grow arbitrarily.
|
||||||
const prec = 512 // 512 is the constant precision
|
const prec = 512 // 512 is the constant precision
|
||||||
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
|
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
|
||||||
check.errorf(opPos(x.expr), "constant %s overflow", opName(x.expr))
|
op := opName(x.expr)
|
||||||
|
if op != "" {
|
||||||
|
op += " "
|
||||||
|
}
|
||||||
|
check.errorf(opPos(x.expr), "constant %soverflow", op)
|
||||||
x.val = constant.MakeUnknown()
|
x.val = constant.MakeUnknown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1344,6 +1348,9 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
|||||||
check.errorf(e, "malformed constant: %s", e.Value)
|
check.errorf(e, "malformed constant: %s", e.Value)
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
// Ensure that integer values don't overflow (issue #54280).
|
||||||
|
x.expr = e // make sure that check.overflow below has an error position
|
||||||
|
check.overflow(x)
|
||||||
|
|
||||||
case *syntax.FuncLit:
|
case *syntax.FuncLit:
|
||||||
if sig, ok := check.typ(e.Type).(*Signature); ok {
|
if sig, ok := check.typ(e.Type).(*Signature); ok {
|
||||||
|
7
src/cmd/compile/internal/types2/testdata/fixedbugs/issue54280.go
vendored
Normal file
7
src/cmd/compile/internal/types2/testdata/fixedbugs/issue54280.go
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow
|
@ -352,7 +352,7 @@ func TestManual(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestLongConstants(t *testing.T) {
|
func TestLongConstants(t *testing.T) {
|
||||||
format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
|
format := "package longconst\n\nconst _ = %s /* ERROR constant overflow */ \nconst _ = %s // ERROR excessively long constant"
|
||||||
src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
|
src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
|
||||||
testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
|
testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,11 @@ func (check *Checker) overflow(x *operand, opPos token.Pos) {
|
|||||||
// Untyped integer values must not grow arbitrarily.
|
// Untyped integer values must not grow arbitrarily.
|
||||||
const prec = 512 // 512 is the constant precision
|
const prec = 512 // 512 is the constant precision
|
||||||
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
|
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
|
||||||
check.errorf(atPos(opPos), _InvalidConstVal, "constant %s overflow", opName(x.expr))
|
op := opName(x.expr)
|
||||||
|
if op != "" {
|
||||||
|
op += " "
|
||||||
|
}
|
||||||
|
check.errorf(atPos(opPos), _InvalidConstVal, "constant %soverflow", op)
|
||||||
x.val = constant.MakeUnknown()
|
x.val = constant.MakeUnknown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1300,6 +1304,8 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||||||
check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value)
|
check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value)
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
// Ensure that integer values don't overflow (issue #54280).
|
||||||
|
check.overflow(x, e.Pos())
|
||||||
|
|
||||||
case *ast.FuncLit:
|
case *ast.FuncLit:
|
||||||
if sig, ok := check.typ(e.Type).(*Signature); ok {
|
if sig, ok := check.typ(e.Type).(*Signature); ok {
|
||||||
|
7
src/go/types/testdata/fixedbugs/issue54280.go
vendored
Normal file
7
src/go/types/testdata/fixedbugs/issue54280.go
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow
|
@ -24,12 +24,12 @@ import (
|
|||||||
// which declares an untyped constant of the given length.
|
// which declares an untyped constant of the given length.
|
||||||
// testProg compiles this package and checks for the absence or
|
// testProg compiles this package and checks for the absence or
|
||||||
// presence of a constant literal error.
|
// presence of a constant literal error.
|
||||||
func testProg(dir, name string, length int, ok bool) {
|
func testProg(dir, name string, length int, msg string) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
fmt.Fprintf(&buf,
|
fmt.Fprintf(&buf,
|
||||||
"package %s; const _ = %s // %d digits",
|
"package %s; const _ = 0b%s // %d bits",
|
||||||
name, strings.Repeat("9", length), length,
|
name, strings.Repeat("1", length), length,
|
||||||
)
|
)
|
||||||
|
|
||||||
filename := filepath.Join(dir, fmt.Sprintf("%s.go", name))
|
filename := filepath.Join(dir, fmt.Sprintf("%s.go", name))
|
||||||
@ -41,7 +41,7 @@ func testProg(dir, name string, length int, ok bool) {
|
|||||||
cmd.Dir = dir
|
cmd.Dir = dir
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
|
|
||||||
if ok {
|
if msg == "" {
|
||||||
// no error expected
|
// no error expected
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("%s: compile failed unexpectedly: %v", name, err)
|
log.Fatalf("%s: compile failed unexpectedly: %v", name, err)
|
||||||
@ -53,7 +53,7 @@ func testProg(dir, name string, length int, ok bool) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
log.Fatalf("%s: compile succeeded unexpectedly", name)
|
log.Fatalf("%s: compile succeeded unexpectedly", name)
|
||||||
}
|
}
|
||||||
if !bytes.Contains(output, []byte("excessively long constant")) {
|
if !bytes.Contains(output, []byte(msg)) {
|
||||||
log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output)
|
log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,7 +69,10 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
const limit = 10000 // compiler-internal constant length limit
|
const bitLimit = 512
|
||||||
testProg(dir, "x1", limit, true)
|
const charLimit = 10000 // compiler-internal constant length limit
|
||||||
testProg(dir, "x2", limit+1, false)
|
testProg(dir, "x1", bitLimit, "")
|
||||||
|
testProg(dir, "x2", bitLimit+1, "constant overflow")
|
||||||
|
testProg(dir, "x3", charLimit-2, "constant overflow") // -2 because literal contains 0b prefix
|
||||||
|
testProg(dir, "x4", charLimit-1, "excessively long constant")
|
||||||
}
|
}
|
||||||
|
11
test/fixedbugs/issue54280.go
Normal file
11
test/fixedbugs/issue54280.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// errorcheck
|
||||||
|
|
||||||
|
// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Don't crash in export of oversized integer constant.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR "constant overflow"
|
Loading…
x
Reference in New Issue
Block a user