Skip to content

Commit 26d1af2

Browse files
committed
gopls/internal/cache/parsego: fix OOB panic in fixAST
The indices to the src[::] slice operation were not the indices validated by the call to safetoken.Offsets. I tried a couple of dozen incomplete expressions at EOF but was unfortunately unable to trigger the crash. Still, this is a principled fix. Fixes golang/go#70745 Change-Id: Ia24c19e074517e8dd766cbf126d702f013392417 Reviewed-on: https://go-review.googlesource.com/c/tools/+/639397 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent bf516ba commit 26d1af2

File tree

1 file changed

+6
-15
lines changed

1 file changed

+6
-15
lines changed

gopls/internal/cache/parsego/parse.go

+6-15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"go/scanner"
2222
"go/token"
2323
"reflect"
24+
"slices"
2425

2526
"golang.org/x/tools/gopls/internal/label"
2627
"golang.org/x/tools/gopls/internal/protocol"
@@ -629,27 +630,17 @@ func readKeyword(pos token.Pos, tok *token.File, src []byte) string {
629630
func fixArrayType(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte) bool {
630631
// Our expected input is a bad expression that looks like "[]someExpr".
631632

632-
from := bad.Pos()
633-
to := bad.End()
634-
635-
if !from.IsValid() || !to.IsValid() {
636-
return false
637-
}
638-
639-
exprBytes := make([]byte, 0, int(to-from)+3)
640-
// Avoid doing tok.Offset(to) since that panics if badExpr ends at EOF.
641-
// It also panics if the position is not in the range of the file, and
642-
// badExprs may not necessarily have good positions, so check first.
643-
fromOffset, toOffset, err := safetoken.Offsets(tok, from, to-1)
633+
from, to := bad.Pos(), bad.End()
634+
fromOffset, toOffset, err := safetoken.Offsets(tok, from, to)
644635
if err != nil {
645636
return false
646637
}
647-
exprBytes = append(exprBytes, src[fromOffset:toOffset+1]...)
648-
exprBytes = bytes.TrimSpace(exprBytes)
638+
639+
exprBytes := bytes.TrimSpace(slices.Clone(src[fromOffset:toOffset]))
649640

650641
// If our expression ends in "]" (e.g. "[]"), add a phantom selector
651642
// so we can complete directly after the "[]".
652-
if len(exprBytes) > 0 && exprBytes[len(exprBytes)-1] == ']' {
643+
if bytes.HasSuffix(exprBytes, []byte("]")) {
653644
exprBytes = append(exprBytes, '_')
654645
}
655646

0 commit comments

Comments
 (0)