From 79af862e6737e9b6ea995ccf9e8eaccd41ef1523 Mon Sep 17 00:00:00 2001 From: Rebecca Stambler Date: Tue, 26 Mar 2019 21:02:11 -0400 Subject: [PATCH] internal/span: switch to an offset function that doesn't panic go/token.File.Offset panics on invalid positions, which is causing crashes on invalid ASTs. Change-Id: I6c698760ae92f3076a056c3560bea2e8eeb528db Reviewed-on: https://go-review.googlesource.com/c/tools/+/169443 Reviewed-by: Ian Cottrell --- internal/span/token.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/internal/span/token.go b/internal/span/token.go index fb4d16d5..0fc0169d 100644 --- a/internal/span/token.go +++ b/internal/span/token.go @@ -65,12 +65,16 @@ func (r Range) Span() (Span, error) { return Span{}, fmt.Errorf("file not found in FileSet") } s := Span{v: span{URI: FileURI(f.Name())}} - if !r.Start.IsValid() { - return Span{}, fmt.Errorf("invalid position for start of range") + var err error + s.v.Start.Offset, err = offset(f, r.Start) + if err != nil { + return Span{}, err } - s.v.Start.Offset = f.Offset(r.Start) if r.End.IsValid() { - s.v.End.Offset = f.Offset(r.End) + s.v.End.Offset, err = offset(f, r.End) + if err != nil { + return Span{}, err + } } s.v.Start.clean() s.v.End.clean() @@ -79,6 +83,15 @@ func (r Range) Span() (Span, error) { return s.WithPosition(converter) } +// offset is a copy of the Offset function in go/token, but with the adjustment +// that it does not panic on invalid positions. +func offset(f *token.File, pos token.Pos) (int, error) { + if int(pos) < f.Base() || int(pos) > f.Base()+f.Size() { + return 0, fmt.Errorf("invalid pos") + } + return int(pos) - f.Base(), nil +} + // Range converts a Span to a Range that represents the Span for the supplied // File. func (s Span) Range(converter *TokenConverter) (Range, error) { @@ -121,5 +134,5 @@ func (l *TokenConverter) ToOffset(line, col int) (int, error) { // we assume that column is in bytes here, and that the first byte of a // line is at column 1 pos += token.Pos(col - 1) - return l.file.Offset(pos), nil + return offset(l.file, pos) }