From 9e3b86ae01290895773ced3832b2d573e342b7eb Mon Sep 17 00:00:00 2001 From: karan-batavia Date: Fri, 20 Dec 2024 14:46:28 +0530 Subject: [PATCH] fix for ast out edge for init methods --- .../ast/AstForDeclarationsCreator.scala | 9 ++-- .../kotlin2cpg/querying/TypeDeclTests.scala | 50 +++++++++++++++++-- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/ast/AstForDeclarationsCreator.scala b/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/ast/AstForDeclarationsCreator.scala index b9474e5b8415..396b046eb87b 100644 --- a/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/ast/AstForDeclarationsCreator.scala +++ b/joern-cli/frontends/kotlin2cpg/src/main/scala/io/joern/kotlin2cpg/ast/AstForDeclarationsCreator.scala @@ -15,14 +15,11 @@ import io.joern.x2cpg.utils.NodeBuilders.newBindingNode import io.joern.x2cpg.utils.NodeBuilders.newIdentifierNode import io.joern.x2cpg.utils.NodeBuilders.newMethodReturnNode import io.joern.x2cpg.utils.NodeBuilders.newModifierNode -import io.shiftleft.codepropertygraph.generated.DispatchTypes -import io.shiftleft.codepropertygraph.generated.EdgeTypes -import io.shiftleft.codepropertygraph.generated.Operators +import io.shiftleft.codepropertygraph.generated.{DispatchTypes, EdgeTypes, ModifierTypes, NodeTypes, Operators} import io.shiftleft.codepropertygraph.generated.nodes.NewBlock import io.shiftleft.codepropertygraph.generated.nodes.NewCall import io.shiftleft.codepropertygraph.generated.nodes.NewMethod import io.shiftleft.codepropertygraph.generated.nodes.NewTypeDecl -import io.shiftleft.codepropertygraph.generated.ModifierTypes import io.shiftleft.semanticcpg.language.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.psi.* @@ -188,7 +185,7 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) { val modifiers = if (isAbstract(ktClass)) List(Ast(NodeBuilders.newModifierNode(ModifierTypes.ABSTRACT))) else Nil val children = methodAsts ++ List(constructorAst) ++ membersFromPrimaryCtorAsts ++ secondaryConstructorAsts ++ - _componentNMethodAsts.toList ++ memberAsts ++ annotationAsts ++ modifiers + _componentNMethodAsts.toList ++ memberAsts ++ annotationAsts ++ modifiers ++ innerTypeDeclAsts.toSeq val ast = Ast(typeDecl).withChildren(children) (List(ctorBindingInfo) ++ bindingsInfo ++ componentNBindingsInfo).foreach(bindingInfoQueue.prepend) @@ -214,7 +211,7 @@ trait AstForDeclarationsCreator(implicit withSchemaValidation: ValidationMode) { methodAstParentStack.pop() scope.popScope() - Seq(finalAst.withChildren(annotations.map(astForAnnotationEntry))) ++ companionObjectAsts ++ innerTypeDeclAsts + Seq(finalAst.withChildren(annotations.map(astForAnnotationEntry))) ++ companionObjectAsts } private def memberSetCallAst(param: KtParameter, classFullName: String)(implicit diff --git a/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/querying/TypeDeclTests.scala b/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/querying/TypeDeclTests.scala index e05da10d7311..e2b0c75994ea 100644 --- a/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/querying/TypeDeclTests.scala +++ b/joern-cli/frontends/kotlin2cpg/src/test/scala/io/joern/kotlin2cpg/querying/TypeDeclTests.scala @@ -8,13 +8,16 @@ import io.shiftleft.codepropertygraph.generated.nodes.{ FieldIdentifier, Identifier, Method, - MethodParameterIn + MethodParameterIn, + MethodReturn, + StoredNode } import io.shiftleft.codepropertygraph.generated.DispatchTypes -import io.shiftleft.semanticcpg.language._ +import io.shiftleft.semanticcpg.language.* import io.shiftleft.semanticcpg.language.types.structure.FileTraversal +import io.joern.dataflowengineoss.language._ -class TypeDeclTests extends KotlinCode2CpgFixture(withOssDataflow = false) { +class TypeDeclTests extends KotlinCode2CpgFixture(withOssDataflow = true) { "CPG for code with class declaration using unresolved types which are available in imports" should { val cpg = code(""" |package no.such.pkg @@ -198,7 +201,7 @@ class TypeDeclTests extends KotlinCode2CpgFixture(withOssDataflow = false) { val cpg = code(""" |package mypkg | - |import java.lang.Object + |import java.lang.x | |class Foo: Object { | val z: Int = 1 @@ -451,4 +454,43 @@ class TypeDeclTests extends KotlinCode2CpgFixture(withOssDataflow = false) { firstCallOfSecondaryCtor.methodFullName shouldBe "mypkg.QClass.:void()" } } + "CPG for code with an anonymous object and an inner class nested inside" should { + val cpg = code(""" + |package au.gov.health.covidsafe.bluetooth.gatt + |class GattServer constructor(val context: Context, serviceUUIDString: String) { + | private val gattServerCallback = object : BluetoothGattServerCallback() { + | inner class ReadRequestEncryptedPayload(val timestamp: Long, val modelP: String, val msg: String) + |}} + |""".stripMargin) + + "have correct ast structure for anonymous object" in { + val List(anonymousObjTypeDecl) = cpg.typeDecl("anonymous_obj").l + + anonymousObjTypeDecl.name shouldBe "anonymous_obj" + anonymousObjTypeDecl.fullName shouldBe "au.gov.health.covidsafe.bluetooth.gatt.GattServer.gattServerCallback$object$1" + + val constructorMethod = anonymousObjTypeDecl.astChildren.isMethod.l + constructorMethod.fullName.l shouldBe List( + "au.gov.health.covidsafe.bluetooth.gatt.GattServer.gattServerCallback$object$1.:void()" + ) + constructorMethod.ast.isParameter.size shouldBe 1 + constructorMethod.ast.count(_.isInstanceOf[MethodReturn]) shouldBe 1 + + } + + "have correct ast structure for the inner class" in { + val List(innerClassTypeDecl) = cpg.typeDecl("ReadRequestEncryptedPayload").l + + innerClassTypeDecl.name shouldBe "ReadRequestEncryptedPayload" + innerClassTypeDecl.fullName shouldBe "au.gov.health.covidsafe.bluetooth.gatt.GattServer.gattServerCallback$object$1.ReadRequestEncryptedPayload" + + val constructorMethod = innerClassTypeDecl.astChildren.isMethod.l + constructorMethod.fullName.l shouldBe List( + "au.gov.health.covidsafe.bluetooth.gatt.GattServer.gattServerCallback.:void(long,java.lang.String,java.lang.String)" + ) + constructorMethod.ast.isParameter.size shouldBe 4 + constructorMethod.ast.count(_.isInstanceOf[MethodReturn]) shouldBe 1 + + } + } }