diff --git a/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/JVMLanguageFrontend.kt b/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/JVMLanguageFrontend.kt index f05d27e91f..879c764df3 100644 --- a/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/JVMLanguageFrontend.kt +++ b/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/JVMLanguageFrontend.kt @@ -34,10 +34,12 @@ import de.fraunhofer.aisec.cpg.graph.types.Type import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation import java.io.File import sootup.core.inputlocation.AnalysisInputLocation +import sootup.core.model.Body import sootup.core.model.SootMethod import sootup.core.model.SourceType import sootup.core.types.ArrayType import sootup.core.types.UnknownType +import sootup.core.util.printer.NormalStmtPrinter import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation import sootup.java.bytecode.interceptors.* import sootup.java.core.JavaSootClass @@ -55,6 +57,12 @@ class JVMLanguageFrontend( val statementHandler = StatementHandler(this) val expressionHandler = ExpressionHandler(this) + lateinit var view: JavaView + + var body: Body? = null + + var printer: NormalStmtPrinter? = null + /** * Because of a limitation in SootUp, we can only specify the whole classpath for soot to parse. * But in the CPG we need to specify one file. In this case, we take the @@ -76,31 +84,35 @@ class JVMLanguageFrontend( val project = JavaProject.builder(language).addInputLocation(inputLocation).build() project.createView() }*/ - val view = - if (file.extension == "class") { - val inputLocation: AnalysisInputLocation = - JavaClassPathAnalysisInputLocation( - ctx.config.topLevel!!.path, - SourceType.Library, - listOf( - NopEliminator(), - CastAndReturnInliner(), - UnreachableCodeEliminator(), - Aggregator(), - CopyPropagator(), - // ConditionalBranchFolder(), - EmptySwitchEliminator(), - TypeAssigner(), - LocalNameStandardizer() + view = + when (file.extension) { + "class" -> { + val inputLocation: AnalysisInputLocation = + JavaClassPathAnalysisInputLocation( + ctx.config.topLevel!!.path, + SourceType.Library, + listOf( + NopEliminator(), + CastAndReturnInliner(), + UnreachableCodeEliminator(), + Aggregator(), + CopyPropagator(), + // ConditionalBranchFolder(), + EmptySwitchEliminator(), + TypeAssigner(), + LocalNameStandardizer() + ) ) - ) - JavaView(inputLocation) - } else if (file.extension == "java") { - val inputLocation: AnalysisInputLocation = - JavaSourcePathAnalysisInputLocation(ctx.config.topLevel!!.path) - JavaView(inputLocation) - } else { - throw TranslationException("unsupported file") + JavaView(inputLocation) + } + "java" -> { + val inputLocation: AnalysisInputLocation = + JavaSourcePathAnalysisInputLocation(ctx.config.topLevel!!.path) + JavaView(inputLocation) + } + else -> { + throw TranslationException("unsupported file") + } } // This contains the whole directory diff --git a/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/StatementHandler.kt b/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/StatementHandler.kt index e20911c417..d71a7eadfb 100644 --- a/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/StatementHandler.kt +++ b/cpg-language-jvm/src/main/kotlin/de/fraunhofer/aisec/cpg/frontends/StatementHandler.kt @@ -26,6 +26,7 @@ package de.fraunhofer.aisec.cpg.frontends import de.fraunhofer.aisec.cpg.graph.* +import de.fraunhofer.aisec.cpg.graph.builder.label import de.fraunhofer.aisec.cpg.graph.statements.GotoStatement import de.fraunhofer.aisec.cpg.graph.statements.IfStatement import de.fraunhofer.aisec.cpg.graph.statements.ReturnStatement @@ -33,6 +34,7 @@ import de.fraunhofer.aisec.cpg.graph.statements.Statement import de.fraunhofer.aisec.cpg.graph.statements.expressions.* import sootup.core.jimple.common.stmt.* import sootup.core.model.Body +import sootup.core.util.printer.NormalStmtPrinter class StatementHandler(frontend: JVMLanguageFrontend) : Handler(::ProblemExpression, frontend) { @@ -50,6 +52,12 @@ class StatementHandler(frontend: JVMLanguageFrontend) : private fun handleBody(body: Body): Block { val block = newBlock(rawNode = body) + val printer = NormalStmtPrinter() + printer.initializeSootMethod(body.stmtGraph) + + frontend.printer = printer + frontend.body = body + // Parse locals, these are always at the beginning of the function for (local in body.locals) { val decl = frontend.declarationHandler.handle(local) @@ -65,6 +73,13 @@ class StatementHandler(frontend: JVMLanguageFrontend) : // Parse statements for (sootStmt in body.stmts) { + val label = printer.labels[sootStmt] + if (label != null) { + val stmt = newLabelStatement() + stmt.label = label + block += stmt + } + handle(sootStmt)?.let { block += it } } @@ -85,7 +100,16 @@ class StatementHandler(frontend: JVMLanguageFrontend) : frontend.expressionHandler.handle(ifStmt.condition) ?: newProblemExpression("missing condition") - // TODO: parse statements + // TODO: insert basic block instead? + frontend.body?.let { + val target = ifStmt.getTargetStmts(it).firstOrNull() + val label = frontend.printer?.labels?.get(target) + if (label != null) { + val goto = newGotoStatement() + goto.labelName = label + stmt.thenStatement = goto + } + } return stmt } @@ -93,7 +117,13 @@ class StatementHandler(frontend: JVMLanguageFrontend) : private fun handleGotoStmt(gotoStmt: JGotoStmt): GotoStatement { val stmt = newGotoStatement(rawNode = gotoStmt) - // TODO: parse statements + frontend.body?.let { + val target = gotoStmt.getTargetStmts(it).firstOrNull() + val label = frontend.printer?.labels?.get(target) + if (label != null) { + stmt.labelName = label + } + } return stmt }