From 8b6e84ba2a8cd15d9d3917c46472d3b82187ef55 Mon Sep 17 00:00:00 2001 From: Rob Findley Date: Thu, 21 Nov 2024 18:15:31 +0000 Subject: [PATCH] gopls/internal/crash: don't crash in xrefs on out of bound nodes As we've seen many times, it is currently (unfortunately) possible that go/ast nodes exceed the bounds of the parsed file. Handle this possibility correctly while building the xrefs index. Updates golang/go#66683 Fixes golang/go#70446 Change-Id: If6364876eb7b8ed8ca11a058417aa028d6b55b41 Reviewed-on: https://go-review.googlesource.com/c/tools/+/630675 LUCI-TryBot-Result: Go LUCI Auto-Submit: Robert Findley Reviewed-by: Alan Donovan --- gopls/internal/cache/xrefs/xrefs.go | 36 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/gopls/internal/cache/xrefs/xrefs.go b/gopls/internal/cache/xrefs/xrefs.go index 4113e08716e..2115322bfdc 100644 --- a/gopls/internal/cache/xrefs/xrefs.go +++ b/gopls/internal/cache/xrefs/xrefs.go @@ -17,6 +17,7 @@ import ( "golang.org/x/tools/gopls/internal/cache/metadata" "golang.org/x/tools/gopls/internal/cache/parsego" "golang.org/x/tools/gopls/internal/protocol" + "golang.org/x/tools/gopls/internal/util/bug" "golang.org/x/tools/gopls/internal/util/frob" ) @@ -43,15 +44,6 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info) []byte { objectpathFor := new(objectpath.Encoder).For for fileIndex, pgf := range files { - - nodeRange := func(n ast.Node) protocol.Range { - rng, err := pgf.PosRange(n.Pos(), n.End()) - if err != nil { - panic(err) // can't fail - } - return rng - } - ast.Inspect(pgf.File, func(n ast.Node) bool { switch n := n.(type) { case *ast.Ident: @@ -82,10 +74,15 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info) []byte { objects[obj] = gobObj } - gobObj.Refs = append(gobObj.Refs, gobRef{ - FileIndex: fileIndex, - Range: nodeRange(n), - }) + // golang/go#66683: nodes can under/overflow the file. + // For example, "var _ = x." creates a SelectorExpr(Sel=Ident("_")) + // that is beyond EOF. (Arguably Ident.Name should be "".) + if rng, err := pgf.NodeRange(n); err == nil { + gobObj.Refs = append(gobObj.Refs, gobRef{ + FileIndex: fileIndex, + Range: rng, + }) + } } } @@ -102,10 +99,15 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info) []byte { gobObj = &gobObject{Path: ""} objects[nil] = gobObj } - gobObj.Refs = append(gobObj.Refs, gobRef{ - FileIndex: fileIndex, - Range: nodeRange(n.Path), - }) + // golang/go#66683: nodes can under/overflow the file. + if rng, err := pgf.NodeRange(n.Path); err == nil { + gobObj.Refs = append(gobObj.Refs, gobRef{ + FileIndex: fileIndex, + Range: rng, + }) + } else { + bug.Reportf("out of bounds import spec %+v", n.Path) + } } return true })