@@ -65,12 +65,16 @@ func (r Range) Span() (Span, error) {
65
65
return Span {}, fmt .Errorf ("file not found in FileSet" )
66
66
}
67
67
s := Span {v : span {URI : FileURI (f .Name ())}}
68
- if ! r .Start .IsValid () {
69
- return Span {}, fmt .Errorf ("invalid position for start of range" )
68
+ var err error
69
+ s .v .Start .Offset , err = offset (f , r .Start )
70
+ if err != nil {
71
+ return Span {}, err
70
72
}
71
- s .v .Start .Offset = f .Offset (r .Start )
72
73
if r .End .IsValid () {
73
- s .v .End .Offset = f .Offset (r .End )
74
+ s .v .End .Offset , err = offset (f , r .End )
75
+ if err != nil {
76
+ return Span {}, err
77
+ }
74
78
}
75
79
s .v .Start .clean ()
76
80
s .v .End .clean ()
@@ -79,6 +83,15 @@ func (r Range) Span() (Span, error) {
79
83
return s .WithPosition (converter )
80
84
}
81
85
86
+ // offset is a copy of the Offset function in go/token, but with the adjustment
87
+ // that it does not panic on invalid positions.
88
+ func offset (f * token.File , pos token.Pos ) (int , error ) {
89
+ if int (pos ) < f .Base () || int (pos ) > f .Base ()+ f .Size () {
90
+ return 0 , fmt .Errorf ("invalid pos" )
91
+ }
92
+ return int (pos ) - f .Base (), nil
93
+ }
94
+
82
95
// Range converts a Span to a Range that represents the Span for the supplied
83
96
// File.
84
97
func (s Span ) Range (converter * TokenConverter ) (Range , error ) {
@@ -121,5 +134,5 @@ func (l *TokenConverter) ToOffset(line, col int) (int, error) {
121
134
// we assume that column is in bytes here, and that the first byte of a
122
135
// line is at column 1
123
136
pos += token .Pos (col - 1 )
124
- return l .file . Offset ( pos ), nil
137
+ return offset ( l .file , pos )
125
138
}
0 commit comments