diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala index 4fc9f82d346f..c47915bf6d88 100644 --- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala +++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/passes/controlflow/codepencegraph/CdgPass.scala @@ -22,6 +22,9 @@ import org.slf4j.{Logger, LoggerFactory} class CdgPass(cpg: Cpg) extends ForkJoinParallelCpgPass[Method](cpg) { import CdgPass.logger + // 10 is just an arbitrary number - we merely want to log 'a few times' but no more than that + val hasLogged = java.util.concurrent.atomic.AtomicInteger(10) + override def generateParts(): Array[Method] = cpg.method.toArray override def runOnPart(dstGraph: DiffGraphBuilder, method: Method): Unit = { @@ -39,16 +42,12 @@ class CdgPass(cpg: Cpg) extends ForkJoinParallelCpgPass[Method](cpg) { case postDomFrontierNode => val nodeLabel = postDomFrontierNode.label val containsIn = postDomFrontierNode._containsIn - if (containsIn == null || !containsIn.hasNext) { - logger.warn(s"Found CDG edge starting at $nodeLabel node. This is most likely caused by an invalid CFG.") - } else { - val method = containsIn.next() + // duplicate check looks (and is) superfluous, but it's a fastpath micro optimization + if (hasLogged.get() > 0 && hasLogged.decrementAndGet() > 0) { + val method = containsIn.nextOption().map(_.toString).getOrElse("N/A") logger.warn( - s"Found CDG edge starting at $nodeLabel node. This is most likely caused by an invalid CFG." + - s" Method: ${method match { - case m: Method => m.fullName; - case other => other.label - }}" + + s"Found CDG edge starting at $nodeLabel node $node <-> ${postDomFrontierNode}. This is most likely caused by an invalid CFG." + + s" Method: ${method}" + s" number of outgoing CFG edges from $nodeLabel node: ${postDomFrontierNode._cfgOut.size}" ) } diff --git a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala index 0c87eb423e48..6e44467fb722 100644 --- a/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala +++ b/joern-cli/frontends/x2cpg/src/main/scala/io/joern/x2cpg/utils/LinkingUtil.scala @@ -18,19 +18,16 @@ trait LinkingUtil { val logger: Logger = LoggerFactory.getLogger(classOf[LinkingUtil]) def typeDeclFullNameToNode(cpg: Cpg, x: String): Option[TypeDecl] = - nodesWithFullName(cpg, x).collectFirst { case x: TypeDecl => x } + cpg.typeDecl.fullNameExact(x).headOption def typeFullNameToNode(cpg: Cpg, x: String): Option[Type] = - nodesWithFullName(cpg, x).collectFirst { case x: Type => x } + cpg.typ.fullNameExact(x).headOption def methodFullNameToNode(cpg: Cpg, x: String): Option[Method] = - nodesWithFullName(cpg, x).collectFirst { case x: Method => x } + cpg.method.fullNameExact(x).headOption def namespaceBlockFullNameToNode(cpg: Cpg, x: String): Option[NamespaceBlock] = - nodesWithFullName(cpg, x).collectFirst { case x: NamespaceBlock => x } - - def nodesWithFullName(cpg: Cpg, x: String): Iterator[StoredNode] = - cpg.graph.nodesWithProperty(propertyName = PropertyNames.FULL_NAME, value = x).cast[StoredNode] + cpg.namespaceBlock.fullNameExact(x).headOption /** For all nodes `n` with a label in `srcLabels`, determine the value of `n.\$dstFullNameKey`, use that to lookup the * destination node in `dstNodeMap`, and create an edge of type `edgeType` between `n` and the destination node.