summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala93
-rw-r--r--test/files/run/t6632.check3
-rw-r--r--test/files/run/t6632.scala29
-rw-r--r--test/files/run/t6633.check3
-rw-r--r--test/files/run/t6633.scala33
5 files changed, 112 insertions, 49 deletions
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index 53b2b57f50..53501a7267 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -129,29 +129,27 @@ final class ListBuffer[A]
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
def update(n: Int, x: A) {
- try {
- if (exported) copy()
- if (n == 0) {
- val newElem = new :: (x, start.tail);
- if (last0 eq start) {
- last0 = newElem
- }
- start = newElem
- } else {
- var cursor = start
- var i = 1
- while (i < n) {
- cursor = cursor.tail
- i += 1
- }
- val newElem = new :: (x, cursor.tail.tail)
- if (last0 eq cursor.tail) {
- last0 = newElem
- }
- cursor.asInstanceOf[::[A]].tl = newElem
+ // We check the bounds early, so that we don't trigger copying.
+ if (n < 0 || n >= len) throw new IndexOutOfBoundsException(n.toString)
+ if (exported) copy()
+ if (n == 0) {
+ val newElem = new :: (x, start.tail);
+ if (last0 eq start) {
+ last0 = newElem
+ }
+ start = newElem
+ } else {
+ var cursor = start
+ var i = 1
+ while (i < n) {
+ cursor = cursor.tail
+ i += 1
+ }
+ val newElem = new :: (x, cursor.tail.tail)
+ if (last0 eq cursor.tail) {
+ last0 = newElem
}
- } catch {
- case ex: Exception => throw new IndexOutOfBoundsException(n.toString())
+ cursor.asInstanceOf[::[A]].tl = newElem
}
}
@@ -212,34 +210,31 @@ final class ListBuffer[A]
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
def insertAll(n: Int, seq: Traversable[A]) {
- try {
- if (exported) copy()
- var elems = seq.toList.reverse
- len += elems.length
- if (n == 0) {
- while (!elems.isEmpty) {
- val newElem = new :: (elems.head, start)
- if (start.isEmpty) last0 = newElem
- start = newElem
- elems = elems.tail
- }
- } else {
- var cursor = start
- var i = 1
- while (i < n) {
- cursor = cursor.tail
- i += 1
- }
- while (!elems.isEmpty) {
- val newElem = new :: (elems.head, cursor.tail)
- if (cursor.tail.isEmpty) last0 = newElem
- cursor.asInstanceOf[::[A]].tl = newElem
- elems = elems.tail
- }
+ // We check the bounds early, so that we don't trigger copying.
+ if (n < 0 || n > len) throw new IndexOutOfBoundsException(n.toString)
+ if (exported) copy()
+ var elems = seq.toList.reverse
+ len += elems.length
+ if (n == 0) {
+ while (!elems.isEmpty) {
+ val newElem = new :: (elems.head, start)
+ if (start.isEmpty) last0 = newElem
+ start = newElem
+ elems = elems.tail
+ }
+ } else {
+ var cursor = start
+ var i = 1
+ while (i < n) {
+ cursor = cursor.tail
+ i += 1
+ }
+ while (!elems.isEmpty) {
+ val newElem = new :: (elems.head, cursor.tail)
+ if (cursor.tail.isEmpty) last0 = newElem
+ cursor.asInstanceOf[::[A]].tl = newElem
+ elems = elems.tail
}
- } catch {
- case ex: Exception =>
- throw new IndexOutOfBoundsException(n.toString())
}
}
diff --git a/test/files/run/t6632.check b/test/files/run/t6632.check
new file mode 100644
index 0000000000..1f084b1dac
--- /dev/null
+++ b/test/files/run/t6632.check
@@ -0,0 +1,3 @@
+java.lang.IndexOutOfBoundsException: -1
+java.lang.IndexOutOfBoundsException: -2
+java.lang.IndexOutOfBoundsException: -3
diff --git a/test/files/run/t6632.scala b/test/files/run/t6632.scala
new file mode 100644
index 0000000000..c1c8d4abe0
--- /dev/null
+++ b/test/files/run/t6632.scala
@@ -0,0 +1,29 @@
+object Test extends App {
+ import collection.mutable.ListBuffer
+
+ def newLB = ListBuffer('a, 'b, 'c, 'd, 'e)
+
+ val lb0 = newLB
+
+ try {
+ lb0.insert(-1, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb1 = newLB
+
+ try {
+ lb1.insertAll(-2, Array('x, 'y, 'z))
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb2 = newLB
+
+ try {
+ lb2.update(-3, 'u)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6633.check b/test/files/run/t6633.check
new file mode 100644
index 0000000000..1ff8cdbc44
--- /dev/null
+++ b/test/files/run/t6633.check
@@ -0,0 +1,3 @@
+java.lang.IndexOutOfBoundsException: 9
+replStringOf OK
+length OK
diff --git a/test/files/run/t6633.scala b/test/files/run/t6633.scala
new file mode 100644
index 0000000000..bd993c8d88
--- /dev/null
+++ b/test/files/run/t6633.scala
@@ -0,0 +1,33 @@
+object Test extends App {
+ import collection.mutable.ListBuffer
+
+ def newLB = ListBuffer('a, 'b, 'c, 'd, 'e)
+
+ val lb0 = newLB
+
+ try {
+ lb0.insert(9, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb1 = newLB
+
+ try {
+ lb1.insert(9, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException =>
+ }
+
+ val replStr = scala.runtime.ScalaRunTime.replStringOf(lb1, 100)
+ if (replStr == "ListBuffer('a, 'b, 'c, 'd, 'e)\n")
+ println("replStringOf OK")
+ else
+ println("replStringOf FAILED: " + replStr)
+
+ val len = lb1.length
+ if (len == 5)
+ println("length OK")
+ else
+ println("length FAILED: " + len)
+} \ No newline at end of file