Skip to content

Commit b0be384

Browse files
Alexey MenshutinCaelmBleidd
authored andcommitted
Fix stack overflow error in AssembleModelGenerator.kt for arrays
1 parent e6bb7f7 commit b0be384

4 files changed

Lines changed: 36 additions & 11 deletions

File tree

utbot-framework-api/src/main/kotlin/org/utbot/framework/plugin/api/Api.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ data class UtArrayModel(
420420
override val id: Int,
421421
override val classId: ClassId,
422422
val length: Int = 0,
423-
val constModel: UtModel,
423+
var constModel: UtModel,
424424
val stores: MutableMap<Int, UtModel>
425425
) : UtReferenceModel(id, classId) {
426426
override fun toString() = withToStringThreadLocalReentrancyGuard {

utbot-framework/src/main/kotlin/org/utbot/framework/assemble/AssembleModelGenerator.kt

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,19 +195,24 @@ class AssembleModelGenerator(private val methodUnderTest: UtMethod<*>) {
195195
/**
196196
* Assembles internal structure of [UtArrayModel].
197197
*/
198-
private fun assembleArrayModel(arrayModel: UtArrayModel): UtModel {
199-
instantiatedModels[arrayModel]?.let { return it }
198+
private fun assembleArrayModel(arrayModel: UtArrayModel): UtModel =
199+
with(arrayModel) {
200+
instantiatedModels[this]?.let { return it }
200201

201-
val constModel = assembleModel(arrayModel.constModel)
202-
val stores = arrayModel.stores
203-
.mapValues { assembleModel(it.value) }
204-
.toMutableMap()
202+
// Note that we use constModel from the source model as is here to avoid
203+
// possible stack overflow error in case when const model has the same
204+
// id as the source one. Later we will try to transform it.
205+
val assembleModel = UtArrayModel(id, classId, length, constModel, stores = mutableMapOf())
205206

206-
val assembleModel = UtArrayModel(arrayModel.id, arrayModel.classId, arrayModel.length, constModel, stores)
207+
instantiatedModels[this] = assembleModel
207208

208-
instantiatedModels[arrayModel] = assembleModel
209-
return assembleModel
210-
}
209+
assembleModel.constModel = assembleModel(constModel)
210+
assembleModel.stores += stores
211+
.mapValues { assembleModel(it.value) }
212+
.toMutableMap()
213+
214+
assembleModel
215+
}
211216

212217
/**
213218
* Assembles internal structure of [UtCompositeModel] if possible and handles assembling exceptions.

utbot-framework/src/test/kotlin/org/utbot/examples/arrays/ArrayOfArraysTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,14 @@ internal class ArrayOfArraysTest : AbstractTestCaseGeneratorTest(testClass = Arr
266266
{ valueBefore, valueAfter -> valueAfter.withIndex().all { it.value == valueBefore[it.index] + it.index } }
267267
)
268268
}
269+
270+
@Test
271+
fun testArrayWithItselfAnAsElement() {
272+
check(
273+
ArrayOfArrays::arrayWithItselfAnAsElement,
274+
eq(2),
275+
coverage = atLeast(percents = 94)
276+
// because of the assumption
277+
)
278+
}
269279
}

utbot-sample/src/main/java/org/utbot/examples/arrays/ArrayOfArrays.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,14 @@ public int[][] fillMultiArrayWithArray(int[] value) {
152152

153153
return array;
154154
}
155+
156+
public Object[] arrayWithItselfAnAsElement(Object[] array) {
157+
UtMock.assume(array != null && array.length > 0);
158+
159+
if (array[0] == array) {
160+
return array;
161+
}
162+
163+
return null;
164+
}
155165
}

0 commit comments

Comments
 (0)