internal/lsp: handle invalid positions in semantic token debug logic

Check that a position is in range before using it.

Fixes golang/vscode-go#1656

Change-Id: I1598ebab76a1775afd8f63b9849049b31fb74a8b
Reviewed-on: https://go-review.googlesource.com/c/tools/+/339169
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Peter Weinberger <pjw@google.com>
This commit is contained in:
Rebecca Stambler 2021-08-02 13:25:24 -04:00
parent 45eff0fdb0
commit f8cfadacc8
3 changed files with 15 additions and 11 deletions

View File

@ -1072,10 +1072,10 @@ func fixArrayType(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte
// Avoid doing tok.Offset(to) since that panics if badExpr ends at EOF.
// It also panics if the position is not in the range of the file, and
// badExprs may not necessarily have good positions, so check first.
if !inRange(tok, from) {
if !source.InRange(tok, from) {
return false
}
if !inRange(tok, to-1) {
if !source.InRange(tok, to-1) {
return false
}
fromOffset := tok.Offset(from)
@ -1112,12 +1112,6 @@ func fixArrayType(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte
return replaceNode(parent, bad, at)
}
// inRange reports whether the given position is in the given token.File.
func inRange(tok *token.File, pos token.Pos) bool {
size := tok.Pos(tok.Size())
return int(pos) >= tok.Base() && pos <= size
}
// precedingToken scans src to find the token preceding pos.
func precedingToken(pos token.Pos, tok *token.File, src []byte) token.Token {
s := &scanner.Scanner{}

View File

@ -236,9 +236,13 @@ func (e *encoded) strStack() string {
}
if len(e.stack) > 0 {
loc := e.stack[len(e.stack)-1].Pos()
add := e.pgf.Tok.PositionFor(loc, false)
nm := filepath.Base(add.Filename)
msg = append(msg, fmt.Sprintf("(%s:%d,col:%d)", nm, add.Line, add.Column))
if !source.InRange(e.pgf.Tok, loc) {
msg = append(msg, fmt.Sprintf("invalid position %v for %s", loc, e.pgf.URI))
} else {
add := e.pgf.Tok.PositionFor(loc, false)
nm := filepath.Base(add.Filename)
msg = append(msg, fmt.Sprintf("(%s:%d,col:%d)", nm, add.Line, add.Column))
}
}
msg = append(msg, "]")
return strings.Join(msg, " ")

View File

@ -544,3 +544,9 @@ func IsValidImport(pkgPath, importPkgPath string) bool {
func IsCommandLineArguments(s string) bool {
return strings.Contains(s, "command-line-arguments")
}
// InRange reports whether the given position is in the given token.File.
func InRange(tok *token.File, pos token.Pos) bool {
size := tok.Pos(tok.Size())
return int(pos) >= tok.Base() && pos <= size
}