internal/span: catch potential panics in go/token

Updates golang/go#32639

Change-Id: Ib413fc316af4308d8928647ff36a437d243a9c11
Reviewed-on: https://go-review.googlesource.com/c/tools/+/184038
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/span/token.go b/internal/span/token.go
index 406da4a..4efd0c8 100644
--- a/internal/span/token.go
+++ b/internal/span/token.go
@@ -99,6 +99,14 @@
 	if err != nil {
 		return Range{}, err
 	}
+	// go/token will panic if the offset is larger than the file's size,
+	// so check here to avoid panicking.
+	if s.Start().Offset() > converter.file.Size() {
+		return Range{}, fmt.Errorf("start offset %v is past the end of the file", s.Start())
+	}
+	if s.End().Offset() > converter.file.Size() {
+		return Range{}, fmt.Errorf("end offset %v is past the end of the file", s.End())
+	}
 	return Range{
 		FileSet: converter.fset,
 		Start:   converter.file.Pos(s.Start().Offset()),
@@ -107,7 +115,9 @@
 }
 
 func (l *TokenConverter) ToPosition(offset int) (int, int, error) {
-	//TODO: check offset fits in file
+	if offset > l.file.Size() {
+		return 0, 0, fmt.Errorf("offset %v is past the end of the file", offset)
+	}
 	pos := l.file.Pos(offset)
 	p := l.fset.Position(pos)
 	return p.Line, p.Column, nil