[K/N] Throw OutOfMemoryError when StringBuilder overflows
This commit is contained in:
committed by
Space Team
parent
af7965d996
commit
ae394caf42
@@ -199,12 +199,8 @@ actual class StringBuilder private constructor (
|
||||
* Otherwise, this method takes no action and simply returns.
|
||||
*/
|
||||
actual fun ensureCapacity(minimumCapacity: Int) {
|
||||
if (minimumCapacity > array.size) {
|
||||
var newSize = array.size * 2 + 2
|
||||
if (minimumCapacity > newSize)
|
||||
newSize = minimumCapacity
|
||||
array = array.copyOf(newSize)
|
||||
}
|
||||
if (minimumCapacity <= array.size) return
|
||||
ensureCapacityInternal(minimumCapacity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,7 +608,15 @@ actual class StringBuilder private constructor (
|
||||
// ---------------------------- private ----------------------------
|
||||
|
||||
private fun ensureExtraCapacity(n: Int) {
|
||||
ensureCapacity(_length + n)
|
||||
ensureCapacityInternal(_length + n)
|
||||
}
|
||||
|
||||
private fun ensureCapacityInternal(minCapacity: Int) {
|
||||
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
||||
if (minCapacity > array.size) {
|
||||
val newSize = AbstractList.newCapacity(array.size, minCapacity)
|
||||
array = array.copyOf(newSize)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIndex(index: Int) {
|
||||
|
||||
@@ -272,6 +272,8 @@ class StringBuilderTest {
|
||||
repeat(Random.nextInt(35, 62)) { sb.insert(0, "s") }
|
||||
sb.ensureCapacity(1)
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
sb.ensureCapacity(-1) // negative argument is ignored
|
||||
assertTrue(sb.capacity() >= sb.length)
|
||||
sb.ensureCapacity(sb.length * 10)
|
||||
testExceptOn(TestPlatform.Js) {
|
||||
assertTrue(sb.capacity() >= sb.length * 10) // not implemented in JS
|
||||
@@ -279,6 +281,26 @@ class StringBuilderTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun overflow() = testExceptOn(TestPlatform.Js) {
|
||||
class CharSeq(override val length: Int) : CharSequence {
|
||||
override fun get(index: Int): Char =
|
||||
throw IllegalStateException("Not expected to be called")
|
||||
|
||||
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence =
|
||||
throw IllegalStateException("Not expected to be called")
|
||||
}
|
||||
|
||||
val initialContent = "a".repeat(20)
|
||||
val bigCharSeq = CharSeq(Int.MAX_VALUE - initialContent.length + 1)
|
||||
assertFailsWith<Error> { // OutOfMemoryError
|
||||
StringBuilder(initialContent).append(bigCharSeq)
|
||||
}
|
||||
assertFailsWith<Error> { // OutOfMemoryError
|
||||
StringBuilder(initialContent).insert(5, bigCharSeq)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun indexOf() {
|
||||
StringBuilder("my indexOf test").let { sb ->
|
||||
|
||||
Reference in New Issue
Block a user