summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/reflect/scala/reflect/internal/util/SourceFile.scala6
-rw-r--r--test/junit/scala/reflect/internal/util/SourceFileTest.scala33
2 files changed, 36 insertions, 3 deletions
diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala
index 9866b043bb..add072aa71 100644
--- a/src/reflect/scala/reflect/internal/util/SourceFile.scala
+++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala
@@ -40,8 +40,8 @@ abstract class SourceFile {
def lineToString(index: Int): String = {
val start = lineToOffset(index)
var end = start
- while (!isEndOfLine(end)) end += 1
- content.slice(start, end) mkString ""
+ while (!isEndOfLine(end) && end <= length) end += 1
+ new String(content, start, end - start)
}
@tailrec
@@ -136,7 +136,7 @@ class BatchSourceFile(val file : AbstractFile, val content0: Array[Char]) extend
private def charAtIsEOL(idx: Int)(p: Char => Boolean) = {
// don't identify the CR in CR LF as a line break, since LF will do.
- def notCRLF0 = content(idx) != CR || idx + 1 >= length || content(idx + 1) != LF
+ def notCRLF0 = content(idx) != CR || !content.isDefinedAt(idx + 1) || content(idx + 1) != LF
idx < length && notCRLF0 && p(content(idx))
}
diff --git a/test/junit/scala/reflect/internal/util/SourceFileTest.scala b/test/junit/scala/reflect/internal/util/SourceFileTest.scala
new file mode 100644
index 0000000000..bbd5685ef7
--- /dev/null
+++ b/test/junit/scala/reflect/internal/util/SourceFileTest.scala
@@ -0,0 +1,33 @@
+package scala.reflect.internal.util
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class SourceFileTest {
+ def lineContentOf(code: String, offset: Int) =
+ Position.offset(new BatchSourceFile("", code), offset).lineContent
+
+ @Test
+ def si8205_overflow(): Unit = {
+ val file = new BatchSourceFile("", "code no newline")
+ // the bug in lineToString counted until MaxValue, and the AIOOBE came from here
+ assertFalse(file.isEndOfLine(Int.MaxValue))
+ }
+
+ @Test
+ def si8205_lineToString(): Unit = {
+ assertEquals("", lineContentOf("", 0))
+ assertEquals("abc", lineContentOf("abc", 0))
+ assertEquals("abc", lineContentOf("abc", 3))
+ assertEquals("code no newline", lineContentOf("code no newline", 1))
+ assertEquals("", lineContentOf("\n", 0))
+ assertEquals("abc", lineContentOf("abc\ndef", 0))
+ assertEquals("abc", lineContentOf("abc\ndef", 3))
+ assertEquals("def", lineContentOf("abc\ndef", 4))
+ assertEquals("def", lineContentOf("abc\ndef", 6))
+ assertEquals("def", lineContentOf("abc\ndef\n", 7))
+ }
+}