Skip to content

Commit

Permalink
[joern-export] Handle Empty CPG (joernio#3897)
Browse files Browse the repository at this point in the history
Upon exporting `Representation.Cpg`, an iterator based on methods is started, and then the result is reduced.

If the iterator is empty, the reduce will throw an exception.

This change instead returns an empty result.

Resolves joernio#3892
  • Loading branch information
DavidBakerEffendi authored Dec 7, 2023
1 parent cdcaf26 commit 7685924
Showing 1 changed file with 24 additions and 17 deletions.
41 changes: 24 additions & 17 deletions joern-cli/src/main/scala/io/joern/joerncli/JoernExport.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package io.joern.joerncli

import better.files.Dsl._
import better.files.Dsl.*
import better.files.File
import io.joern.dataflowengineoss.DefaultSemantics
import io.joern.dataflowengineoss.layers.dataflows._
import io.joern.dataflowengineoss.layers.dataflows.*
import io.joern.dataflowengineoss.semanticsloader.Semantics
import io.joern.joerncli.CpgBasedTool.exitIfInvalid
import io.joern.x2cpg.layers._
import io.joern.x2cpg.layers.*
import io.shiftleft.codepropertygraph.Cpg
import io.shiftleft.codepropertygraph.generated.NodeTypes
import io.shiftleft.semanticcpg.language.{toAstNodeMethods, toNodeTypeStarters}
import io.shiftleft.semanticcpg.layers._
import io.shiftleft.semanticcpg.layers.*
import overflowdb.formats.ExportResult
import overflowdb.formats.dot.DotExporter
import overflowdb.formats.graphml.GraphMLExporter
Expand Down Expand Up @@ -142,19 +143,23 @@ object JoernExport {
case Representation.All =>
exporter.runExport(cpg.graph, outDir)
case Representation.Cpg =>
val windowsFilenameDeduplicationHelper = mutable.Set.empty[String]
splitByMethod(cpg).iterator
.map { case subGraph @ MethodSubGraph(methodName, methodFilename, nodes) =>
val relativeFilename = sanitizedFileName(
methodName,
methodFilename,
exporter.defaultFileExtension,
windowsFilenameDeduplicationHelper
)
val outFileName = outDir.resolve(relativeFilename)
exporter.runExport(nodes, subGraph.edges, outFileName)
}
.reduce(plus)
if (cpg.graph.nodeCount(NodeTypes.METHOD) > 0) {
val windowsFilenameDeduplicationHelper = mutable.Set.empty[String]
splitByMethod(cpg).iterator
.map { case subGraph @ MethodSubGraph(methodName, methodFilename, nodes) =>
val relativeFilename = sanitizedFileName(
methodName,
methodFilename,
exporter.defaultFileExtension,
windowsFilenameDeduplicationHelper
)
val outFileName = outDir.resolve(relativeFilename)
exporter.runExport(nodes, subGraph.edges, outFileName)
}
.reduce(plus)
} else {
emptyExportResult
}
case other =>
throw new NotImplementedError(s"repr=$repr not yet supported for this format")
}
Expand Down Expand Up @@ -213,6 +218,8 @@ object JoernExport {
)
}

private def emptyExportResult = ExportResult(0, 0, Seq.empty, Option("Empty CPG"))

case class MethodSubGraph(methodName: String, methodFilename: String, nodes: Set[Node]) {
def edges: Set[Edge] = {
for {
Expand Down

0 comments on commit 7685924

Please sign in to comment.