summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/Iterator.scala3
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala5
-rw-r--r--src/library/scala/collection/mutable/ArraySeq.scala2
-rw-r--r--src/library/scala/collection/mutable/ResizableArray.scala2
-rw-r--r--test/files/run/t6827.check12
-rw-r--r--test/files/run/t6827.scala20
6 files changed, 31 insertions, 13 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index adb97e27e3..4e3abf2286 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -1187,9 +1187,8 @@ trait Iterator[+A] extends TraversableOnce[A] {
* $willNotTerminateInf
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Unit = {
- require(start >= 0 && (start < xs.length || xs.length == 0), s"start $start out of range ${xs.length}")
var i = start
- val end = start + math.min(len, xs.length - start)
+ val end = start + math.min(len, xs.length - start)
while (i < end && hasNext) {
xs(i) = next()
i += 1
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 00491ef20e..2bc41b5802 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -40,9 +40,8 @@ trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParalleliza
arrayElementClass(repr.getClass)
override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) {
- var l = math.min(len, repr.length)
- if (xs.length - start < l) l = xs.length - start max 0
- Array.copy(repr, 0, xs, start, l)
+ val l = len min repr.length min (xs.length - start)
+ if (l > 0) Array.copy(repr, 0, xs, start, l)
}
override def toArray[U >: T : ClassTag]: Array[U] = {
diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala
index 577a838315..5a50f4fb27 100644
--- a/src/library/scala/collection/mutable/ArraySeq.scala
+++ b/src/library/scala/collection/mutable/ArraySeq.scala
@@ -87,7 +87,7 @@ extends AbstractSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
override def clone(): ArraySeq[A] = {
diff --git a/src/library/scala/collection/mutable/ResizableArray.scala b/src/library/scala/collection/mutable/ResizableArray.scala
index c3047522e2..85a299216e 100644
--- a/src/library/scala/collection/mutable/ResizableArray.scala
+++ b/src/library/scala/collection/mutable/ResizableArray.scala
@@ -74,7 +74,7 @@ trait ResizableArray[A] extends IndexedSeq[A]
*/
override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) {
val len1 = len min (xs.length - start) min length
- Array.copy(array, 0, xs, start, len1)
+ if (len1 > 0) Array.copy(array, 0, xs, start, len1)
}
//##########################################################################
diff --git a/test/files/run/t6827.check b/test/files/run/t6827.check
index 3a3a71c67d..4889e05be8 100644
--- a/test/files/run/t6827.check
+++ b/test/files/run/t6827.check
@@ -1,6 +1,6 @@
-start at -5: java.lang.IllegalArgumentException: requirement failed: start -5 out of range 10
-start at -1: java.lang.IllegalArgumentException: requirement failed: start -1 out of range 10
-start at limit: java.lang.IllegalArgumentException: requirement failed: start 10 out of range 10
+start at -5: java.lang.ArrayIndexOutOfBoundsException: -5
+start at -1: java.lang.ArrayIndexOutOfBoundsException: -1
+start at limit: ok
start at limit-1: ok
first 10: ok
read all: ok
@@ -8,8 +8,8 @@ test huge len: ok
5 from 5: ok
20 from 5: ok
test len overflow: ok
-start beyond limit: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
+start beyond limit: ok
read 0: ok
read -1: ok
-invalid read 0: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
-invalid read -1: java.lang.IllegalArgumentException: requirement failed: start 30 out of range 10
+invalid read 0: ok
+invalid read -1: ok
diff --git a/test/files/run/t6827.scala b/test/files/run/t6827.scala
index 8e17af09e2..eb020711bb 100644
--- a/test/files/run/t6827.scala
+++ b/test/files/run/t6827.scala
@@ -31,4 +31,24 @@ object Test extends App {
// okay, see SI-7128
"...".toIterator.copyToArray(new Array[Char](0), 0, 0)
+
+
+ // Bonus test from @som-snytt to check for overflow in
+ // index calculations.
+ def testOverflow(start: Int, len: Int, expected: List[Char]) {
+ def copyFromIterator = {
+ val arr = Array.fill[Char](3)('-')
+ "abc".toIterator.copyToArray(arr, start, len)
+ arr.toList
+ }
+ def copyFromArray = {
+ val arr = Array.fill[Char](3)('-')
+ "abc".toArray.copyToArray(arr, start, len)
+ arr.toList
+ }
+ assert(copyFromIterator == expected)
+ assert(copyFromArray == expected)
+ }
+ testOverflow(1, Int.MaxValue - 1, "-ab".toList)
+ testOverflow(1, Int.MaxValue, "-ab".toList)
}