[K/N] Throw OutOfMemoryError when StringBuilder overflows

This commit is contained in:
Abduqodiri Qurbonzoda
2023-05-30 22:58:51 +03:00
committed by Space Team
parent af7965d996
commit ae394caf42
2 changed files with 33 additions and 7 deletions
@@ -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 ->