Handle container builders capacity overflow
This commit is contained in:
committed by
Space
parent
f8bcba0b76
commit
cca5f82aa0
@@ -143,6 +143,7 @@ actual class ArrayList<E> private constructor(
|
||||
|
||||
final actual fun ensureCapacity(minCapacity: Int) {
|
||||
if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList
|
||||
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
||||
if (minCapacity > array.size) {
|
||||
val newSize = ArrayDeque.newCapacity(array.size, minCapacity)
|
||||
array = array.copyOfUninitializedElements(newSize)
|
||||
|
||||
@@ -180,6 +180,7 @@ actual class HashMap<K, V> private constructor(
|
||||
}
|
||||
|
||||
private fun ensureCapacity(capacity: Int) {
|
||||
if (capacity < 0) throw OutOfMemoryError() // overflow
|
||||
if (capacity > this.capacity) {
|
||||
var newSize = this.capacity * 3 / 2
|
||||
if (capacity > newSize) newSize = capacity
|
||||
|
||||
@@ -178,6 +178,7 @@ internal class ListBuilder<E> private constructor(
|
||||
|
||||
private fun ensureCapacity(minCapacity: Int) {
|
||||
if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ListBuilder
|
||||
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
||||
if (minCapacity > array.size) {
|
||||
val newSize = ArrayDeque.newCapacity(array.size, minCapacity)
|
||||
array = array.copyOfUninitializedElements(newSize)
|
||||
|
||||
@@ -177,6 +177,7 @@ internal class MapBuilder<K, V> private constructor(
|
||||
}
|
||||
|
||||
private fun ensureCapacity(capacity: Int) {
|
||||
if (capacity < 0) throw OutOfMemoryError() // overflow
|
||||
if (capacity > this.capacity) {
|
||||
var newSize = this.capacity * 3 / 2
|
||||
if (capacity > newSize) newSize = capacity
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
package test.collections
|
||||
|
||||
import kotlin.collections.builders.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertSame
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.*
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER")
|
||||
class ListBuilderTest {
|
||||
@@ -57,4 +55,22 @@ class ListBuilderTest {
|
||||
testToArray(numberOfElements + 1) { (this as java.util.Collection<Int>).toArray(it) }
|
||||
testToArray(numberOfElements + 2) { (this as java.util.Collection<Int>).toArray(it) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun capacityOverflow() {
|
||||
val builderSize = 15
|
||||
val giantListSize = Int.MAX_VALUE - builderSize + 1
|
||||
|
||||
val giantList = object : AbstractList<String>() {
|
||||
override val size: Int get() = giantListSize
|
||||
override fun get(index: Int): String = "element"
|
||||
}
|
||||
|
||||
buildList {
|
||||
repeat(builderSize) { add("element") }
|
||||
|
||||
assertFails { addAll(giantList) }
|
||||
assertEquals(builderSize, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test.collections
|
||||
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFails
|
||||
import kotlin.test.Test
|
||||
|
||||
class MapBuilderTest {
|
||||
|
||||
@Test
|
||||
fun capacityOverflow() {
|
||||
val builderSize = 15
|
||||
val giantMapSize = Int.MAX_VALUE - builderSize + 1
|
||||
|
||||
val giantMap = object : AbstractMap<Int, String>() {
|
||||
override val entries: Set<Map.Entry<Int, String>> = object : AbstractSet<Map.Entry<Int, String>>() {
|
||||
override val size: Int get() = giantMapSize
|
||||
override fun iterator(): Iterator<Map.Entry<Int, String>> {
|
||||
return indexSequence().map {
|
||||
object : Map.Entry<Int, String> {
|
||||
override val key: Int get() = it
|
||||
override val value: String get() = "value"
|
||||
}
|
||||
}.take(size).iterator()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildMap {
|
||||
repeat(builderSize) { put(-it, "value") }
|
||||
|
||||
assertFails { putAll(giantMap) }
|
||||
assertEquals(builderSize, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user