Skip to content

Commit

Permalink
gopls/internal/crash: don't crash in xrefs on out of bound nodes
Browse files Browse the repository at this point in the history
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 <[email protected]>
Auto-Submit: Robert Findley <[email protected]>
Reviewed-by: Alan Donovan <[email protected]>
  • Loading branch information
findleyr authored and gopherbot committed Nov 21, 2024
1 parent 936a401 commit 8b6e84b
Showing 1 changed file with 19 additions and 17 deletions.
36 changes: 19 additions & 17 deletions gopls/internal/cache/xrefs/xrefs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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:
Expand Down Expand Up @@ -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,
})
}
}
}

Expand All @@ -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
})
Expand Down

0 comments on commit 8b6e84b

Please sign in to comment.