Skip to content

Commit 10ab72d

Browse files
Added joern-slice Data-Flow Script Test (#4786)
* Added a script that parses and creates a sensible string from a slice that can be tested against. * Fixed a slicing bug where slicing direction was in the opposite direction of neighbour retrieval and ended up ignoring certain nodes. * Added entry in the `test-scripts` job to run the slice script, parse the slice, and assert the expected flow with `grep`. Resolves #4783
1 parent 03161bb commit 10ab72d

File tree

4 files changed

+41
-4
lines changed

4 files changed

+41
-4
lines changed

.github/workflows/pr.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ jobs:
100100
./joern --src /tmp/foo --run scan
101101
./joern-scan /tmp/foo
102102
./joern-scan --dump
103-
#./joern-slice data-flow -o target/slice
103+
- run: |
104+
mkdir /tmp/slice
105+
./joern-slice data-flow tests/code/javasrc/SliceTest.java -o /tmp/slice/dataflow-slice-javasrc.json
106+
./joern --script "./test-dataflow-slice.sc" --param sliceFile=/tmp/slice/dataflow-slice-javasrc.json | grep -q 'List(boolean b, b, this, s, "MALICIOUS", s, new Foo("MALICIOUS"), s, s, "SAFE", s, b, this, this, b, s, System.out)'
104107
- run: |
105108
cd joern-cli/target/universal/stage
106109
./schema-extender/test.sh

dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/slicing/DataFlowSlicing.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package io.joern.dataflowengineoss.slicing
22

33
import io.joern.dataflowengineoss.language.*
44
import io.joern.x2cpg.utils.ConcurrentTaskUtil
5-
import io.shiftleft.codepropertygraph.generated.{Cpg, Properties}
5+
import io.shiftleft.codepropertygraph.generated.{Cpg, EdgeTypes, Properties}
66
import io.shiftleft.codepropertygraph.generated.nodes.*
77
import io.shiftleft.semanticcpg.language.*
88
import org.slf4j.LoggerFactory
@@ -46,8 +46,9 @@ object DataFlowSlicing {
4646
val sliceNodes = sinks.iterator.repeat(_.ddgIn)(_.maxDepth(config.sliceDepth).emit).dedup.l
4747
val sliceNodesIdSet = sliceNodes.id.toSet
4848
// Lazily set up the rest if the filters are satisfied
49-
lazy val sliceEdges = sliceNodes.outE
50-
.filter(x => sliceNodesIdSet.contains(x.dst.id()))
49+
lazy val sliceEdges = sliceNodes
50+
.inE(EdgeTypes.REACHING_DEF)
51+
.filter(x => sliceNodesIdSet.contains(x.src.id()))
5152
.map { e => SliceEdge(e.src.id(), e.dst.id(), e.label) }
5253
.toSet
5354
lazy val slice = Option(DataFlowSlice(sliceNodes.map(cfgNodeToSliceNode).toSet, sliceEdges))

test-dataflow-slice.sc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import upickle.default.*
2+
import io.shiftleft.utils.IOUtils
3+
import java.nio.file.Path
4+
import io.joern.dataflowengineoss.slicing.{DataFlowSlice, SliceEdge}
5+
6+
@main def exec(sliceFile: String) = {
7+
val jsonContent = IOUtils.readLinesInFile(Path.of(sliceFile)).mkString
8+
val dataFlowSlice = read[DataFlowSlice](jsonContent)
9+
val nodeMap = dataFlowSlice.nodes.map(n => n.id -> n).toMap
10+
val edges = dataFlowSlice.edges.toList
11+
.map { case SliceEdge(src, dst, _) =>
12+
(nodeMap(src).lineNumber, nodeMap(dst).lineNumber) -> List(nodeMap(src).code, nodeMap(dst).code).distinct
13+
}
14+
.sortBy(_._1)
15+
.flatMap(_._2)
16+
println(edges)
17+
}

tests/code/javasrc/SliceTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
3+
public class SliceTest {
4+
5+
public void foo(boolean b) {
6+
String s = new Foo("MALICIOUS");
7+
if (b) {
8+
s.setFoo("SAFE");
9+
}
10+
bar(b);
11+
}
12+
13+
public void bar(String x) {
14+
System.out.println(s);
15+
}
16+
}

0 commit comments

Comments
 (0)