Skip to content

Commit b26740d

Browse files
authored
Merge pull request #5991 from dotty-staging/ide/harden-pos
IDE: Guard against out of bounds positions in requests
2 parents df8f79f + b79f961 commit b26740d

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

compiler/src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ class SourceFile(val file: AbstractFile, computeContent: => Array[Char]) extends
115115
/** Map line to offset of first character in line */
116116
def lineToOffset(index: Int): Int = lineIndices(index)
117117

118+
/** Like `lineToOffset`, but doesn't crash if the index is out of bounds. */
119+
def lineToOffsetOpt(index: Int): Option[Int] =
120+
if (index < 0 || index >= lineIndices.length)
121+
None
122+
else
123+
Some(lineToOffset(index))
124+
118125
/** A cache to speed up offsetToLine searches to similar lines */
119126
private[this] var lastLine = 0
120127

language-server/src/dotty/tools/languageserver/DottyLanguageServer.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,10 +651,15 @@ object DottyLanguageServer {
651651
if (isWorksheet(uri)) toWrappedPosition(pos)
652652
else pos
653653
val source = driver.openedFiles(uri)
654-
if (source.exists) {
655-
val p = Spans.Span(source.lineToOffset(actualPosition.getLine) + actualPosition.getCharacter)
656-
new SourcePosition(source, p)
657-
}
654+
if (source.exists)
655+
source.lineToOffsetOpt(actualPosition.getLine).map(_ + actualPosition.getCharacter) match {
656+
// `<=` to allow an offset to point to the end of the file
657+
case Some(offset) if offset <= source.content().length =>
658+
val p = Spans.Span(offset)
659+
new SourcePosition(source, p)
660+
case _ =>
661+
NoSourcePosition
662+
}
658663
else NoSourcePosition
659664
}
660665

0 commit comments

Comments
 (0)