From cc7f787459d5591cefafee003ac740e810f78fce Mon Sep 17 00:00:00 2001 From: Xavier Pinho Date: Wed, 25 Sep 2024 18:05:43 +0100 Subject: [PATCH] [dataflowengineoss] remove overriding operator semantics (#4952) * fix assignmentModulo * fix assignmentXor * fix assignmentOr * fix assignmentAnd * fix assignmentExponentiation * fix assignmentShiftLeft * fix assignment{Logical,Arithmetic}ShiftRight * scalafmt --- .../dataflowengineoss/DefaultSemantics.scala | 12 -- .../joern/c2cpg/dataflow/DataFlowTests.scala | 133 ++++++++++++++++++ .../dataflow/SingleAssignmentTests.scala | 15 ++ 3 files changed, 148 insertions(+), 12 deletions(-) diff --git a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/DefaultSemantics.scala b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/DefaultSemantics.scala index 9b9acc341b70..33312f054950 100644 --- a/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/DefaultSemantics.scala +++ b/dataflowengineoss/src/main/scala/io/joern/dataflowengineoss/DefaultSemantics.scala @@ -60,18 +60,6 @@ object DefaultSemantics { F(Operators.preIncrement, List((1, 1), (1, -1))), F(Operators.sizeOf, List.empty[(Int, Int)]), - // some of those operators have duplicate mappings due to a typo - // - see https://github.com/ShiftLeftSecurity/codepropertygraph/pull/1630 - - F(".assignmentExponentiation", List((2, 1), (1, 1))), - F(".assignmentModulo", List((2, 1), (1, 1))), - F(".assignmentShiftLeft", List((2, 1), (1, 1))), - F(".assignmentLogicalShiftRight", List((2, 1), (1, 1))), - F(".assignmentArithmeticShiftRight", List((2, 1), (1, 1))), - F(".assignmentAnd", List((2, 1), (1, 1))), - F(".assignmentOr", List((2, 1), (1, 1))), - F(".assignmentXor", List((2, 1), (1, 1))), - // Language specific operators PTF(".tupleLiteral"), PTF(".dictLiteral"), diff --git a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/DataFlowTests.scala b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/DataFlowTests.scala index c78a5cd3fe8a..644bf471a117 100644 --- a/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/DataFlowTests.scala +++ b/joern-cli/frontends/c2cpg/src/test/scala/io/joern/c2cpg/dataflow/DataFlowTests.scala @@ -1988,4 +1988,137 @@ class DataFlowTestsWithCallDepth extends DataFlowCodeToCpgSuite { ) } } + + "DataFlowTest73" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x%=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x%=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x%=2", 4), ("call1(x%=2)", 4))) + } + + "the literal in x%=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x%=2", 4), ("call2(x)", 5))) + } + + } + + "DataFlowTest74" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x^=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x^=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x^=2", 4), ("call1(x^=2)", 4))) + } + + "the literal in x^=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x^=2", 4), ("call2(x)", 5))) + } + } + + "DataFlowTest75" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x|=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x|=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x|=2", 4), ("call1(x|=2)", 4))) + } + + "the literal in x|=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x|=2", 4), ("call2(x)", 5))) + } + } + + "DataFlowTest76" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x&=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x&=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x&=2", 4), ("call1(x&=2)", 4))) + } + + "the literal in x&=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x&=2", 4), ("call2(x)", 5))) + } + } + + "DataFlowTest77" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x<<=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x<<=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x<<=2", 4), ("call1(x<<=2)", 4))) + } + + "the literal in x<<=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x<<=2", 4), ("call2(x)", 5))) + } + } + + "DataFlowTest78" should { + val cpg = code(""" + |int main(void) { + | int x = 5; + | call1(x>>=2); + | call2(x); + |} + |""".stripMargin) + + "the literal in x>>=2 should taint the outer expression" in { + val source = cpg.literal("2") + val sink = cpg.call("call1") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x>>=2", 4), ("call1(x>>=2)", 4))) + } + + "the literal in x>>=2 should taint the next occurrence of x" in { + val source = cpg.literal("2") + val sink = cpg.call("call2") + sink.reachableByFlows(source).map(flowToResultPairs).l shouldBe List(List(("x>>=2", 4), ("call2(x)", 5))) + } + } } diff --git a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/SingleAssignmentTests.scala b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/SingleAssignmentTests.scala index c9ace03bcd28..8ee26a108469 100644 --- a/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/SingleAssignmentTests.scala +++ b/joern-cli/frontends/rubysrc2cpg/src/test/scala/io/joern/rubysrc2cpg/dataflow/SingleAssignmentTests.scala @@ -47,6 +47,21 @@ class SingleAssignmentTests extends RubyCode2CpgFixture(withPostProcessing = tru sink.reachableByFlows(src).l.size shouldBe 2 } + "flow through **=" in { + val cpg = code(""" + |x = 5 + |call1(x**=2) + |call2(x) + |""".stripMargin) + + val source = cpg.literal("2").l + val call1 = cpg.call("call1") + val call2 = cpg.call("call2") + + call1.reachableBy(source).l shouldBe source + call2.reachableBy(source).l shouldBe source + } + "Data flow through grouping expression" in { val cpg = code(""" |x = 0