Skip to content

Commit 304b48b

Browse files
authored
Fix IllegalArgumentException: "Invalid range specified" when generating SARIF report (#1370)
1 parent 4e15b67 commit 304b48b

File tree

2 files changed

+21
-22
lines changed

2 files changed

+21
-22
lines changed

utbot-framework-test/src/test/kotlin/org/utbot/sarif/SarifReportTest.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class SarifReportTest {
7272
UtImplicitlyThrownException(NullPointerException(), false)
7373
)
7474
Mockito.`when`(mockUtExecution.stateBefore.parameters).thenReturn(listOf())
75-
Mockito.`when`(mockUtExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(1337)
75+
Mockito.`when`(mockUtExecution.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(1337)
7676
Mockito.`when`(mockUtExecution.testMethodName).thenReturn("testMain_ThrowArithmeticException")
7777

7878
val report = sarifReportMain.createReport()
@@ -243,8 +243,8 @@ class SarifReportTest {
243243
Mockito.`when`(mockUtExecution2.result).thenReturn(UtImplicitlyThrownException(NullPointerException(), false))
244244

245245
// different locations
246-
Mockito.`when`(mockUtExecution1.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(11)
247-
Mockito.`when`(mockUtExecution2.path.lastOrNull()?.stmt?.javaSourceStartLineNumber).thenReturn(22)
246+
Mockito.`when`(mockUtExecution1.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(11)
247+
Mockito.`when`(mockUtExecution2.coverage?.coveredInstructions?.lastOrNull()?.lineNumber).thenReturn(22)
248248

249249
val testSets = listOf(
250250
UtMethodTestSet(mockExecutableId, listOf(mockUtExecution1)),

utbot-framework/src/main/kotlin/org/utbot/sarif/SarifReport.kt

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ class SarifReport(
150150
if (classFqn == null)
151151
return listOf()
152152
val sourceRelativePath = sourceFinding.getSourceRelativePath(classFqn)
153-
val startLine = getLastLineNumber(utExecution) ?: defaultLineNumber
153+
val startLine = getLastLineNumber(utExecution, classFqn) ?: defaultLineNumber
154154
val sourceCode = sourceFinding.getSourceFile(classFqn)?.readText() ?: ""
155155
val sourceRegion = SarifRegion.withStartLine(sourceCode, startLine)
156156
return listOf(
@@ -317,26 +317,25 @@ class SarifReport(
317317
}
318318

319319
/**
320-
* Returns the number of the last line in the execution path.
320+
* Returns the number of the last line in the execution path which is located in the [classFqn].
321321
*/
322-
private fun getLastLineNumber(utExecution: UtExecution): Int? {
323-
// if for some reason we can't extract the last line from the path
324-
val lastCoveredInstruction =
325-
utExecution.coverage?.coveredInstructions?.lastOrNull()?.lineNumber
326-
327-
return if (utExecution is UtSymbolicExecution) {
328-
val lastPathLine = try {
329-
// path/fullPath might be empty when engine executes in another process -
330-
// soot entities cannot be passed to the main process because kryo cannot deserialize them
331-
utExecution.path.lastOrNull()?.stmt?.javaSourceStartLineNumber
332-
} catch (t: Throwable) {
333-
null
334-
}
335-
336-
lastPathLine ?: lastCoveredInstruction
337-
} else {
338-
lastCoveredInstruction
322+
private fun getLastLineNumber(utExecution: UtExecution, classFqn: String): Int? {
323+
val classFqnPath = classFqn.replace(".", "/")
324+
val coveredInstructions = utExecution.coverage?.coveredInstructions
325+
val lastCoveredInstruction = coveredInstructions?.lastOrNull { it.className == classFqnPath }
326+
?: coveredInstructions?.lastOrNull()
327+
if (lastCoveredInstruction != null)
328+
return lastCoveredInstruction.lineNumber
329+
330+
// if for some reason we can't extract the last line from the coverage
331+
val lastPathElementLineNumber = try {
332+
// path/fullPath might be empty when engine executes in another process -
333+
// soot entities cannot be passed to the main process because kryo cannot deserialize them
334+
(utExecution as? UtSymbolicExecution)?.path?.lastOrNull()?.stmt?.javaSourceStartLineNumber
335+
} catch (t: Throwable) {
336+
null
339337
}
338+
return lastPathElementLineNumber
340339
}
341340

342341
private fun shouldProcessExecutionResult(result: UtExecutionResult): Boolean {

0 commit comments

Comments
 (0)