Skip to content

Commit 8d38122

Browse files
findleyrgopherbot
authored andcommitted
gopls/internal/cache: reproduce and fix crash on if cond overflow
Through reverse engineering, I was able to reproduce the overflow of golang/go#72026, and verify the fix of CL 653596. Along the way, I incidentally reproduced golang/go#66766, which I think we can safely ignore now that we understand it. Updates golang/go#72026 Fixes golang/go#66766 Change-Id: I2131d771c13688c1ad47f6bc6285e524fb4c04a1 Reviewed-on: https://go-review.googlesource.com/c/tools/+/654336 Reviewed-by: Alan Donovan <[email protected]> Auto-Submit: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent d81d6fc commit 8d38122

File tree

3 files changed

+25
-8
lines changed

3 files changed

+25
-8
lines changed

gopls/internal/cache/check.go

+7-8
Original file line numberDiff line numberDiff line change
@@ -2005,15 +2005,14 @@ func typeErrorsToDiagnostics(pkg *syntaxPackage, inputs *typeCheckInputs, errs [
20052005
posn := safetoken.StartPosition(e.Fset, start)
20062006
if !posn.IsValid() {
20072007
// All valid positions produced by the type checker should described by
2008-
// its fileset.
2008+
// its fileset, yet since type checker errors are associated with
2009+
// positions in the AST, and AST nodes can overflow the file
2010+
// (golang/go#48300), we can't rely on this.
20092011
//
2010-
// Note: in golang/go#64488, we observed an error that was positioned
2011-
// over fixed syntax, which overflowed its file. So it's definitely
2012-
// possible that we get here (it's hard to reason about fixing up the
2013-
// AST). Nevertheless, it's a bug.
2014-
if pkg.hasFixedFiles() {
2015-
bug.Reportf("internal error: type checker error %q outside its Fset (fixed files)", e)
2016-
} else {
2012+
// We should fix the parser, but in the meantime type errors are not
2013+
// significant if there are parse errors, so we can safely ignore this
2014+
// case.
2015+
if len(pkg.parseErrors) == 0 {
20172016
bug.Reportf("internal error: type checker error %q outside its Fset", e)
20182017
}
20192018
continue

gopls/internal/cache/parsego/parse.go

+1
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ func fixInitStmt(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte)
532532
if err != nil {
533533
return false
534534
}
535+
assert(end <= len(src), "offset overflow") // golang/go#72026
535536
stmtBytes := src[start:end]
536537
stmt, err := parseStmt(tok, bad.Pos(), stmtBytes)
537538
if err != nil {

gopls/internal/test/integration/completion/fixedbugs_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,20 @@ package
3838
}
3939
})
4040
}
41+
42+
func TestFixInitStatementCrash_Issue72026(t *testing.T) {
43+
// This test checks that we don't crash when the if condition overflows the
44+
// file (as is possible with a malformed struct type).
45+
46+
const files = `
47+
-- go.mod --
48+
module example.com
49+
50+
go 1.18
51+
`
52+
53+
Run(t, files, func(t *testing.T, env *Env) {
54+
env.CreateBuffer("p.go", "package p\nfunc _() {\n\tfor i := struct")
55+
env.AfterChange()
56+
})
57+
}

0 commit comments

Comments
 (0)