From b07bc1edd4ac27fda797833e4aa17078143970ef Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Tue, 9 Jul 2024 00:46:32 +0200 Subject: [PATCH 01/11] implement call graph diff --- .../sootup/callgraph/CallGraphDifference.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java new file mode 100644 index 00000000000..63b706eb608 --- /dev/null +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java @@ -0,0 +1,74 @@ +package sootup.callgraph; + +import sootup.core.signatures.MethodSignature; + +import java.util.*; + +public class CallGraphDifference { + + private MethodSignature entrypoint; + + List> cg1Edges; + List> cg2Edges; + + public CallGraphDifference(CallGraph cg1, CallGraph cg2, MethodSignature entrypoint) { + this.cg1Edges = constructEdges(cg1); + this.cg2Edges = constructEdges(cg2); + } + + private List> constructEdges(CallGraph cg) { + List> cgEdges = new ArrayList<>(); + for (MethodSignature srcNode : cg.getMethodSignatures()) { + Set outNodes = cg.callsFrom(srcNode); + for (MethodSignature targetNode : outNodes) { + cgEdges.add(new Pair<>(srcNode, targetNode)); + } + } + return cgEdges; + } + + /* + This internal class is used to describe the edge in the graph. + */ + public static class Pair { + private L l; + private R r; + public Pair(L l, R r){ + this.l = l; + this.r = r; + } + public L getL(){ return l; } + public R getR(){ return r; } + public void setL(L l){ this.l = l; } + public void setR(R r){ this.r = r; } + } + + /* + In the addedEdges() function, we iterate over each edge in cg2Edges and + check if it exists in cg1Edges. If it doesn't, we add it to the addedEdges list. + */ + public List> addedEdges() { + List> addedEdges = new ArrayList<>(); + for (Pair edge : cg2Edges) { + if (!cg1Edges.contains(edge)) { + addedEdges.add(edge); + } + } + return addedEdges; + } + + /* + In the removedEdges() function, we iterate over each edge in cg1Edges and + check if it exists in cg2Edges. If it doesn't, we add it to the removedEdges list. + */ + public List> removedEdges() { + List> removedEdges = new ArrayList<>(); + for (Pair edge : cg1Edges) { + if (!cg2Edges.contains(edge)) { + removedEdges.add(edge); + } + } + return removedEdges; + } + +} From 5e927ea82a1206ced2183f7d6535d88f65d7728d Mon Sep 17 00:00:00 2001 From: sahil Date: Wed, 10 Jul 2024 01:41:09 +0530 Subject: [PATCH 02/11] write test case --- .../sootup/callgraph/CallGraphDifference.java | 25 ++++------- .../callgraph/CallGraphDifferenceTest.java | 27 ++++++++++++ .../CallGraphDifference/cg1/CG1.java | 24 +++++++++++ .../CallGraphDifference/cg2/CG2.java | 24 +++++++++++ .../src/main/java/sootup/core/types/Type.java | 43 +++++++++++++++++++ 5 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java index 63b706eb608..ff6aff4deda 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java @@ -1,5 +1,7 @@ package sootup.callgraph; +import org.apache.commons.lang3.tuple.MutablePair; +import org.apache.commons.lang3.tuple.Pair; import sootup.core.signatures.MethodSignature; import java.util.*; @@ -16,33 +18,22 @@ public CallGraphDifference(CallGraph cg1, CallGraph cg2, MethodSignature entrypo this.cg2Edges = constructEdges(cg2); } + public CallGraphDifference(CallGraph cg1, CallGraph cg2) { + this.cg1Edges = constructEdges(cg1); + this.cg2Edges = constructEdges(cg2); + } + private List> constructEdges(CallGraph cg) { List> cgEdges = new ArrayList<>(); for (MethodSignature srcNode : cg.getMethodSignatures()) { Set outNodes = cg.callsFrom(srcNode); for (MethodSignature targetNode : outNodes) { - cgEdges.add(new Pair<>(srcNode, targetNode)); + cgEdges.add(new MutablePair<>(srcNode, targetNode)); } } return cgEdges; } - /* - This internal class is used to describe the edge in the graph. - */ - public static class Pair { - private L l; - private R r; - public Pair(L l, R r){ - this.l = l; - this.r = r; - } - public L getL(){ return l; } - public R getR(){ return r; } - public void setL(L l){ this.l = l; } - public void setR(R r){ this.r = r; } - } - /* In the addedEdges() function, we iterate over each edge in cg2Edges and check if it exists in cg1Edges. If it doesn't, we add it to the addedEdges list. diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java new file mode 100644 index 00000000000..e2cc303429f --- /dev/null +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -0,0 +1,27 @@ +package sootup.callgraph; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; +import sootup.core.signatures.MethodSignature; +import sootup.java.core.views.JavaView; + +import java.util.List; + +public class CallGraphDifferenceTest extends CallGraphTestBase { + + @Test + public void testCGDiff() { + CallGraph cg1 = loadCallGraph("CallGraphDifference", true, "cg1.CG1"); + CallGraph cg2 = loadCallGraph("CallGraphDifference", true, "cg2.CG2"); + CallGraphDifference callGraphDifference = new CallGraphDifference(cg1, cg2); + List> addedEdges = callGraphDifference.addedEdges(); + addedEdges.forEach(System.out::println); + List> removedEdges = callGraphDifference.removedEdges(); + removedEdges.forEach(System.out::println); + } + + @Override + protected AbstractCallGraphAlgorithm createAlgorithm(JavaView view) { + return new ClassHierarchyAnalysisAlgorithm(view); + } +} diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java new file mode 100644 index 00000000000..15c3e392862 --- /dev/null +++ b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java @@ -0,0 +1,24 @@ +package cg1; +public class CG1 { + public static void main(String[] args) { + a(); + } + + public static void a(){ + b(); + d(); + } + + public static void b() { + c(); + } + + public static void c() { + + } + + public static void d() { + + } + +} \ No newline at end of file diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java new file mode 100644 index 00000000000..1089cb4b2c8 --- /dev/null +++ b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java @@ -0,0 +1,24 @@ +package cg2; +public class CG2 { + public static void main(String[] args) { + a(); + } + + public static void a(){ + b(); + } + + public static void b() { + c(); + d(); + } + + public static void c() { + + } + + public static void d() { + + } + +} \ No newline at end of file diff --git a/sootup.core/src/main/java/sootup/core/types/Type.java b/sootup.core/src/main/java/sootup/core/types/Type.java index 805da414e0d..813bc6f7a55 100644 --- a/sootup.core/src/main/java/sootup/core/types/Type.java +++ b/sootup.core/src/main/java/sootup/core/types/Type.java @@ -29,6 +29,49 @@ /** Represents the signature of a Java type, e.g., a class, a primitive type, void, or null. */ public abstract class Type implements Acceptor { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + public static boolean isObjectLikeType(Type type) { return type.toString().equals("java.lang.Object") || type.toString().equals("java.io.Serializable") From 9bc31521a59da685402826c4c41a372028417fef Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Wed, 10 Jul 2024 17:43:42 +0200 Subject: [PATCH 03/11] testcase --- .../callgraph/CallGraphDifferenceTest.java | 35 +++++++++++++++---- .../CallGraphDifference/{cg1 => }/CG1.java | 1 - .../CallGraphDifference/{cg2 => }/CG2.java | 1 - 3 files changed, 28 insertions(+), 9 deletions(-) rename sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/{cg1 => }/CG1.java (95%) rename sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/{cg2 => }/CG2.java (95%) diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index e2cc303429f..62067f2b2d0 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -1,27 +1,48 @@ package sootup.callgraph; import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.model.SourceType; import sootup.core.signatures.MethodSignature; +import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.core.types.JavaClassType; import sootup.java.core.views.JavaView; +import sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation; +import java.io.File; +import java.util.Collections; import java.util.List; +import java.util.Set; -public class CallGraphDifferenceTest extends CallGraphTestBase { +public class CallGraphDifferenceTest { @Test public void testCGDiff() { - CallGraph cg1 = loadCallGraph("CallGraphDifference", true, "cg1.CG1"); - CallGraph cg2 = loadCallGraph("CallGraphDifference", true, "cg2.CG2"); + String classPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-classes" + File.separator + "callgraph" + File.separator + "CallGraphDifference"; + AnalysisInputLocation inputLocation = new JavaClassPathAnalysisInputLocation(classPath, null, Collections.emptyList()); + JavaView view = new JavaView(inputLocation); + + ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); + JavaClassType chaClassType = view.getIdentifierFactory().getClassType("CG1"); + MethodSignature chaMethodSignature = view.getIdentifierFactory() + .getMethodSignature(chaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); + CallGraph cg1 = chaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); + + RapidTypeAnalysisAlgorithm rtaAlgorithm = new RapidTypeAnalysisAlgorithm(view); + JavaClassType rtaClassType = view.getIdentifierFactory().getClassType("CG2"); + MethodSignature rtaMethodSignature = view.getIdentifierFactory() + .getMethodSignature(rtaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); + CallGraph cg2 = rtaAlgorithm.initialize(Collections.singletonList(rtaMethodSignature)); + CallGraphDifference callGraphDifference = new CallGraphDifference(cg1, cg2); List> addedEdges = callGraphDifference.addedEdges(); addedEdges.forEach(System.out::println); + System.out.println("-----"); List> removedEdges = callGraphDifference.removedEdges(); removedEdges.forEach(System.out::println); } - @Override - protected AbstractCallGraphAlgorithm createAlgorithm(JavaView view) { - return new ClassHierarchyAnalysisAlgorithm(view); - } } diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java similarity index 95% rename from sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java rename to sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java index 15c3e392862..6b870d6eaca 100644 --- a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg1/CG1.java +++ b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java @@ -1,4 +1,3 @@ -package cg1; public class CG1 { public static void main(String[] args) { a(); diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java similarity index 95% rename from sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java rename to sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java index 1089cb4b2c8..d55d2e4e6af 100644 --- a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/cg2/CG2.java +++ b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java @@ -1,4 +1,3 @@ -package cg2; public class CG2 { public static void main(String[] args) { a(); From c57c98731fa41d06dfdedd8a0cc72b94f3d886c4 Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 12 Jul 2024 01:12:33 +0200 Subject: [PATCH 04/11] refactor call graph diff --- .../main/java/sootup/callgraph/CallGraph.java | 5 + .../sootup/callgraph/CallGraphDifference.java | 108 +++++++++++++----- .../sootup/callgraph/GraphBasedCallGraph.java | 6 + .../callgraph/CallGraphDifferenceTest.java | 41 ++++--- .../callgraph/CallGraphDifference/CG1.java | 23 ---- .../callgraph/CallGraphDifference/CG2.java | 23 ---- .../CallGraphDifference/Example.java | 35 ++++++ .../builder/callgraph/OnFlyCallGraph.java | 8 ++ 8 files changed, 155 insertions(+), 94 deletions(-) delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java index e90694879bb..713810e43d8 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java @@ -96,4 +96,9 @@ boolean containsCall( */ @Nonnull MutableCallGraph copy(); + + /** This method compares the difference between the current call graph and call graph passed into the argument. */ + @Nonnull + CallGraphDifference diff(@Nonnull CallGraph callGraph); + } diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java index ff6aff4deda..c2e29c7e84f 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java @@ -5,22 +5,21 @@ import sootup.core.signatures.MethodSignature; import java.util.*; +import java.util.stream.Collectors; public class CallGraphDifference { - private MethodSignature entrypoint; + private final CallGraph baseCallGraph; + private final CallGraph otherCallGraph; - List> cg1Edges; - List> cg2Edges; + private final List> baseCallGraphEdges; + private final List> otherCallGraphEdges; - public CallGraphDifference(CallGraph cg1, CallGraph cg2, MethodSignature entrypoint) { - this.cg1Edges = constructEdges(cg1); - this.cg2Edges = constructEdges(cg2); - } - - public CallGraphDifference(CallGraph cg1, CallGraph cg2) { - this.cg1Edges = constructEdges(cg1); - this.cg2Edges = constructEdges(cg2); + public CallGraphDifference(CallGraph baseCallGraph, CallGraph otherCallGraph) { + this.baseCallGraph = baseCallGraph; + this.otherCallGraph = otherCallGraph; + this.baseCallGraphEdges = constructEdges(baseCallGraph); + this.otherCallGraphEdges = constructEdges(otherCallGraph); } private List> constructEdges(CallGraph cg) { @@ -34,32 +33,79 @@ private List> constructEdges(CallGraph cg return cgEdges; } + public CallGraph getBaseCallGraph() { + return baseCallGraph; + } + + public CallGraph getOtherCallGraph() { + return otherCallGraph; + } + + public List> getBaseCallGraphEdges() { + return baseCallGraphEdges; + } + + public List> getOtherCallGraphEdges() { + return otherCallGraphEdges; + } + /* - In the addedEdges() function, we iterate over each edge in cg2Edges and - check if it exists in cg1Edges. If it doesn't, we add it to the addedEdges list. + In the intersectedCalls() function, we iterate over each edge in both call graphs and + return the intersection of the edges. */ - public List> addedEdges() { - List> addedEdges = new ArrayList<>(); - for (Pair edge : cg2Edges) { - if (!cg1Edges.contains(edge)) { - addedEdges.add(edge); - } - } - return addedEdges; + public List> intersectedCalls() { + return baseCallGraphEdges.stream() + .filter(otherCallGraphEdges::contains) + .collect(Collectors.toList()); } /* - In the removedEdges() function, we iterate over each edge in cg1Edges and - check if it exists in cg2Edges. If it doesn't, we add it to the removedEdges list. + In the intersectedMethods() function, we iterate over each node in both call graphs and + return the intersection of the nodes. */ - public List> removedEdges() { - List> removedEdges = new ArrayList<>(); - for (Pair edge : cg1Edges) { - if (!cg2Edges.contains(edge)) { - removedEdges.add(edge); - } - } - return removedEdges; + public List intersectedMethods() { + return baseCallGraph.getMethodSignatures().stream() + .filter(otherCallGraph.getMethodSignatures()::contains) + .collect(Collectors.toList()); } + /* + In the uniqueBaseGraphCalls() function, we iterate over each edges in base call graph and + return the unique edges present in the base call graph. + */ + public List> uniqueBaseGraphCalls() { + return baseCallGraphEdges.stream() + .filter(edge -> !otherCallGraphEdges.contains(edge)) + .collect(Collectors.toList()); + } + + /* + In the uniqueBaseGraphMethods() function, we iterate over each node in base call graph and + return the unique nodes present in the base call graph. + */ + public List uniqueBaseGraphMethods() { + return baseCallGraph.getMethodSignatures().stream() + .filter(node -> !otherCallGraph.getMethodSignatures().contains(node)) + .collect(Collectors.toList()); + } + + /* + In the uniqueOtherGraphCalls() function, we iterate over each edges in other call graph and + return the unique edges present in the other call graph. + */ + public List> uniqueOtherGraphCalls() { + return otherCallGraphEdges.stream() + .filter(edge -> !baseCallGraphEdges.contains(edge)) + .collect(Collectors.toList()); + } + + /* + In the uniqueOtherGraphMethods() function, we iterate over each node in other call graph and + return the unique nodes present in the other call graph. + */ + public List uniqueOtherGraphMethods() { + return otherCallGraph.getMethodSignatures().stream() + .filter(node -> !baseCallGraph.getMethodSignatures().contains(node)) + .collect(Collectors.toList()); + } } diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/GraphBasedCallGraph.java b/sootup.callgraph/src/main/java/sootup/callgraph/GraphBasedCallGraph.java index d6672716bbe..e2470c802a0 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/GraphBasedCallGraph.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/GraphBasedCallGraph.java @@ -198,6 +198,12 @@ public MutableCallGraph copy() { (DefaultDirectedGraph) graph.clone(), new HashMap<>(signatureToVertex)); } + @Nonnull + @Override + public CallGraphDifference diff(@Nonnull CallGraph callGraph) { + return new CallGraphDifference(this, callGraph); + } + /** * it returns the vertex of the graph that describes the given method signature in the call graph. * diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index 62067f2b2d0..12fcf5965f0 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -1,21 +1,16 @@ package sootup.callgraph; import org.apache.commons.lang3.tuple.Pair; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import sootup.core.inputlocation.AnalysisInputLocation; -import sootup.core.model.SourceType; import sootup.core.signatures.MethodSignature; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.types.JavaClassType; import sootup.java.core.views.JavaView; -import sootup.java.sourcecode.inputlocation.JavaSourcePathAnalysisInputLocation; import java.io.File; import java.util.Collections; import java.util.List; -import java.util.Set; public class CallGraphDifferenceTest { @@ -26,23 +21,35 @@ public void testCGDiff() { JavaView view = new JavaView(inputLocation); ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); - JavaClassType chaClassType = view.getIdentifierFactory().getClassType("CG1"); + JavaClassType chaClassType = view.getIdentifierFactory().getClassType("Example"); MethodSignature chaMethodSignature = view.getIdentifierFactory() .getMethodSignature(chaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); CallGraph cg1 = chaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); RapidTypeAnalysisAlgorithm rtaAlgorithm = new RapidTypeAnalysisAlgorithm(view); - JavaClassType rtaClassType = view.getIdentifierFactory().getClassType("CG2"); - MethodSignature rtaMethodSignature = view.getIdentifierFactory() - .getMethodSignature(rtaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); - CallGraph cg2 = rtaAlgorithm.initialize(Collections.singletonList(rtaMethodSignature)); - - CallGraphDifference callGraphDifference = new CallGraphDifference(cg1, cg2); - List> addedEdges = callGraphDifference.addedEdges(); - addedEdges.forEach(System.out::println); - System.out.println("-----"); - List> removedEdges = callGraphDifference.removedEdges(); - removedEdges.forEach(System.out::println); + CallGraph cg2 = rtaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); + + CallGraphDifference callGraphDifference = cg1.diff(cg2); + System.out.println("Unique Base Graph Calls/Edges"); + List> uniqueBaseGraphCalls = callGraphDifference.uniqueBaseGraphCalls(); + uniqueBaseGraphCalls.forEach(System.out::println); + System.out.println("Unique Base Graph Methods/Nodes"); + List uniqueBaseGraphMethods = callGraphDifference.uniqueBaseGraphMethods(); + uniqueBaseGraphMethods.forEach(System.out::println); + + System.out.println("Unique Other Graph Calls/Edges"); + List> uniqueOtherGraphCalls = callGraphDifference.uniqueOtherGraphCalls(); + uniqueOtherGraphCalls.forEach(System.out::println); + System.out.println("Unique Other Graph Methods/Nodes"); + List uniqueOtherGraphMethods = callGraphDifference.uniqueOtherGraphMethods(); + uniqueOtherGraphMethods.forEach(System.out::println); + + System.out.println("Intersected Calls/Edges"); + List> intersectedCalls = callGraphDifference.intersectedCalls(); + intersectedCalls.forEach(System.out::println); + System.out.println("Intersected Methods/Nodes"); + List intersectedMethods = callGraphDifference.intersectedMethods(); + intersectedMethods.forEach(System.out::println); } } diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java deleted file mode 100644 index 6b870d6eaca..00000000000 --- a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG1.java +++ /dev/null @@ -1,23 +0,0 @@ -public class CG1 { - public static void main(String[] args) { - a(); - } - - public static void a(){ - b(); - d(); - } - - public static void b() { - c(); - } - - public static void c() { - - } - - public static void d() { - - } - -} \ No newline at end of file diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java deleted file mode 100644 index d55d2e4e6af..00000000000 --- a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/CG2.java +++ /dev/null @@ -1,23 +0,0 @@ -public class CG2 { - public static void main(String[] args) { - a(); - } - - public static void a(){ - b(); - } - - public static void b() { - c(); - d(); - } - - public static void c() { - - } - - public static void d() { - - } - -} \ No newline at end of file diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java new file mode 100644 index 00000000000..3ef3f87dd2a --- /dev/null +++ b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java @@ -0,0 +1,35 @@ +class Example { + + public static void main(String[] args) { + A objB = new B(); + B.staticDispatch(new C()); + + A objC=new E(); + + objB.virtualDispatch(); + } +} + +class A extends Object { + public void virtualDispatch() { } + public static void staticDispatch( Object o) { } +} + +class B extends A { + public void virtualDispatch() { } + public static void staticDispatch( Object o) { } +} + +class C extends D { + public static void staticDispatch( Object o) { } +} + +class D extends A { + public void virtualDispatch() { } + public static void staticDispatch( Object o) { } +} + +class E extends A { + public void virtualDispatch() { } + public static void staticDispatch( Object o) { } +} diff --git a/sootup.qilin/src/main/java/qilin/core/builder/callgraph/OnFlyCallGraph.java b/sootup.qilin/src/main/java/qilin/core/builder/callgraph/OnFlyCallGraph.java index d7b8caa1fb3..557788735bd 100644 --- a/sootup.qilin/src/main/java/qilin/core/builder/callgraph/OnFlyCallGraph.java +++ b/sootup.qilin/src/main/java/qilin/core/builder/callgraph/OnFlyCallGraph.java @@ -35,6 +35,8 @@ import qilin.util.DataFactory; import qilin.util.queue.ChunkedQueue; import qilin.util.queue.QueueReader; +import sootup.callgraph.CallGraph; +import sootup.callgraph.CallGraphDifference; import sootup.callgraph.MutableCallGraph; import sootup.core.jimple.common.stmt.Stmt; import sootup.core.model.SootMethod; @@ -450,6 +452,12 @@ public MutableCallGraph copy() { throw new UnsupportedOperationException(); } + @Nonnull + @Override + public CallGraphDifference diff(@Nonnull CallGraph callGraph) { + throw new UnsupportedOperationException(); + } + @Override public boolean containsMethod(@Nonnull MethodSignature method) { return this.methods.contains(method); From 2794a1fec86769b3b61422fbb708cb4493376789 Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 12 Jul 2024 01:24:04 +0200 Subject: [PATCH 05/11] added binary files for the example test case --- .gitignore | 1 + .../sootup/callgraph/CallGraphDifferenceTest.java | 2 +- .../callgraph/CallGraphDifference/binary/A.class | Bin 0 -> 319 bytes .../callgraph/CallGraphDifference/binary/B.class | Bin 0 -> 304 bytes .../callgraph/CallGraphDifference/binary/C.class | Bin 0 -> 247 bytes .../callgraph/CallGraphDifference/binary/D.class | Bin 0 -> 304 bytes .../callgraph/CallGraphDifference/binary/E.class | Bin 0 -> 304 bytes .../CallGraphDifference/binary/Example.class | Bin 0 -> 427 bytes 8 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/C.class create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class create mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class diff --git a/.gitignore b/.gitignore index 8f1bc7b7aa2..8aea9c1135a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.class !shared-test-resources/miniTestSuite/**/*.class !sootup.analysis/src/test/resources/taint/binary/*.class +!sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/*.class # Log file *.log diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index 12fcf5965f0..3055b959817 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -16,7 +16,7 @@ public class CallGraphDifferenceTest { @Test public void testCGDiff() { - String classPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-classes" + File.separator + "callgraph" + File.separator + "CallGraphDifference"; + String classPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-classes" + File.separator + "callgraph" + File.separator + "CallGraphDifference" + File.separator + "binary"; AnalysisInputLocation inputLocation = new JavaClassPathAnalysisInputLocation(classPath, null, Collections.emptyList()); JavaView view = new JavaView(inputLocation); diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class new file mode 100644 index 0000000000000000000000000000000000000000..9e8e2840b232e96cbdad77b57077fb4a6db9667f GIT binary patch literal 319 zcmZ{ezly>@5Ql$b)OZ?`G*?&%mhlRG07Vf0RB~4+={IrlR$`R65nsznu(${Cp~P8> z69gA_cKFT5w{yK+{s0W&S5bgvqv)W7GQnSqgXktAU3Gt=wTv~P+*hg61A-N_LmL$W z4GG23b}0$oOr`QW-$XK7h$u11L1j7@$yn`oLdU-Zcdvz3@iX`gX0PA$+99Dj-{x5? zr^5@E!e!MITl}D6@(A&n*5SUzRsW%H*Dc*#z38G?H_GCrcAtIE}NVO OY>aO)k8Lgk1$cL5bTqI4 literal 0 HcmV?d00001 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class new file mode 100644 index 0000000000000000000000000000000000000000..c1aff20e3eaf54e2b879f3de37e5a648cd4b8c89 GIT binary patch literal 304 zcmZ{e&1%9>5QWc}G|@Co#I_3;LYLY_^8kwA?@HQ*lKoA*v{z!3coTfBt_ofB0emQN zZWk>SIxs(+`8b@@`ST0F2u%+)ST1ZIS8xb4A~*w;D?KDw-CpdX&gz(8Pj+ib2p1}s z&*e6e#Y!ZZQ7TpFQe;zg*bAM$5rTsjTBX0jeRr`Dm54HtzeX>~My9&oiwWLxR~D(9 zE92wOj$*sdI7P-3p7S<1xlE6Nylg}e zvEwCLXcbOXauzz=6RPdSL0m;Y67jCT3Jx;VgN{!qu21PDlyhaa+}TYW&ynmI6fHRX shbhzf6A%ilnmoxk-3RE-g0FBlF;HWq1ediz8^4r^f2__xnL`WS7co#LtN;K2 literal 0 HcmV?d00001 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class new file mode 100644 index 0000000000000000000000000000000000000000..4ea7eb2c4a1c2f6413948aa0e4da445831aa5d8f GIT binary patch literal 304 zcmZ{e&uYRz5XQer)KpDlFFh13cvKJi02M)+dXn}~@xIwEy0XR)H{xq~5_<3f`cTr@ z9x4b9%pbn_@y-04zfS7k~p)u8| zdN03G>J}3VMLY1dy?&Or-5p>{zUAVe6(BxYGN1y(-Ok86vb_#LN OuyeeLxl<7X9vZ*I9WNFD literal 0 HcmV?d00001 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class new file mode 100644 index 0000000000000000000000000000000000000000..f1cd2e1ada565ffcd5745434aef294453871556b GIT binary patch literal 304 zcmZ{e&1%9>5QWbqny5`;Y6M{2VnbNNWdl0N$G+3PxYSZ0D65654 zB}t4L%~={h^)TEfcp`pPfA1 QGi)6H#hw`O8L-g40LTk3CIA2c literal 0 HcmV?d00001 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class new file mode 100644 index 0000000000000000000000000000000000000000..36d1bb6ccde914e47b59cbb950ad937eda81ea3d GIT binary patch literal 427 zcmZ8d+e$)F5M86@*3-#bX=SDMW(D~HMPO#VSUng)^t3%4bc-J4xRrjZmyCoyppS}X zq9~e&S&O->8P@y9>l=VNb{#|zRfxG*LY$E4>zS?%bkMC`cly3(3GrhS7<)p9R`+fd z5(GMRpk!;AdBcH&s1#Bz(#Q}}6RWN9&dg-2t=A*utF8aCM(VefxP@8~IsNVlM+P0wy zx_p%2v`5p>^UsY8yWe_;@*gVLWH%%vvmYRAG23AzsqD`|PfQ5goTV*1$pa-u8NCoY w8OsZ(yE&4r1sq2A1uF|=nXO(PJY(%wq`-H87!r&*HnGTZC3cih=6VE`PbBtBbpQYW literal 0 HcmV?d00001 From 6aac24148c601469825ad8f4d9c9c238c7f6f58a Mon Sep 17 00:00:00 2001 From: sahil Date: Fri, 12 Jul 2024 16:54:41 +0530 Subject: [PATCH 06/11] removed extra spaces, formatting --- .../src/main/java/sootup/core/types/Type.java | 132 ++++++------------ 1 file changed, 46 insertions(+), 86 deletions(-) diff --git a/sootup.core/src/main/java/sootup/core/types/Type.java b/sootup.core/src/main/java/sootup/core/types/Type.java index 813bc6f7a55..3bef415392c 100644 --- a/sootup.core/src/main/java/sootup/core/types/Type.java +++ b/sootup.core/src/main/java/sootup/core/types/Type.java @@ -23,107 +23,67 @@ */ import javax.annotation.Nonnull; + import sootup.core.jimple.visitor.Acceptor; import sootup.core.jimple.visitor.TypeVisitor; -/** Represents the signature of a Java type, e.g., a class, a primitive type, void, or null. */ +/** + * Represents the signature of a Java type, e.g., a class, a primitive type, void, or null. + */ public abstract class Type implements Acceptor { + public static boolean isObjectLikeType(Type type) { + return type.toString().equals("java.lang.Object") + || type.toString().equals("java.io.Serializable") + || type.toString().equals("java.lang.Cloneable"); + } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - public static boolean isObjectLikeType(Type type) { - return type.toString().equals("java.lang.Object") - || type.toString().equals("java.io.Serializable") - || type.toString().equals("java.lang.Cloneable"); - } - - public static boolean isIntLikeType(Type type) { - return type instanceof PrimitiveType.IntType; + public static boolean isIntLikeType(Type type) { + return type instanceof PrimitiveType.IntType; /* type == PrimitiveType.IntType.getInstance() || type == PrimitiveType.ByteType.getInstance() || type == PrimitiveType.ShortType.getInstance() || type == PrimitiveType.CharType.getInstance() || type == PrimitiveType.BooleanType.getInstance(); */ - } - - public static boolean isObject(Type type) { - return type.toString().equals("java.lang.Object"); - } - - /** - * This method is used to make an array type for the given type. If the given type is an array - * type, then increase its dimension with given dim - */ - public static ArrayType createArrayType(@Nonnull Type type, int dim) { - if (type instanceof ArrayType) { - return new ArrayType( - ((ArrayType) type).getBaseType(), ((ArrayType) type).getDimension() + dim); - } else { - return new ArrayType(type, dim); } - } - public static int getValueBitSize(Type type) { - // TODO: ms: make use of the typevisitor to get O(1) - if (type instanceof PrimitiveType.BooleanType) { - return 1; - } - if (type instanceof PrimitiveType.ByteType) { - return 8; + public static boolean isObject(Type type) { + return type.toString().equals("java.lang.Object"); } - if (type instanceof PrimitiveType.ShortType || type instanceof PrimitiveType.CharType) { - return 16; - } - if (type instanceof PrimitiveType.IntType || type instanceof PrimitiveType.FloatType) { - return 32; + + /** + * This method is used to make an array type for the given type. If the given type is an array + * type, then increase its dimension with given dim + */ + public static ArrayType createArrayType(@Nonnull Type type, int dim) { + if (type instanceof ArrayType) { + return new ArrayType( + ((ArrayType) type).getBaseType(), ((ArrayType) type).getDimension() + dim); + } else { + return new ArrayType(type, dim); + } } - if (type instanceof PrimitiveType.LongType - || type instanceof PrimitiveType.DoubleType - || type instanceof ClassType) { - return 64; + + public static int getValueBitSize(Type type) { + // TODO: ms: make use of the typevisitor to get O(1) + if (type instanceof PrimitiveType.BooleanType) { + return 1; + } + if (type instanceof PrimitiveType.ByteType) { + return 8; + } + if (type instanceof PrimitiveType.ShortType || type instanceof PrimitiveType.CharType) { + return 16; + } + if (type instanceof PrimitiveType.IntType || type instanceof PrimitiveType.FloatType) { + return 32; + } + if (type instanceof PrimitiveType.LongType + || type instanceof PrimitiveType.DoubleType + || type instanceof ClassType) { + return 64; + } + return 0; } - return 0; - } } From ca3923cf111fba9f3a6c4fce4526d422aabda15a Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 12 Jul 2024 14:43:38 +0200 Subject: [PATCH 07/11] formatted mvn fmt:format --- .../main/java/sootup/callgraph/CallGraph.java | 6 +- .../sootup/callgraph/CallGraphDifference.java | 201 +++++++++--------- .../callgraph/CallGraphDifferenceTest.java | 97 +++++---- .../src/main/java/sootup/core/types/Type.java | 89 ++++---- 4 files changed, 203 insertions(+), 190 deletions(-) diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java index 713810e43d8..470a1d92219 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraph.java @@ -97,8 +97,10 @@ boolean containsCall( @Nonnull MutableCallGraph copy(); - /** This method compares the difference between the current call graph and call graph passed into the argument. */ + /** + * This method compares the difference between the current call graph and call graph passed into + * the argument. + */ @Nonnull CallGraphDifference diff(@Nonnull CallGraph callGraph); - } diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java index c2e29c7e84f..abbc0f44828 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java @@ -1,111 +1,110 @@ package sootup.callgraph; +import java.util.*; +import java.util.stream.Collectors; import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.Pair; import sootup.core.signatures.MethodSignature; -import java.util.*; -import java.util.stream.Collectors; - public class CallGraphDifference { - private final CallGraph baseCallGraph; - private final CallGraph otherCallGraph; - - private final List> baseCallGraphEdges; - private final List> otherCallGraphEdges; - - public CallGraphDifference(CallGraph baseCallGraph, CallGraph otherCallGraph) { - this.baseCallGraph = baseCallGraph; - this.otherCallGraph = otherCallGraph; - this.baseCallGraphEdges = constructEdges(baseCallGraph); - this.otherCallGraphEdges = constructEdges(otherCallGraph); - } - - private List> constructEdges(CallGraph cg) { - List> cgEdges = new ArrayList<>(); - for (MethodSignature srcNode : cg.getMethodSignatures()) { - Set outNodes = cg.callsFrom(srcNode); - for (MethodSignature targetNode : outNodes) { - cgEdges.add(new MutablePair<>(srcNode, targetNode)); - } - } - return cgEdges; - } - - public CallGraph getBaseCallGraph() { - return baseCallGraph; - } - - public CallGraph getOtherCallGraph() { - return otherCallGraph; - } - - public List> getBaseCallGraphEdges() { - return baseCallGraphEdges; - } - - public List> getOtherCallGraphEdges() { - return otherCallGraphEdges; - } - - /* - In the intersectedCalls() function, we iterate over each edge in both call graphs and - return the intersection of the edges. - */ - public List> intersectedCalls() { - return baseCallGraphEdges.stream() - .filter(otherCallGraphEdges::contains) - .collect(Collectors.toList()); - } - - /* - In the intersectedMethods() function, we iterate over each node in both call graphs and - return the intersection of the nodes. - */ - public List intersectedMethods() { - return baseCallGraph.getMethodSignatures().stream() - .filter(otherCallGraph.getMethodSignatures()::contains) - .collect(Collectors.toList()); - } - - /* - In the uniqueBaseGraphCalls() function, we iterate over each edges in base call graph and - return the unique edges present in the base call graph. - */ - public List> uniqueBaseGraphCalls() { - return baseCallGraphEdges.stream() - .filter(edge -> !otherCallGraphEdges.contains(edge)) - .collect(Collectors.toList()); - } - - /* - In the uniqueBaseGraphMethods() function, we iterate over each node in base call graph and - return the unique nodes present in the base call graph. - */ - public List uniqueBaseGraphMethods() { - return baseCallGraph.getMethodSignatures().stream() - .filter(node -> !otherCallGraph.getMethodSignatures().contains(node)) - .collect(Collectors.toList()); - } - - /* - In the uniqueOtherGraphCalls() function, we iterate over each edges in other call graph and - return the unique edges present in the other call graph. - */ - public List> uniqueOtherGraphCalls() { - return otherCallGraphEdges.stream() - .filter(edge -> !baseCallGraphEdges.contains(edge)) - .collect(Collectors.toList()); - } - - /* - In the uniqueOtherGraphMethods() function, we iterate over each node in other call graph and - return the unique nodes present in the other call graph. - */ - public List uniqueOtherGraphMethods() { - return otherCallGraph.getMethodSignatures().stream() - .filter(node -> !baseCallGraph.getMethodSignatures().contains(node)) - .collect(Collectors.toList()); + private final CallGraph baseCallGraph; + private final CallGraph otherCallGraph; + + private final List> baseCallGraphEdges; + private final List> otherCallGraphEdges; + + public CallGraphDifference(CallGraph baseCallGraph, CallGraph otherCallGraph) { + this.baseCallGraph = baseCallGraph; + this.otherCallGraph = otherCallGraph; + this.baseCallGraphEdges = constructEdges(baseCallGraph); + this.otherCallGraphEdges = constructEdges(otherCallGraph); + } + + private List> constructEdges(CallGraph cg) { + List> cgEdges = new ArrayList<>(); + for (MethodSignature srcNode : cg.getMethodSignatures()) { + Set outNodes = cg.callsFrom(srcNode); + for (MethodSignature targetNode : outNodes) { + cgEdges.add(new MutablePair<>(srcNode, targetNode)); + } } + return cgEdges; + } + + public CallGraph getBaseCallGraph() { + return baseCallGraph; + } + + public CallGraph getOtherCallGraph() { + return otherCallGraph; + } + + public List> getBaseCallGraphEdges() { + return baseCallGraphEdges; + } + + public List> getOtherCallGraphEdges() { + return otherCallGraphEdges; + } + + /* + In the intersectedCalls() function, we iterate over each edge in both call graphs and + return the intersection of the edges. + */ + public List> intersectedCalls() { + return baseCallGraphEdges.stream() + .filter(otherCallGraphEdges::contains) + .collect(Collectors.toList()); + } + + /* + In the intersectedMethods() function, we iterate over each node in both call graphs and + return the intersection of the nodes. + */ + public List intersectedMethods() { + return baseCallGraph.getMethodSignatures().stream() + .filter(otherCallGraph.getMethodSignatures()::contains) + .collect(Collectors.toList()); + } + + /* + In the uniqueBaseGraphCalls() function, we iterate over each edges in base call graph and + return the unique edges present in the base call graph. + */ + public List> uniqueBaseGraphCalls() { + return baseCallGraphEdges.stream() + .filter(edge -> !otherCallGraphEdges.contains(edge)) + .collect(Collectors.toList()); + } + + /* + In the uniqueBaseGraphMethods() function, we iterate over each node in base call graph and + return the unique nodes present in the base call graph. + */ + public List uniqueBaseGraphMethods() { + return baseCallGraph.getMethodSignatures().stream() + .filter(node -> !otherCallGraph.getMethodSignatures().contains(node)) + .collect(Collectors.toList()); + } + + /* + In the uniqueOtherGraphCalls() function, we iterate over each edges in other call graph and + return the unique edges present in the other call graph. + */ + public List> uniqueOtherGraphCalls() { + return otherCallGraphEdges.stream() + .filter(edge -> !baseCallGraphEdges.contains(edge)) + .collect(Collectors.toList()); + } + + /* + In the uniqueOtherGraphMethods() function, we iterate over each node in other call graph and + return the unique nodes present in the other call graph. + */ + public List uniqueOtherGraphMethods() { + return otherCallGraph.getMethodSignatures().stream() + .filter(node -> !baseCallGraph.getMethodSignatures().contains(node)) + .collect(Collectors.toList()); + } } diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index 3055b959817..c7fe8a600be 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -1,5 +1,8 @@ package sootup.callgraph; +import java.io.File; +import java.util.Collections; +import java.util.List; import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.Test; import sootup.core.inputlocation.AnalysisInputLocation; @@ -8,48 +11,60 @@ import sootup.java.core.types.JavaClassType; import sootup.java.core.views.JavaView; -import java.io.File; -import java.util.Collections; -import java.util.List; - public class CallGraphDifferenceTest { - @Test - public void testCGDiff() { - String classPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-classes" + File.separator + "callgraph" + File.separator + "CallGraphDifference" + File.separator + "binary"; - AnalysisInputLocation inputLocation = new JavaClassPathAnalysisInputLocation(classPath, null, Collections.emptyList()); - JavaView view = new JavaView(inputLocation); - - ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); - JavaClassType chaClassType = view.getIdentifierFactory().getClassType("Example"); - MethodSignature chaMethodSignature = view.getIdentifierFactory() - .getMethodSignature(chaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); - CallGraph cg1 = chaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); - - RapidTypeAnalysisAlgorithm rtaAlgorithm = new RapidTypeAnalysisAlgorithm(view); - CallGraph cg2 = rtaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); - - CallGraphDifference callGraphDifference = cg1.diff(cg2); - System.out.println("Unique Base Graph Calls/Edges"); - List> uniqueBaseGraphCalls = callGraphDifference.uniqueBaseGraphCalls(); - uniqueBaseGraphCalls.forEach(System.out::println); - System.out.println("Unique Base Graph Methods/Nodes"); - List uniqueBaseGraphMethods = callGraphDifference.uniqueBaseGraphMethods(); - uniqueBaseGraphMethods.forEach(System.out::println); - - System.out.println("Unique Other Graph Calls/Edges"); - List> uniqueOtherGraphCalls = callGraphDifference.uniqueOtherGraphCalls(); - uniqueOtherGraphCalls.forEach(System.out::println); - System.out.println("Unique Other Graph Methods/Nodes"); - List uniqueOtherGraphMethods = callGraphDifference.uniqueOtherGraphMethods(); - uniqueOtherGraphMethods.forEach(System.out::println); - - System.out.println("Intersected Calls/Edges"); - List> intersectedCalls = callGraphDifference.intersectedCalls(); - intersectedCalls.forEach(System.out::println); - System.out.println("Intersected Methods/Nodes"); - List intersectedMethods = callGraphDifference.intersectedMethods(); - intersectedMethods.forEach(System.out::println); - } + @Test + public void testCGDiff() { + String classPath = + System.getProperty("user.dir") + + File.separator + + "target" + + File.separator + + "test-classes" + + File.separator + + "callgraph" + + File.separator + + "CallGraphDifference" + + File.separator + + "binary"; + AnalysisInputLocation inputLocation = + new JavaClassPathAnalysisInputLocation(classPath, null, Collections.emptyList()); + JavaView view = new JavaView(inputLocation); + + ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); + JavaClassType chaClassType = view.getIdentifierFactory().getClassType("Example"); + MethodSignature chaMethodSignature = + view.getIdentifierFactory() + .getMethodSignature( + chaClassType, "main", "void", Collections.singletonList("java.lang.String[]")); + CallGraph cg1 = chaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); + + RapidTypeAnalysisAlgorithm rtaAlgorithm = new RapidTypeAnalysisAlgorithm(view); + CallGraph cg2 = rtaAlgorithm.initialize(Collections.singletonList(chaMethodSignature)); + + CallGraphDifference callGraphDifference = cg1.diff(cg2); + System.out.println("Unique Base Graph Calls/Edges"); + List> uniqueBaseGraphCalls = + callGraphDifference.uniqueBaseGraphCalls(); + uniqueBaseGraphCalls.forEach(System.out::println); + System.out.println("Unique Base Graph Methods/Nodes"); + List uniqueBaseGraphMethods = callGraphDifference.uniqueBaseGraphMethods(); + uniqueBaseGraphMethods.forEach(System.out::println); + + System.out.println("Unique Other Graph Calls/Edges"); + List> uniqueOtherGraphCalls = + callGraphDifference.uniqueOtherGraphCalls(); + uniqueOtherGraphCalls.forEach(System.out::println); + System.out.println("Unique Other Graph Methods/Nodes"); + List uniqueOtherGraphMethods = callGraphDifference.uniqueOtherGraphMethods(); + uniqueOtherGraphMethods.forEach(System.out::println); + System.out.println("Intersected Calls/Edges"); + List> intersectedCalls = + callGraphDifference.intersectedCalls(); + intersectedCalls.forEach(System.out::println); + System.out.println("Intersected Methods/Nodes"); + List intersectedMethods = callGraphDifference.intersectedMethods(); + intersectedMethods.forEach(System.out::println); + } } diff --git a/sootup.core/src/main/java/sootup/core/types/Type.java b/sootup.core/src/main/java/sootup/core/types/Type.java index 3bef415392c..805da414e0d 100644 --- a/sootup.core/src/main/java/sootup/core/types/Type.java +++ b/sootup.core/src/main/java/sootup/core/types/Type.java @@ -23,67 +23,64 @@ */ import javax.annotation.Nonnull; - import sootup.core.jimple.visitor.Acceptor; import sootup.core.jimple.visitor.TypeVisitor; -/** - * Represents the signature of a Java type, e.g., a class, a primitive type, void, or null. - */ +/** Represents the signature of a Java type, e.g., a class, a primitive type, void, or null. */ public abstract class Type implements Acceptor { - public static boolean isObjectLikeType(Type type) { - return type.toString().equals("java.lang.Object") - || type.toString().equals("java.io.Serializable") - || type.toString().equals("java.lang.Cloneable"); - } + public static boolean isObjectLikeType(Type type) { + return type.toString().equals("java.lang.Object") + || type.toString().equals("java.io.Serializable") + || type.toString().equals("java.lang.Cloneable"); + } - public static boolean isIntLikeType(Type type) { - return type instanceof PrimitiveType.IntType; + public static boolean isIntLikeType(Type type) { + return type instanceof PrimitiveType.IntType; /* type == PrimitiveType.IntType.getInstance() || type == PrimitiveType.ByteType.getInstance() || type == PrimitiveType.ShortType.getInstance() || type == PrimitiveType.CharType.getInstance() || type == PrimitiveType.BooleanType.getInstance(); */ - } + } - public static boolean isObject(Type type) { - return type.toString().equals("java.lang.Object"); - } + public static boolean isObject(Type type) { + return type.toString().equals("java.lang.Object"); + } - /** - * This method is used to make an array type for the given type. If the given type is an array - * type, then increase its dimension with given dim - */ - public static ArrayType createArrayType(@Nonnull Type type, int dim) { - if (type instanceof ArrayType) { - return new ArrayType( - ((ArrayType) type).getBaseType(), ((ArrayType) type).getDimension() + dim); - } else { - return new ArrayType(type, dim); - } + /** + * This method is used to make an array type for the given type. If the given type is an array + * type, then increase its dimension with given dim + */ + public static ArrayType createArrayType(@Nonnull Type type, int dim) { + if (type instanceof ArrayType) { + return new ArrayType( + ((ArrayType) type).getBaseType(), ((ArrayType) type).getDimension() + dim); + } else { + return new ArrayType(type, dim); } + } - public static int getValueBitSize(Type type) { - // TODO: ms: make use of the typevisitor to get O(1) - if (type instanceof PrimitiveType.BooleanType) { - return 1; - } - if (type instanceof PrimitiveType.ByteType) { - return 8; - } - if (type instanceof PrimitiveType.ShortType || type instanceof PrimitiveType.CharType) { - return 16; - } - if (type instanceof PrimitiveType.IntType || type instanceof PrimitiveType.FloatType) { - return 32; - } - if (type instanceof PrimitiveType.LongType - || type instanceof PrimitiveType.DoubleType - || type instanceof ClassType) { - return 64; - } - return 0; + public static int getValueBitSize(Type type) { + // TODO: ms: make use of the typevisitor to get O(1) + if (type instanceof PrimitiveType.BooleanType) { + return 1; + } + if (type instanceof PrimitiveType.ByteType) { + return 8; + } + if (type instanceof PrimitiveType.ShortType || type instanceof PrimitiveType.CharType) { + return 16; + } + if (type instanceof PrimitiveType.IntType || type instanceof PrimitiveType.FloatType) { + return 32; + } + if (type instanceof PrimitiveType.LongType + || type instanceof PrimitiveType.DoubleType + || type instanceof ClassType) { + return 64; } + return 0; + } } From e67873602b20a42e0ca3bca685f4a4ba822c44b4 Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 12 Jul 2024 15:00:15 +0200 Subject: [PATCH 08/11] added license mvn -B org.codehaus.mojo:license-maven-plugin:check-file-header --- .../sootup/callgraph/CallGraphDifference.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java index abbc0f44828..3aaf15a5fc9 100644 --- a/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java +++ b/sootup.callgraph/src/main/java/sootup/callgraph/CallGraphDifference.java @@ -6,6 +6,28 @@ import org.apache.commons.lang3.tuple.Pair; import sootup.core.signatures.MethodSignature; +/*- + * #%L + * Soot + * %% + * Copyright (C) 2024 Sahil Agichani + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 2.1 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * . + * #L% + */ + public class CallGraphDifference { private final CallGraph baseCallGraph; From 0bca0d9d56b7254343536c982e3a6c06918f80e1 Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 19 Jul 2024 13:31:02 +0200 Subject: [PATCH 09/11] moved files from resources to shared-test-resources to make it build tool independent. --- .../CallGraphDifference/Example.java | 0 .../callgraph/CallGraphDifferenceTest.java | 16 ++-------------- .../CallGraphDifference/binary/A.class | Bin 319 -> 0 bytes .../CallGraphDifference/binary/B.class | Bin 304 -> 0 bytes .../CallGraphDifference/binary/C.class | Bin 247 -> 0 bytes .../CallGraphDifference/binary/D.class | Bin 304 -> 0 bytes .../CallGraphDifference/binary/E.class | Bin 304 -> 0 bytes .../CallGraphDifference/binary/Example.class | Bin 427 -> 0 bytes 8 files changed, 2 insertions(+), 14 deletions(-) rename {sootup.callgraph/src/test/resources/callgraph => shared-test-resources}/CallGraphDifference/Example.java (100%) delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/C.class delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class delete mode 100644 sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java b/shared-test-resources/CallGraphDifference/Example.java similarity index 100% rename from sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/Example.java rename to shared-test-resources/CallGraphDifference/Example.java diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index c7fe8a600be..708f111c95d 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -1,6 +1,5 @@ package sootup.callgraph; -import java.io.File; import java.util.Collections; import java.util.List; import org.apache.commons.lang3.tuple.Pair; @@ -15,20 +14,9 @@ public class CallGraphDifferenceTest { @Test public void testCGDiff() { - String classPath = - System.getProperty("user.dir") - + File.separator - + "target" - + File.separator - + "test-classes" - + File.separator - + "callgraph" - + File.separator - + "CallGraphDifference" - + File.separator - + "binary"; + String baseDir = "../shared-test-resources/CallGraphDifference/binary/"; AnalysisInputLocation inputLocation = - new JavaClassPathAnalysisInputLocation(classPath, null, Collections.emptyList()); + new JavaClassPathAnalysisInputLocation(baseDir, null, Collections.emptyList()); JavaView view = new JavaView(inputLocation); ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/A.class deleted file mode 100644 index 9e8e2840b232e96cbdad77b57077fb4a6db9667f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 319 zcmZ{ezly>@5Ql$b)OZ?`G*?&%mhlRG07Vf0RB~4+={IrlR$`R65nsznu(${Cp~P8> z69gA_cKFT5w{yK+{s0W&S5bgvqv)W7GQnSqgXktAU3Gt=wTv~P+*hg61A-N_LmL$W z4GG23b}0$oOr`QW-$XK7h$u11L1j7@$yn`oLdU-Zcdvz3@iX`gX0PA$+99Dj-{x5? zr^5@E!e!MITl}D6@(A&n*5SUzRsW%H*Dc*#z38G?H_GCrcAtIE}NVO OY>aO)k8Lgk1$cL5bTqI4 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/B.class deleted file mode 100644 index c1aff20e3eaf54e2b879f3de37e5a648cd4b8c89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 304 zcmZ{e&1%9>5QWc}G|@Co#I_3;LYLY_^8kwA?@HQ*lKoA*v{z!3coTfBt_ofB0emQN zZWk>SIxs(+`8b@@`ST0F2u%+)ST1ZIS8xb4A~*w;D?KDw-CpdX&gz(8Pj+ib2p1}s z&*e6e#Y!ZZQ7TpFQe;zg*bAM$5rTsjTBX0jeRr`Dm54HtzeX>~My9&oiwWLxR~D(9 zE92wOj$*sdI7P-3p7S<1xlE6Nylg}e zvEwCLXcbOXauzz=6RPdSL0m;Y67jCT3Jx;VgN{!qu21PDlyhaa+}TYW&ynmI6fHRX shbhzf6A%ilnmoxk-3RE-g0FBlF;HWq1ediz8^4r^f2__xnL`WS7co#LtN;K2 diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/D.class deleted file mode 100644 index 4ea7eb2c4a1c2f6413948aa0e4da445831aa5d8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 304 zcmZ{e&uYRz5XQer)KpDlFFh13cvKJi02M)+dXn}~@xIwEy0XR)H{xq~5_<3f`cTr@ z9x4b9%pbn_@y-04zfS7k~p)u8| zdN03G>J}3VMLY1dy?&Or-5p>{zUAVe6(BxYGN1y(-Ok86vb_#LN OuyeeLxl<7X9vZ*I9WNFD diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/E.class deleted file mode 100644 index f1cd2e1ada565ffcd5745434aef294453871556b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 304 zcmZ{e&1%9>5QWbqny5`;Y6M{2VnbNNWdl0N$G+3PxYSZ0D65654 zB}t4L%~={h^)TEfcp`pPfA1 QGi)6H#hw`O8L-g40LTk3CIA2c diff --git a/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class b/sootup.callgraph/src/test/resources/callgraph/CallGraphDifference/binary/Example.class deleted file mode 100644 index 36d1bb6ccde914e47b59cbb950ad937eda81ea3d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 427 zcmZ8d+e$)F5M86@*3-#bX=SDMW(D~HMPO#VSUng)^t3%4bc-J4xRrjZmyCoyppS}X zq9~e&S&O->8P@y9>l=VNb{#|zRfxG*LY$E4>zS?%bkMC`cly3(3GrhS7<)p9R`+fd z5(GMRpk!;AdBcH&s1#Bz(#Q}}6RWN9&dg-2t=A*utF8aCM(VefxP@8~IsNVlM+P0wy zx_p%2v`5p>^UsY8yWe_;@*gVLWH%%vvmYRAG23AzsqD`|PfQ5goTV*1$pa-u8NCoY w8OsZ(yE&4r1sq2A1uF|=nXO(PJY(%wq`-H87!r&*HnGTZC3cih=6VE`PbBtBbpQYW From 42b853d90116fd13a81bd4d686b87de2680e2e9e Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 19 Jul 2024 15:02:43 +0200 Subject: [PATCH 10/11] modify tc --- .../test/java/sootup/callgraph/CallGraphDifferenceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index 708f111c95d..0a35975a50c 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -5,6 +5,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.Test; import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.model.SourceType; import sootup.core.signatures.MethodSignature; import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation; import sootup.java.core.types.JavaClassType; @@ -16,7 +17,7 @@ public class CallGraphDifferenceTest { public void testCGDiff() { String baseDir = "../shared-test-resources/CallGraphDifference/binary/"; AnalysisInputLocation inputLocation = - new JavaClassPathAnalysisInputLocation(baseDir, null, Collections.emptyList()); + new JavaClassPathAnalysisInputLocation(baseDir, SourceType.Application, Collections.emptyList()); JavaView view = new JavaView(inputLocation); ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view); From 2df6dec563dfe5e4ee7054d901ddd9373c6e1066 Mon Sep 17 00:00:00 2001 From: sahilagichani Date: Fri, 19 Jul 2024 15:09:51 +0200 Subject: [PATCH 11/11] formatted the code --- .../test/java/sootup/callgraph/CallGraphDifferenceTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java index 0a35975a50c..7743df98c31 100644 --- a/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java +++ b/sootup.callgraph/src/test/java/sootup/callgraph/CallGraphDifferenceTest.java @@ -17,7 +17,8 @@ public class CallGraphDifferenceTest { public void testCGDiff() { String baseDir = "../shared-test-resources/CallGraphDifference/binary/"; AnalysisInputLocation inputLocation = - new JavaClassPathAnalysisInputLocation(baseDir, SourceType.Application, Collections.emptyList()); + new JavaClassPathAnalysisInputLocation( + baseDir, SourceType.Application, Collections.emptyList()); JavaView view = new JavaView(inputLocation); ClassHierarchyAnalysisAlgorithm chaAlgorithm = new ClassHierarchyAnalysisAlgorithm(view);