From 925c6e34635a9a8621b20c328670cbd23975327f Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Fri, 9 Nov 2012 03:18:33 +0100 Subject: SI-6632 SI-6633 Fixes issues and data corruption in ListBuffer - Disallow negative positions for ListBuffer#insert/insertAll/update - Fix data corruption issue in ListBuffer#insert --- .../scala/collection/mutable/ListBuffer.scala | 93 ++++++++++------------ 1 file changed, 44 insertions(+), 49 deletions(-) (limited to 'src/library') 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()) } } -- cgit v1.2.3