@@ -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