diff --git a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala index dfb756bb981..60445f3481d 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/main/scala/io/joern/rubysrc2cpg/astcreation/AstCreator.scala @@ -1192,12 +1192,13 @@ class AstCreator(filename: String, global: Global) } def astForCallNode(localIdentifier: TerminalNode): Seq[Ast] = { - val column = localIdentifier.getSymbol().getCharPositionInLine() - val line = localIdentifier.getSymbol().getLine() - val name = getActualMethodName(localIdentifier.getText) + val column = localIdentifier.getSymbol().getCharPositionInLine() + val line = localIdentifier.getSymbol().getLine() + val name = getActualMethodName(localIdentifier.getText) + val methodFullName = s"$filename:$name" val callNode = NewCall() .name(name) - .methodFullName(name) + .methodFullName(methodFullName) .signature(localIdentifier.getText()) .typeFullName(MethodFullNames.UnknownFullName) .dispatchType(DispatchTypes.STATIC_DISPATCH) @@ -1401,11 +1402,13 @@ class AstCreator(filename: String, global: Global) val astBody = astForBodyStatementContext(ctx.bodyStatement()) popScope() + // TODO why is there a `callNode` here? + val classPath = classStack.toList.mkString(".") + "." val methodNode = NewMethod() .code(callNode.code) .name(callNode.name) - .fullName(classPath + callNode.name) + .fullName(s"$filename:${callNode.name}") .columnNumber(callNode.columnNumber) .lineNumber(callNode.lineNumber) .filename(filename) diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala index c2fe39e9aa5..7ad59c66305 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/DataFlowTests.scala @@ -31,4 +31,25 @@ class DataFlowTests extends DataFlowCodeToCpgSuite { sink.reachableByFlows(source).l.size shouldBe 2 } } + + "Flow via call" should { + val cpg = code(""" + |def print(content) + |puts content + |end + | + |def main + |n = 1 + |print( n ) + |end + |""".stripMargin) + + "be found" in { + implicit val resolver: ICallResolver = NoResolve + val src = cpg.identifier.name("n").where(_.inCall.name("print")).l + val sink = cpg.method.name("puts").callIn.argument(1).l + sink.reachableByFlows(src).size shouldBe 1 + } + } + } diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/CallGraphTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/CallGraphTests.scala index ba0e06217c5..ec5d1a484b6 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/CallGraphTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/CallGraphTests.scala @@ -1,6 +1,7 @@ package io.joern.rubysrc2cpg.querying import io.joern.rubysrc2cpg.testfixtures.RubyCode2CpgFixture +import io.shiftleft.codepropertygraph.generated.nodes.Method import io.shiftleft.semanticcpg.language._ class CallGraphTests extends RubyCode2CpgFixture { @@ -18,8 +19,11 @@ class CallGraphTests extends RubyCode2CpgFixture { "should identify call from `foo` to `bar`" in { val List(callToBar) = cpg.call("bar").l callToBar.name shouldBe "bar" + callToBar.methodFullName.matches(".*Test.*.rb:bar") shouldBe true callToBar.lineNumber shouldBe Some(7) - cpg.method("bar").caller.name.l shouldBe List("foo") + val List(bar: Method) = cpg.method("bar").internal.l + bar.fullName shouldBe callToBar.methodFullName + bar.caller.name.l shouldBe List("foo") } } diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala index bfbac5fb4bf..2416d125925 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/querying/IdentifierTests.scala @@ -67,7 +67,7 @@ class IdentifierTests extends RubyCode2CpgFixture { cpg.method.name("initialize").size shouldBe 1 cpg.method .name("greet") - .size shouldBe 2 // FIXME the second node is coming in without adding it. Need to check this + .size shouldBe 1 cpg.call.name("puts").size shouldBe 2 cpg.method.name("have_birthday").size shouldBe 1 cpg.identifier.size shouldBe 11 @@ -468,7 +468,7 @@ class IdentifierTests extends RubyCode2CpgFixture { |""".stripMargin) "recognise all method nodes" in { - cpg.method.name("yield_with_args_method").l.size shouldBe 2 + cpg.method.name("yield_with_args_method").l.size shouldBe 1 // TODO need to figure out how yield block should be connected to the method }