Repository: joernio/joern (scala)

Issue:
Two-edges between two nodes in the Control Flow Graphs
I am using Joern to extract the Control Flow Graphs (CFGs) of a large dataset that contains C/C++ vulnerable functions. In my initial analysis, I noticed a behavior that I wanted to double check with you or anyone from the Joern development team. I am not sure if it was implemented like that as a feature, or if it is a bug, or if it is something that I'm not using Joern properly.

The behavior I am noticing is the presence of two edges in the same direction between two  same nodes in a CFG. I saw this behavior in three specific code constructs:

- A conditional ternary, such as the following source code:
    `return server_banner ? server_banner : AP_SERVER_BASEVERSION;`
- A for, in the node of the condition of the for loop.
- A switch, in which more than one case goes to the same instruction line.

Is this the expected behavior? Or is it something that should have been mapped differently in the CFG?
Could you help me with that?

Pull request:
Depends on: https://github.com/ShiftLeftSecurity/codepropertygraph/pull/1588
Fixes: https://github.com/joernio/joern/issues/969

Patch:
diff --git a/build.sbt b/build.sbt
index e53a3dbdac81..7bd386c595fc 100644
--- a/build.sbt
+++ b/build.sbt
@@ -2,7 +2,7 @@ name := "joern"
 ThisBuild / organization := "io.joern"
 ThisBuild / scalaVersion := "2.13.7"
 
-val cpgVersion = "1.3.493"
+val cpgVersion = "1.3.495"
 val js2cpgVersion = "0.2.100"
 
 lazy val joerncli = Projects.joerncli


Test patch:
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotCfgGeneratorTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotCfgGeneratorTests.scala
index 0500d88d31b1..65abb4ba6058 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotCfgGeneratorTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotCfgGeneratorTests.scala
@@ -3,7 +3,7 @@ package io.joern.c2cpg.dotgenerator
 import io.joern.c2cpg.testfixtures.CCodeToCpgSuite
 import io.shiftleft.semanticcpg.language._
 
-class DotCfgGeneratorTests extends CCodeToCpgSuite {
+class DotCfgGeneratorTest1 extends CCodeToCpgSuite {
 
   override val code: String =
     """
@@ -20,8 +20,8 @@ class DotCfgGeneratorTests extends CCodeToCpgSuite {
   "A CfgDotGenerator" should {
 
     "create a dot graph" in {
-      inside(cpg.method.name("main").dotCfg.l) { case List(x) =>
-        x should (
+      inside(cpg.method.name("main").dotCfg.l) { case List(dotStr) =>
+        dotStr should (
           startWith("digraph \"main\" {") and
             include("(<operator>.assignment,i = 0)") and
             endWith("}\n")
@@ -30,8 +30,8 @@ class DotCfgGeneratorTests extends CCodeToCpgSuite {
     }
 
     "not contain IDENTIFIER nodes" in {
-      inside(cpg.method.name("main").dotCfg.l) { case List(x) =>
-        x should not include "IDENTIFIER"
+      inside(cpg.method.name("main").dotCfg.l) { case List(dotStr) =>
+        dotStr should not include "IDENTIFIER"
       }
     }
 
@@ -50,3 +50,28 @@ class DotCfgGeneratorTests extends CCodeToCpgSuite {
   }
 
 }
+
+class DotCfgGeneratorTest2 extends CCodeToCpgSuite {
+
+  override val code: String =
+    """
+      |bool a;
+      |bool b;
+      |
+      |bool test() {
+      |  return a ? a : b;
+      |}""".stripMargin
+
+  "A CfgDotGenerator" should {
+
+    "not contain the same edge more than once" in {
+      inside(cpg.method.name("test").dotCfg.l) { case List(dotStr) =>
+        val rawEdges = dotStr.split("\n").filter(x => x.contains("->"))
+        val dedupEdges = rawEdges.distinct
+        rawEdges.length shouldBe dedupEdges.length
+      }
+    }
+
+  }
+
+}
diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotDdgGeneratorTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotDdgGeneratorTests.scala
index 8c11fccbbf1d..9af89c45d533 100644
--- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotDdgGeneratorTests.scala
+++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dotgenerator/DotDdgGeneratorTests.scala
@@ -5,7 +5,7 @@ import io.joern.dataflowengineoss.language._
 import io.joern.dataflowengineoss.semanticsloader.Semantics
 import io.shiftleft.semanticcpg.language._
 
-class DotDdgGeneratorTests extends DataFlowCodeToCpgSuite {
+class DotDdgGeneratorTest1 extends DataFlowCodeToCpgSuite {
 
   override val code: String =
     """
@@ -33,7 +33,7 @@ class DotDdgGeneratorTests extends DataFlowCodeToCpgSuite {
   }
 }
 
-class DotDdgGeneratorTests2 extends DataFlowCodeToCpgSuite {
+class DotDdgGeneratorTest2 extends DataFlowCodeToCpgSuite {
 
   override val code: String =
     """