diff --git a/Jenkinsfile b/Jenkinsfile index 271ab982..7bc5ec66 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -34,7 +34,7 @@ pipeline { maven: 'Maven 3.6.3', mavenSettingsConfig: '9ff5ed8e-79e5-4010-b7e2-f137f16176dd') { - sh 'mvn -P ci com.coveo:fmt-maven-plugin:check -DskipFormatPlugin=false' + sh 'mvn -P ci com.coveo:fmt-maven-plugin:check -DskipFormat=false' } } } diff --git a/PDS/pom.xml b/PDS/pom.xml new file mode 100644 index 00000000..87432dce --- /dev/null +++ b/PDS/pom.xml @@ -0,0 +1,20 @@ + + + + de.fraunhofer.iem + SPDS + 3.2.3 + ../pom.xml + + 4.0.0 + PDS + + + 11 + 11 + UTF-8 + + + \ No newline at end of file diff --git a/WPDS/src/main/java/wpds/interfaces/Empty.java b/PDS/src/main/java/de/fraunhofer/iem/Empty.java similarity index 95% rename from WPDS/src/main/java/wpds/interfaces/Empty.java rename to PDS/src/main/java/de/fraunhofer/iem/Empty.java index 48b0f43d..0ad2cfcd 100644 --- a/WPDS/src/main/java/wpds/interfaces/Empty.java +++ b/PDS/src/main/java/de/fraunhofer/iem/Empty.java @@ -9,6 +9,6 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package wpds.interfaces; +package de.fraunhofer.iem; public interface Empty {} diff --git a/WPDS/src/main/java/wpds/interfaces/Location.java b/PDS/src/main/java/de/fraunhofer/iem/Location.java similarity index 95% rename from WPDS/src/main/java/wpds/interfaces/Location.java rename to PDS/src/main/java/de/fraunhofer/iem/Location.java index 41234dde..f514033f 100644 --- a/WPDS/src/main/java/wpds/interfaces/Location.java +++ b/PDS/src/main/java/de/fraunhofer/iem/Location.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package wpds.interfaces; +package de.fraunhofer.iem; public interface Location { boolean accepts(Location other); diff --git a/WPDS/src/main/java/wpds/wildcard/ExclusionWildcard.java b/PDS/src/main/java/de/fraunhofer/iem/wildcard/ExclusionWildcard.java similarity index 90% rename from WPDS/src/main/java/wpds/wildcard/ExclusionWildcard.java rename to PDS/src/main/java/de/fraunhofer/iem/wildcard/ExclusionWildcard.java index af0d463c..630fffe3 100644 --- a/WPDS/src/main/java/wpds/wildcard/ExclusionWildcard.java +++ b/PDS/src/main/java/de/fraunhofer/iem/wildcard/ExclusionWildcard.java @@ -9,8 +9,8 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package wpds.wildcard; +package de.fraunhofer.iem.wildcard; public interface ExclusionWildcard extends Wildcard { - public Location excludes(); + Location excludes(); } diff --git a/WPDS/src/main/java/wpds/wildcard/Wildcard.java b/PDS/src/main/java/de/fraunhofer/iem/wildcard/Wildcard.java similarity index 88% rename from WPDS/src/main/java/wpds/wildcard/Wildcard.java rename to PDS/src/main/java/de/fraunhofer/iem/wildcard/Wildcard.java index 3eb409b6..7ad80b72 100644 --- a/WPDS/src/main/java/wpds/wildcard/Wildcard.java +++ b/PDS/src/main/java/de/fraunhofer/iem/wildcard/Wildcard.java @@ -9,8 +9,8 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package wpds.wildcard; +package de.fraunhofer.iem.wildcard; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; public interface Wildcard extends Location {} diff --git a/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..3246b19d --- /dev/null +++ b/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,4 @@ +de/fraunhofer/iem/wildcard/ExclusionWildcard.class +de/fraunhofer/iem/Empty.class +de/fraunhofer/iem/Location.class +de/fraunhofer/iem/wildcard/Wildcard.class diff --git a/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..254bc518 --- /dev/null +++ b/PDS/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,4 @@ +/home/smarkus/workspace/Java/SparseBoomerang/PDS/src/main/java/de/fraunhofer/iem/Empty.java +/home/smarkus/workspace/Java/SparseBoomerang/PDS/src/main/java/de/fraunhofer/iem/Location.java +/home/smarkus/workspace/Java/SparseBoomerang/PDS/src/main/java/de/fraunhofer/iem/wildcard/ExclusionWildcard.java +/home/smarkus/workspace/Java/SparseBoomerang/PDS/src/main/java/de/fraunhofer/iem/wildcard/Wildcard.java diff --git a/PDS/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/PDS/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 00000000..e69de29b diff --git a/PDS/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/PDS/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 00000000..e69de29b diff --git a/SparseBoomerangCorrectness/pom.xml b/SparseBoomerangCorrectness/pom.xml index f08f403f..2c72f953 100644 --- a/SparseBoomerangCorrectness/pom.xml +++ b/SparseBoomerangCorrectness/pom.xml @@ -10,6 +10,20 @@ 4.0.0 SparseBoomerangCorrectness + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.1.2 + + true + + + + + junit diff --git a/SparseBoomerangCorrectness/src/main/java/aliasing/SparseAliasManager.java b/SparseBoomerangCorrectness/src/main/java/aliasing/SparseAliasManager.java index 6b4e0114..a3940d54 100644 --- a/SparseBoomerangCorrectness/src/main/java/aliasing/SparseAliasManager.java +++ b/SparseBoomerangCorrectness/src/main/java/aliasing/SparseAliasManager.java @@ -6,7 +6,7 @@ import boomerang.results.BackwardBoomerangResults; import boomerang.scene.*; import boomerang.scene.jimple.*; -import boomerang.scene.sparse.SparseCFGCache; +import boomerang.sparse.SparsificationStrategy; import boomerang.util.AccessPath; import com.google.common.base.Stopwatch; import com.google.common.cache.CacheBuilder; @@ -35,24 +35,24 @@ public class SparseAliasManager { private DataFlowScope dataFlowScope; private boolean disableAliasing = false; - private SparseCFGCache.SparsificationStrategy sparsificationStrategy; + private SparsificationStrategy sparsificationStrategy; private boolean ignoreAfterQuery; static class BoomerangOptions extends DefaultBoomerangOptions { - private SparseCFGCache.SparsificationStrategy sparsificationStrategy; + private SparsificationStrategy sparsificationStrategy; private boolean ignoreAfterQuery; public BoomerangOptions( - SparseCFGCache.SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { this.sparsificationStrategy = sparsificationStrategy; this.ignoreAfterQuery = ignoreAfterQuery; } @Override - public SparseCFGCache.SparsificationStrategy getSparsificationStrategy() { + public SparsificationStrategy getSparsificationStrategy() { if (this.sparsificationStrategy == null) { - return SparseCFGCache.SparsificationStrategy.NONE; + return SparsificationStrategy.NONE; } return this.sparsificationStrategy; } @@ -96,7 +96,7 @@ public boolean trackAnySubclassOfThrowable() { private static Duration totalAliasingDuration; private SparseAliasManager( - SparseCFGCache.SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { this.sparsificationStrategy = sparsificationStrategy; this.ignoreAfterQuery = ignoreAfterQuery; totalAliasingDuration = Duration.ZERO; @@ -110,7 +110,7 @@ public static Duration getTotalDuration() { } public static synchronized SparseAliasManager getInstance( - SparseCFGCache.SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { if (INSTANCE == null || INSTANCE.sparsificationStrategy != sparsificationStrategy || INSTANCE.ignoreAfterQuery != ignoreAfterQuery) { diff --git a/SparseBoomerangCorrectness/src/test/java/test/aliasing/AliasingTestSetUp.java b/SparseBoomerangCorrectness/src/test/java/test/aliasing/AliasingTestSetUp.java index e8b5047e..3697f2a6 100644 --- a/SparseBoomerangCorrectness/src/test/java/test/aliasing/AliasingTestSetUp.java +++ b/SparseBoomerangCorrectness/src/test/java/test/aliasing/AliasingTestSetUp.java @@ -4,7 +4,6 @@ import aliasing.SparseAliasManager; import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.sparse.SparseCFGCache; import boomerang.util.AccessPath; import com.google.common.base.Predicate; import java.io.File; @@ -32,7 +31,7 @@ public Set executeStaticAnalysis( String targetClassName, String targetMethod, String queryLHS, - SparseCFGCache.SparsificationStrategy sparsificationStrategy, + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { setupSoot(targetClassName); registerSootTransformers(queryLHS, sparsificationStrategy, targetMethod, ignoreAfterQuery); @@ -78,7 +77,7 @@ protected void setupSoot(String targetTestClassName) { public Set getAliases( SootMethod method, String queryLHS, - SparseCFGCache.SparsificationStrategy sparsificationStrategy, + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { String[] split = queryLHS.split("\\."); Optional unitOp; @@ -117,7 +116,7 @@ public Set getAliases( protected Transformer createAnalysisTransformer( String queryLHS, - SparseCFGCache.SparsificationStrategy sparsificationStrategy, + SparsificationStrategy sparsificationStrategy, String targetMethod, boolean ignoreAfterQuery) { return new SceneTransformer() { @@ -153,7 +152,7 @@ protected SootMethod getEntryPointMethod(String targetMethod) { protected void registerSootTransformers( String queryLHS, - SparseCFGCache.SparsificationStrategy sparsificationStrategy, + SparsificationStrategy sparsificationStrategy, String targetMethod, boolean ignoreAfterQuery) { Transform transform = @@ -175,66 +174,43 @@ protected void executeSootTransformers() { protected void runAnalyses(String queryLHS, String targetClass, String targetMethod) { Set nonSparseAliases = - getAliases( - targetClass, queryLHS, targetMethod, SparseCFGCache.SparsificationStrategy.NONE, true); + getAliases(targetClass, queryLHS, targetMethod, SparsificationStrategy.NONE, true); Set typeBasedSparseAliases = - getAliases( - targetClass, - queryLHS, - targetMethod, - SparseCFGCache.SparsificationStrategy.TYPE_BASED, - true); + getAliases(targetClass, queryLHS, targetMethod, SparsificationStrategy.TYPE_BASED, true); Set aliasAwareSparseAliases = - getAliases( - targetClass, - queryLHS, - targetMethod, - SparseCFGCache.SparsificationStrategy.ALIAS_AWARE, - true); - checkResults( - SparseCFGCache.SparsificationStrategy.TYPE_BASED, typeBasedSparseAliases, nonSparseAliases); - checkResults( - SparseCFGCache.SparsificationStrategy.ALIAS_AWARE, - aliasAwareSparseAliases, - nonSparseAliases); + getAliases(targetClass, queryLHS, targetMethod, SparsificationStrategy.ALIAS_AWARE, true); + checkResults(SparsificationStrategy.TYPE_BASED, typeBasedSparseAliases, nonSparseAliases); + checkResults(SparsificationStrategy.ALIAS_AWARE, aliasAwareSparseAliases, nonSparseAliases); } protected void runAnalyses( String queryLHS, String targetClass, String targetMethod, boolean ignoreAfterQuery) { Set nonSparseAliases = getAliases( - targetClass, - queryLHS, - targetMethod, - SparseCFGCache.SparsificationStrategy.NONE, - ignoreAfterQuery); + targetClass, queryLHS, targetMethod, SparsificationStrategy.NONE, ignoreAfterQuery); Set typeBasedSparseAliases = getAliases( targetClass, queryLHS, targetMethod, - SparseCFGCache.SparsificationStrategy.TYPE_BASED, + SparsificationStrategy.TYPE_BASED, ignoreAfterQuery); Set aliasAwareSparseAliases = getAliases( targetClass, queryLHS, targetMethod, - SparseCFGCache.SparsificationStrategy.ALIAS_AWARE, + SparsificationStrategy.ALIAS_AWARE, ignoreAfterQuery); - checkResults( - SparseCFGCache.SparsificationStrategy.TYPE_BASED, typeBasedSparseAliases, nonSparseAliases); - checkResults( - SparseCFGCache.SparsificationStrategy.ALIAS_AWARE, - aliasAwareSparseAliases, - nonSparseAliases); + checkResults(SparsificationStrategy.TYPE_BASED, typeBasedSparseAliases, nonSparseAliases); + checkResults(SparsificationStrategy.ALIAS_AWARE, aliasAwareSparseAliases, nonSparseAliases); } protected Set getAliases( String targetClass, String queryLHS, String targetMethod, - SparseCFGCache.SparsificationStrategy sparsificationStrategy, + SparsificationStrategy sparsificationStrategy, boolean ignoreAfterQuery) { Set aliases = executeStaticAnalysis( @@ -243,7 +219,7 @@ protected Set getAliases( } protected void checkResults( - SparseCFGCache.SparsificationStrategy strategy, + SparsificationStrategy strategy, Set sparseAliases, Set nonSparseAliases) { List nonSparse = diff --git a/SynchronizedPDS/.settings/org.eclipse.m2e.core.prefs b/SynchronizedPDS/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f1..00000000 --- a/SynchronizedPDS/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/SynchronizedPDS/pom.xml b/SynchronizedPDS/pom.xml index 59f0ee4f..6b889d3b 100644 --- a/SynchronizedPDS/pom.xml +++ b/SynchronizedPDS/pom.xml @@ -12,7 +12,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + ${maven-surefire-plugin.version} -Xmx8G -Xss128m @@ -36,5 +36,9 @@ junit junit + + de.fraunhofer.iem + PDS + \ No newline at end of file diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/CastNormalRule.java b/SynchronizedPDS/src/main/java/sync/pds/solver/CastNormalRule.java index 2a8a7d0b..dd0f4436 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/CastNormalRule.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/CastNormalRule.java @@ -11,10 +11,10 @@ */ package sync.pds.solver; +import de.fraunhofer.iem.Location; import wpds.impl.NormalRule; import wpds.impl.Transition; import wpds.impl.Weight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class CastNormalRule diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/OneWeightFunctions.java b/SynchronizedPDS/src/main/java/sync/pds/solver/OneWeightFunctions.java index 09471078..6dfc28fa 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/OneWeightFunctions.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/OneWeightFunctions.java @@ -16,7 +16,7 @@ public class OneWeightFunctions implements WeightFunctions { - private W one; + private final W one; public OneWeightFunctions(W one) { this.one = one; diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSSolver.java b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSSolver.java index 827728fa..cca4c38a 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSSolver.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSSolver.java @@ -17,6 +17,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.AbstractMap; import java.util.Collection; import java.util.HashSet; @@ -42,7 +43,6 @@ import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; import wpds.impl.WeightedPushdownSystem; -import wpds.interfaces.Location; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; import wpds.interfaces.WPAUpdateListener; @@ -61,13 +61,13 @@ public enum PDSSystem { protected final WeightedPushdownSystem, W> callingPDS = new WeightedPushdownSystem, W>() { public String toString() { - return "Call " + SyncPDSSolver.this.toString(); + return "Call " + SyncPDSSolver.this; } }; protected final WeightedPushdownSystem>, W> fieldPDS = new WeightedPushdownSystem>, W>() { public String toString() { - return "Field " + SyncPDSSolver.this.toString(); + return "Field " + SyncPDSSolver.this; } }; private final Set> reachedStates = Sets.newHashSet(); @@ -206,7 +206,7 @@ public void nestedAutomaton( private class FieldAddEpsilonToInitialStateListener extends WPAStateListener>, W> { - private WeightedPAutomaton>, W> parent; + private final WeightedPAutomaton>, W> parent; public FieldAddEpsilonToInitialStateListener( INode> state, @@ -249,9 +249,8 @@ public boolean equals(Object obj) { FieldAddEpsilonToInitialStateListener other = (FieldAddEpsilonToInitialStateListener) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (parent == null) { - if (other.parent != null) return false; - } else if (!parent.equals(other.parent)) return false; - return true; + return other.parent == null; + } else return parent.equals(other.parent); } private SyncPDSSolver getOuterType() { @@ -261,7 +260,7 @@ private SyncPDSSolver getOuterType() { private class FieldOnOutTransitionAddToStateListener extends WPAStateListener>, W> { - private Transition>> nestedT; + private final Transition>> nestedT; public FieldOnOutTransitionAddToStateListener( INode> state, Transition>> nestedT) { @@ -300,9 +299,8 @@ public boolean equals(Object obj) { FieldOnOutTransitionAddToStateListener other = (FieldOnOutTransitionAddToStateListener) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (nestedT == null) { - if (other.nestedT != null) return false; - } else if (!nestedT.equals(other.nestedT)) return false; - return true; + return other.nestedT == null; + } else return nestedT.equals(other.nestedT); } private SyncPDSSolver getOuterType() { @@ -323,7 +321,7 @@ public void nestedAutomaton( private class AddEpsilonToInitialStateListener extends WPAStateListener, W> { - private WeightedPAutomaton, W> parent; + private final WeightedPAutomaton, W> parent; public AddEpsilonToInitialStateListener( INode state, WeightedPAutomaton, W> parent) { @@ -364,9 +362,8 @@ public boolean equals(Object obj) { AddEpsilonToInitialStateListener other = (AddEpsilonToInitialStateListener) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (parent == null) { - if (other.parent != null) return false; - } else if (!parent.equals(other.parent)) return false; - return true; + return other.parent == null; + } else return parent.equals(other.parent); } private SyncPDSSolver getOuterType() { @@ -375,7 +372,7 @@ private SyncPDSSolver getOuterType() { } private class OnOutTransitionAddToStateListener extends WPAStateListener, W> { - private Transition> nestedT; + private final Transition> nestedT; public OnOutTransitionAddToStateListener( INode state, Transition> nestedT) { @@ -416,9 +413,8 @@ public boolean equals(Object obj) { OnOutTransitionAddToStateListener other = (OnOutTransitionAddToStateListener) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (nestedT == null) { - if (other.nestedT != null) return false; - } else if (!nestedT.equals(other.nestedT)) return false; - return true; + return other.nestedT == null; + } else return nestedT.equals(other.nestedT); } private SyncPDSSolver getOuterType() { diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSUpdateListener.java b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSUpdateListener.java index 39305588..692be10d 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSUpdateListener.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncPDSUpdateListener.java @@ -11,10 +11,10 @@ */ package sync.pds.solver; +import de.fraunhofer.iem.Location; import sync.pds.solver.nodes.Node; -import wpds.interfaces.Location; public interface SyncPDSUpdateListener { - public void onReachableNodeAdded(Node reachableNode); + void onReachableNodeAdded(Node reachableNode); } diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncStatePDSUpdateListener.java b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncStatePDSUpdateListener.java index 26ad0b8c..d88de2e2 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/SyncStatePDSUpdateListener.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/SyncStatePDSUpdateListener.java @@ -11,12 +11,12 @@ */ package sync.pds.solver; +import de.fraunhofer.iem.Location; import sync.pds.solver.nodes.Node; -import wpds.interfaces.Location; public abstract class SyncStatePDSUpdateListener { - private Node node; + private final Node node; public SyncStatePDSUpdateListener(Node node) { this.node = node; diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/WitnessListener.java b/SynchronizedPDS/src/main/java/sync/pds/solver/WitnessListener.java index 026c9418..c064a6fa 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/WitnessListener.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/WitnessListener.java @@ -11,10 +11,10 @@ */ package sync.pds.solver; +import de.fraunhofer.iem.Location; import sync.pds.solver.nodes.INode; import sync.pds.solver.nodes.Node; import wpds.impl.Transition; -import wpds.interfaces.Location; public interface WitnessListener { diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/CallPopNode.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/CallPopNode.java index e1bed0c4..91b549d3 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/CallPopNode.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/CallPopNode.java @@ -41,8 +41,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; CallPopNode other = (CallPopNode) obj; if (returnSite == null) { - if (other.returnSite != null) return false; - } else if (!returnSite.equals(other.returnSite)) return false; - return true; + return other.returnSite == null; + } else return returnSite.equals(other.returnSite); } } diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/ExclusionNode.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/ExclusionNode.java index 5b330b5a..460f7b7b 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/ExclusionNode.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/ExclusionNode.java @@ -13,7 +13,7 @@ public class ExclusionNode extends Node { - private Location exclusion; + private final Location exclusion; public ExclusionNode(Stmt stmt, Fact variable, Location exclusion) { super(stmt, variable); @@ -35,9 +35,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ExclusionNode other = (ExclusionNode) obj; if (exclusion == null) { - if (other.exclusion != null) return false; - } else if (!exclusion.equals(other.exclusion)) return false; - return true; + return other.exclusion == null; + } else return exclusion.equals(other.exclusion); } public Location exclusion() { diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/GeneratedState.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/GeneratedState.java index 73076bd9..223fa06c 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/GeneratedState.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/GeneratedState.java @@ -13,8 +13,8 @@ public class GeneratedState implements INode { - private INode node; - private N loc; + private final INode node; + private final N loc; public GeneratedState(INode node, N loc) { this.node = node; @@ -59,8 +59,7 @@ public boolean equals(Object obj) { if (other.loc != null) return false; } else if (!loc.equals(other.loc)) return false; if (node == null) { - if (other.node != null) return false; - } else if (!node.equals(other.node)) return false; - return true; + return other.node == null; + } else return node.equals(other.node); } } diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/Node.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/Node.java index 176728a3..baff8bd5 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/Node.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/Node.java @@ -53,9 +53,8 @@ public boolean equals(Object obj) { if (other.stmt != null) return false; } else if (!stmt.equals(other.stmt)) return false; if (variable == null) { - if (other.variable != null) return false; - } else if (!variable.equals(other.variable)) return false; - return true; + return other.variable == null; + } else return variable.equals(other.variable); } @Override diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/NodeWithLocation.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/NodeWithLocation.java index b7ef114f..f08a8df6 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/NodeWithLocation.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/NodeWithLocation.java @@ -13,8 +13,8 @@ public class NodeWithLocation implements INode> { - private Location loc; - private Node fact; + private final Location loc; + private final Node fact; public NodeWithLocation(Stmt stmt, Fact variable, Location loc) { this.fact = new Node<>(stmt, variable); @@ -49,9 +49,8 @@ public boolean equals(Object obj) { if (other.fact != null) return false; } else if (!fact.equals(other.fact)) return false; if (loc == null) { - if (other.loc != null) return false; - } else if (!loc.equals(other.loc)) return false; - return true; + return other.loc == null; + } else return loc.equals(other.loc); } @Override diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PopNode.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PopNode.java index b8193dbf..834d1cf7 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PopNode.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PopNode.java @@ -16,8 +16,8 @@ public class PopNode implements State { - private PDSSystem system; - private Location location; + private final PDSSystem system; + private final Location location; public PopNode(Location location, PDSSystem system) { this.system = system; @@ -43,9 +43,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; PopNode other = (PopNode) obj; if (location == null) { - if (other.location != null) return false; - } else if (!location.equals(other.location)) return false; - return true; + return other.location == null; + } else return location.equals(other.location); } public Location location() { diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PushNode.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PushNode.java index 8042426d..fd2904b5 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PushNode.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/PushNode.java @@ -15,8 +15,8 @@ public class PushNode extends Node { - private PDSSystem system; - private Location location; + private final PDSSystem system; + private final Location location; public PushNode(Stmt stmt, Fact variable, Location location, PDSSystem system) { super(stmt, variable); @@ -47,9 +47,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; PushNode other = (PushNode) obj; if (location == null) { - if (other.location != null) return false; - } else if (!location.equals(other.location)) return false; - return true; + return other.location == null; + } else return location.equals(other.location); } @Override diff --git a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/SingleNode.java b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/SingleNode.java index de7bc31c..6c5767ee 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/SingleNode.java +++ b/SynchronizedPDS/src/main/java/sync/pds/solver/nodes/SingleNode.java @@ -12,7 +12,7 @@ package sync.pds.solver.nodes; public class SingleNode implements INode { - private Fact fact; + private final Fact fact; private int hashCode = 0; public SingleNode(Fact fact) { @@ -36,9 +36,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; SingleNode other = (SingleNode) obj; if (fact == null) { - if (other.fact != null) return false; - } else if (!fact.equals(other.fact)) return false; - return true; + return other.fact == null; + } else return fact.equals(other.fact); } @Override diff --git a/SynchronizedPDS/src/main/java/sync/pds/weights/SetDomain.java b/SynchronizedPDS/src/main/java/sync/pds/weights/SetDomain.java index 6cda318c..8793e952 100644 --- a/SynchronizedPDS/src/main/java/sync/pds/weights/SetDomain.java +++ b/SynchronizedPDS/src/main/java/sync/pds/weights/SetDomain.java @@ -12,11 +12,11 @@ package sync.pds.weights; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.Set; import sync.pds.solver.nodes.Node; import wpds.impl.Weight; -import wpds.interfaces.Location; public class SetDomain extends Weight { @@ -35,7 +35,7 @@ private SetDomain(Collection> nodes) { } public SetDomain(Node node) { - this.nodes = Sets.>newHashSet(node); + this.nodes = Sets.newHashSet(node); this.rep = null; } @@ -98,9 +98,8 @@ public boolean equals(Object obj) { if (other.nodes != null) return false; } else if (!nodes.equals(other.nodes)) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } public Collection> elements() { diff --git a/SynchronizedPDS/src/test/java/analysis/test/DoublePDSTest.java b/SynchronizedPDS/src/test/java/analysis/test/DoublePDSTest.java index ab799836..ca11785f 100644 --- a/SynchronizedPDS/src/test/java/analysis/test/DoublePDSTest.java +++ b/SynchronizedPDS/src/test/java/analysis/test/DoublePDSTest.java @@ -16,6 +16,9 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.ExclusionWildcard; +import de.fraunhofer.iem.wildcard.Wildcard; import java.util.Collection; import org.junit.Test; import org.slf4j.Logger; @@ -32,15 +35,12 @@ import sync.pds.solver.nodes.SingleNode; import wpds.impl.SummaryNestedWeightedPAutomatons; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; -import wpds.wildcard.ExclusionWildcard; -import wpds.wildcard.Wildcard; public class DoublePDSTest { - private static Logger LOGGER = LoggerFactory.getLogger(DoublePDSTest.class); - private Multimap, State> successorMap = HashMultimap.create(); - private Multimap, Node> summaryMap = + private static final Logger LOGGER = LoggerFactory.getLogger(DoublePDSTest.class); + private final Multimap, State> successorMap = HashMultimap.create(); + private final Multimap, Node> summaryMap = HashMultimap.create(); private void addFieldPop( @@ -82,10 +82,11 @@ private void addExcludeField( addSucc(curr, new ExclusionNode<>(succ.stmt(), succ.fact(), push)); } - private FieldRef epsilonField = new FieldRef("EMPTY"); - private Statement epsilonCallSite = new Statement(-1); + private final FieldRef epsilonField = new FieldRef("EMPTY"); + private final Statement epsilonCallSite = new Statement(-1); - private SyncPDSSolver solver = new TestSyncPDSSolver(); + private final SyncPDSSolver solver = + new TestSyncPDSSolver(); private class TestSyncPDSSolver extends SyncPDSSolver { @@ -709,7 +710,7 @@ public ExclusionWildcardField(FieldRef excl) { @Override public FieldRef excludes() { - return (FieldRef) excludes; + return excludes; } @Override @@ -732,9 +733,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ExclusionWildcardField other = (ExclusionWildcardField) obj; if (excludes == null) { - if (other.excludes != null) return false; - } else if (!excludes.equals(other.excludes)) return false; - return true; + return other.excludes == null; + } else return excludes.equals(other.excludes); } } @@ -771,9 +771,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; StringBasedObj other = (StringBasedObj) obj; if (name == null) { - if (other.name != null) return false; - } else if (!name.equals(other.name)) return false; - return true; + return other.name == null; + } else return name.equals(other.name); } @Override diff --git a/WPDS/pom.xml b/WPDS/pom.xml index b092f985..fc4c11c2 100644 --- a/WPDS/pom.xml +++ b/WPDS/pom.xml @@ -8,6 +8,10 @@ 4.0.0 WPDS + + de.fraunhofer.iem + PDS + junit junit diff --git a/WPDS/src/main/java/wpds/debug/Debugger.java b/WPDS/src/main/java/wpds/debug/Debugger.java index 0925cd7f..ee8a70f0 100644 --- a/WPDS/src/main/java/wpds/debug/Debugger.java +++ b/WPDS/src/main/java/wpds/debug/Debugger.java @@ -11,8 +11,8 @@ */ package wpds.debug; +import de.fraunhofer.iem.Location; import wpds.impl.Weight; -import wpds.interfaces.Location; import wpds.interfaces.State; public interface Debugger {} diff --git a/WPDS/src/main/java/wpds/impl/Configuration.java b/WPDS/src/main/java/wpds/impl/Configuration.java index 97d43fc1..4d90515a 100644 --- a/WPDS/src/main/java/wpds/impl/Configuration.java +++ b/WPDS/src/main/java/wpds/impl/Configuration.java @@ -11,12 +11,12 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public class Configuration { - private D state; - private N location; + private final D state; + private final N location; public Configuration(N location, D state) { this.location = location; @@ -42,8 +42,7 @@ public boolean equals(Object obj) { if (other.location != null) return false; } else if (!location.equals(other.location)) return false; if (state == null) { - if (other.state != null) return false; - } else if (!state.equals(other.state)) return false; - return true; + return other.state == null; + } else return state.equals(other.state); } } diff --git a/WPDS/src/main/java/wpds/impl/ConnectPushListener.java b/WPDS/src/main/java/wpds/impl/ConnectPushListener.java index 8f15241c..1d4ce218 100644 --- a/WPDS/src/main/java/wpds/impl/ConnectPushListener.java +++ b/WPDS/src/main/java/wpds/impl/ConnectPushListener.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public interface ConnectPushListener { diff --git a/WPDS/src/main/java/wpds/impl/NestedAutomatonListener.java b/WPDS/src/main/java/wpds/impl/NestedAutomatonListener.java index 3f126ac6..08d62120 100644 --- a/WPDS/src/main/java/wpds/impl/NestedAutomatonListener.java +++ b/WPDS/src/main/java/wpds/impl/NestedAutomatonListener.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public interface NestedAutomatonListener { diff --git a/WPDS/src/main/java/wpds/impl/NestedWeightedPAutomatons.java b/WPDS/src/main/java/wpds/impl/NestedWeightedPAutomatons.java index 631f69ca..10ad4cd2 100644 --- a/WPDS/src/main/java/wpds/impl/NestedWeightedPAutomatons.java +++ b/WPDS/src/main/java/wpds/impl/NestedWeightedPAutomatons.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public interface NestedWeightedPAutomatons { diff --git a/WPDS/src/main/java/wpds/impl/NormalRule.java b/WPDS/src/main/java/wpds/impl/NormalRule.java index 0c0ef18f..6726c20d 100644 --- a/WPDS/src/main/java/wpds/impl/NormalRule.java +++ b/WPDS/src/main/java/wpds/impl/NormalRule.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public class NormalRule diff --git a/WPDS/src/main/java/wpds/impl/PAutomaton.java b/WPDS/src/main/java/wpds/impl/PAutomaton.java index 9bb9777f..227c1cfe 100644 --- a/WPDS/src/main/java/wpds/impl/PAutomaton.java +++ b/WPDS/src/main/java/wpds/impl/PAutomaton.java @@ -11,9 +11,9 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; import pathexpression.LabeledGraph; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public abstract class PAutomaton diff --git a/WPDS/src/main/java/wpds/impl/PopRule.java b/WPDS/src/main/java/wpds/impl/PopRule.java index cf3adbb7..b65a3316 100644 --- a/WPDS/src/main/java/wpds/impl/PopRule.java +++ b/WPDS/src/main/java/wpds/impl/PopRule.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public class PopRule extends Rule { diff --git a/WPDS/src/main/java/wpds/impl/PostStar.java b/WPDS/src/main/java/wpds/impl/PostStar.java index f4f1e7d6..eb2691ab 100644 --- a/WPDS/src/main/java/wpds/impl/PostStar.java +++ b/WPDS/src/main/java/wpds/impl/PostStar.java @@ -11,15 +11,15 @@ */ package wpds.impl; -import wpds.interfaces.Empty; +import de.fraunhofer.iem.Empty; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.ExclusionWildcard; +import de.fraunhofer.iem.wildcard.Wildcard; import wpds.interfaces.IPushdownSystem; -import wpds.interfaces.Location; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; import wpds.interfaces.WPAUpdateListener; import wpds.interfaces.WPDSUpdateListener; -import wpds.wildcard.ExclusionWildcard; -import wpds.wildcard.Wildcard; public abstract class PostStar { private IPushdownSystem pds; @@ -34,7 +34,7 @@ public void poststar(IPushdownSystem pds, WeightedPAutomaton i private class PostStarUpdateListener implements WPDSUpdateListener { - private WeightedPAutomaton aut; + private final WeightedPAutomaton aut; public PostStarUpdateListener(WeightedPAutomaton fa) { aut = fa; @@ -67,17 +67,16 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; PostStarUpdateListener other = (PostStarUpdateListener) obj; if (aut == null) { - if (other.aut != null) return false; - } else if (!aut.equals(other.aut)) return false; - return true; + return other.aut == null; + } else return aut.equals(other.aut); } } private class UpdateTransitivePopListener extends WPAStateListener { - private D start; - private N label; - private W newWeight; + private final D start; + private final N label; + private final W newWeight; public UpdateTransitivePopListener(D start, N label, D target, W newWeight) { super(target); @@ -118,16 +117,15 @@ public boolean equals(Object obj) { if (other.newWeight != null) return false; } else if (!newWeight.equals(other.newWeight)) return false; if (label == null) { - if (other.label != null) return false; - } else if (!label.equals(other.label)) return false; - return true; + return other.label == null; + } else return label.equals(other.label); } } private class HandlePopListener extends WPAStateListener { - private N popLabel; - private D targetState; - private W ruleWeight; + private final N popLabel; + private final D targetState; + private final W ruleWeight; public HandlePopListener(D state, N popLabel, D targetState, W ruleWeight) { super(state); @@ -192,14 +190,13 @@ public boolean equals(Object obj) { if (other.ruleWeight != null) return false; } else if (!ruleWeight.equals(other.ruleWeight)) return false; if (targetState == null) { - if (other.targetState != null) return false; - } else if (!targetState.equals(other.targetState)) return false; - return true; + return other.targetState == null; + } else return targetState.equals(other.targetState); } } private class HandleNormalListener extends WPAStateListener { - private NormalRule rule; + private final NormalRule rule; public HandleNormalListener(NormalRule rule) { super(rule.getS1()); @@ -247,14 +244,13 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; HandleNormalListener other = (HandleNormalListener) obj; if (rule == null) { - if (other.rule != null) return false; - } else if (!rule.equals(other.rule)) return false; - return true; + return other.rule == null; + } else return rule.equals(other.rule); } } private class HandlePushListener extends WPAStateListener { - private PushRule rule; + private final PushRule rule; public HandlePushListener(PushRule rule) { super(rule.getS1()); @@ -291,7 +287,7 @@ public void onOutTransitionAdded( public void onWeightAdded( Transition t, W w, WeightedPAutomaton innerAut) { if ((t.getLabel().equals(fa.epsilon()) && t.getTarget().equals(irState))) { - update(t, (W) w); + update(t, w); W newWeight = getWeightFor(callSiteTransition); update( @@ -326,9 +322,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; HandlePushListener other = (HandlePushListener) obj; if (rule == null) { - if (other.rule != null) return false; - } else if (!rule.equals(other.rule)) return false; - return true; + return other.rule == null; + } else return rule.equals(other.rule); } } diff --git a/WPDS/src/main/java/wpds/impl/PreStar.java b/WPDS/src/main/java/wpds/impl/PreStar.java index 4d2d1444..63efe2af 100644 --- a/WPDS/src/main/java/wpds/impl/PreStar.java +++ b/WPDS/src/main/java/wpds/impl/PreStar.java @@ -13,12 +13,12 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.Wildcard; import java.util.LinkedList; import java.util.List; import wpds.interfaces.IPushdownSystem; -import wpds.interfaces.Location; import wpds.interfaces.State; -import wpds.wildcard.Wildcard; public class PreStar { private LinkedList> worklist = Lists.newLinkedList(); @@ -39,7 +39,7 @@ public WeightedPAutomaton prestar( update( new Transition(r.getS1(), r.getL1(), r.getS2()), r.getWeight(), - Lists.>newLinkedList()); + Lists.newLinkedList()); } while (!worklist.isEmpty()) { @@ -47,7 +47,7 @@ public WeightedPAutomaton prestar( for (NormalRule r : pds.getNormalRulesEnding(t.getStart(), t.getLabel())) { // Normal rules - LinkedList> previous = Lists.>newLinkedList(); + LinkedList> previous = Lists.newLinkedList(); previous.add(t); update(new Transition(r.getS1(), r.getL1(), t.getTarget()), r.getWeight(), previous); } @@ -55,7 +55,7 @@ public WeightedPAutomaton prestar( // Push rules for (Transition tdash : Sets.newHashSet(fa.getTransitions())) { if (tdash.getLabel().equals(r.getCallSite())) { - LinkedList> previous = Lists.>newLinkedList(); + LinkedList> previous = Lists.newLinkedList(); previous.add(t); previous.add(tdash); update( @@ -63,7 +63,7 @@ public WeightedPAutomaton prestar( r.getWeight(), previous); } else if (r.getCallSite() instanceof Wildcard) { - LinkedList> previous = Lists.>newLinkedList(); + LinkedList> previous = Lists.newLinkedList(); previous.add(t); previous.add(tdash); update( @@ -82,7 +82,7 @@ public WeightedPAutomaton prestar( if (!fa.getTransitions().contains(tdash)) { continue; } - LinkedList> previous = Lists.>newLinkedList(); + LinkedList> previous = Lists.newLinkedList(); previous.add(tdash); previous.add(t); N label = ((r.getCallSite() instanceof Wildcard) ? t.getLabel() : r.getL1()); @@ -110,9 +110,8 @@ private void update(Transition trans, W weight, List> pre private W getOrCreateWeight(Transition trans) { W w = fa.getWeightFor(trans); - if (w != null) return w; + return w; // z.setRange(trans.getLabel(), trans.getLabel()); - return null; } } diff --git a/WPDS/src/main/java/wpds/impl/PrefixImport.java b/WPDS/src/main/java/wpds/impl/PrefixImport.java index dd9fc93f..93cfcd98 100644 --- a/WPDS/src/main/java/wpds/impl/PrefixImport.java +++ b/WPDS/src/main/java/wpds/impl/PrefixImport.java @@ -1,6 +1,6 @@ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; @@ -49,7 +49,7 @@ public void trigger(Transition baseT, Transition flowT) { private class Import extends WPAStateListener { - private D flowTarget; + private final D flowTarget; public Import(D state, D flowTarget) { super(state); @@ -84,9 +84,8 @@ public boolean equals(Object obj) { Import other = (Import) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (flowTarget == null) { - if (other.flowTarget != null) return false; - } else if (!flowTarget.equals(other.flowTarget)) return false; - return true; + return other.flowTarget == null; + } else return flowTarget.equals(other.flowTarget); } private PrefixImport getOuterType() { @@ -96,9 +95,9 @@ private PrefixImport getOuterType() { private class IntersectionListener extends WPAStateListener { - private D flowState; - private N label; - private IntersectionCallback callback; + private final D flowState; + private final N label; + private final IntersectionCallback callback; public IntersectionListener(D baseState, D flowState, N label, IntersectionCallback callback) { super(baseState); @@ -139,9 +138,8 @@ public boolean equals(Object obj) { if (other.flowState != null) return false; } else if (!flowState.equals(other.flowState)) return false; if (label == null) { - if (other.label != null) return false; - } else if (!label.equals(other.label)) return false; - return true; + return other.label == null; + } else return label.equals(other.label); } private PrefixImport getOuterType() { @@ -189,9 +187,8 @@ public boolean equals(Object obj) { HasOutTransWithSameLabel other = (HasOutTransWithSameLabel) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (baseT == null) { - if (other.baseT != null) return false; - } else if (!baseT.equals(other.baseT)) return false; - return true; + return other.baseT == null; + } else return baseT.equals(other.baseT); } private PrefixImport getOuterType() { @@ -201,8 +198,8 @@ private PrefixImport getOuterType() { private class IntersectionListenerNoLabel extends WPAStateListener { - private D flowState; - private IntersectionCallback callback; + private final D flowState; + private final IntersectionCallback callback; public IntersectionListenerNoLabel(D baseState, D flowState, IntersectionCallback callback) { super(baseState); @@ -237,9 +234,8 @@ public boolean equals(Object obj) { IntersectionListenerNoLabel other = (IntersectionListenerNoLabel) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (flowState == null) { - if (other.flowState != null) return false; - } else if (!flowState.equals(other.flowState)) return false; - return true; + return other.flowState == null; + } else return flowState.equals(other.flowState); } private PrefixImport getOuterType() { diff --git a/WPDS/src/main/java/wpds/impl/PushRule.java b/WPDS/src/main/java/wpds/impl/PushRule.java index 574b3b90..8f1bf01d 100644 --- a/WPDS/src/main/java/wpds/impl/PushRule.java +++ b/WPDS/src/main/java/wpds/impl/PushRule.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public class PushRule extends Rule { @@ -42,9 +42,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; PushRule other = (PushRule) obj; if (callSite == null) { - if (other.callSite != null) return false; - } else if (!callSite.equals(other.callSite)) return false; - return true; + return other.callSite == null; + } else return callSite.equals(other.callSite); } @Override diff --git a/WPDS/src/main/java/wpds/impl/PushdownSystem.java b/WPDS/src/main/java/wpds/impl/PushdownSystem.java index 57af9cd1..cf313f39 100644 --- a/WPDS/src/main/java/wpds/impl/PushdownSystem.java +++ b/WPDS/src/main/java/wpds/impl/PushdownSystem.java @@ -11,8 +11,8 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class PushdownSystem diff --git a/WPDS/src/main/java/wpds/impl/Rule.java b/WPDS/src/main/java/wpds/impl/Rule.java index 09f8f7b4..d6eebb66 100644 --- a/WPDS/src/main/java/wpds/impl/Rule.java +++ b/WPDS/src/main/java/wpds/impl/Rule.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public abstract class Rule { @@ -92,8 +92,7 @@ public boolean equals(Object obj) { if (other.s2 != null) return false; } else if (!s2.equals(other.s2)) return false; if (w == null) { - if (other.w != null) return false; - } else if (!w.equals(other.w)) return false; - return true; + return other.w == null; + } else return w.equals(other.w); } } diff --git a/WPDS/src/main/java/wpds/impl/StackListener.java b/WPDS/src/main/java/wpds/impl/StackListener.java index 19372ae8..98503bc1 100644 --- a/WPDS/src/main/java/wpds/impl/StackListener.java +++ b/WPDS/src/main/java/wpds/impl/StackListener.java @@ -1,8 +1,8 @@ package wpds.impl; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.Set; -import wpds.interfaces.Location; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; @@ -11,8 +11,8 @@ public abstract class StackListener aut; - private N source; - private Set notifiedStacks = Sets.newHashSet(); + private final N source; + private final Set notifiedStacks = Sets.newHashSet(); public StackListener(WeightedPAutomaton weightedPAutomaton, D state, N source) { super(state); @@ -58,13 +58,12 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; StackListener other = (StackListener) obj; if (source == null) { - if (other.source != null) return false; - } else if (!source.equals(other.source)) return false; - return true; + return other.source == null; + } else return source.equals(other.source); } private class SubStackListener extends WPAStateListener { - private StackListener parent; + private final StackListener parent; public SubStackListener(D state, StackListener parent) { super(state); @@ -106,9 +105,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; SubStackListener other = (SubStackListener) obj; if (parent == null) { - if (other.parent != null) return false; - } else if (!parent.equals(other.parent)) return false; - return true; + return other.parent == null; + } else return parent.equals(other.parent); } } } diff --git a/WPDS/src/main/java/wpds/impl/SummaryNestedWeightedPAutomatons.java b/WPDS/src/main/java/wpds/impl/SummaryNestedWeightedPAutomatons.java index 17f0be6b..46a4e811 100644 --- a/WPDS/src/main/java/wpds/impl/SummaryNestedWeightedPAutomatons.java +++ b/WPDS/src/main/java/wpds/impl/SummaryNestedWeightedPAutomatons.java @@ -12,14 +12,14 @@ package wpds.impl; import com.google.common.collect.Maps; +import de.fraunhofer.iem.Location; import java.util.Map; -import wpds.interfaces.Location; import wpds.interfaces.State; public class SummaryNestedWeightedPAutomatons implements NestedWeightedPAutomatons { - private Map> summaries = Maps.newHashMap(); + private final Map> summaries = Maps.newHashMap(); @Override public void putSummaryAutomaton(D target, WeightedPAutomaton aut) { diff --git a/WPDS/src/main/java/wpds/impl/Transition.java b/WPDS/src/main/java/wpds/impl/Transition.java index 72285a7e..3d7801d1 100644 --- a/WPDS/src/main/java/wpds/impl/Transition.java +++ b/WPDS/src/main/java/wpds/impl/Transition.java @@ -11,10 +11,10 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.Wildcard; import pathexpression.Edge; -import wpds.interfaces.Location; import wpds.interfaces.State; -import wpds.wildcard.Wildcard; public class Transition implements Edge { private final D s1; @@ -69,9 +69,8 @@ public boolean equals(Object obj) { if (other.s1 != null) return false; } else if (!s1.equals(other.s1)) return false; if (s2 == null) { - if (other.s2 != null) return false; - } else if (!s2.equals(other.s2)) return false; - return true; + return other.s2 == null; + } else return s2.equals(other.s2); } @Override diff --git a/WPDS/src/main/java/wpds/impl/UNormalRule.java b/WPDS/src/main/java/wpds/impl/UNormalRule.java index 9e92c21f..3ef92d4a 100644 --- a/WPDS/src/main/java/wpds/impl/UNormalRule.java +++ b/WPDS/src/main/java/wpds/impl/UNormalRule.java @@ -11,8 +11,8 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class UNormalRule extends NormalRule { diff --git a/WPDS/src/main/java/wpds/impl/UPopRule.java b/WPDS/src/main/java/wpds/impl/UPopRule.java index c4e7dc33..e118478e 100644 --- a/WPDS/src/main/java/wpds/impl/UPopRule.java +++ b/WPDS/src/main/java/wpds/impl/UPopRule.java @@ -11,8 +11,8 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class UPopRule extends PopRule { diff --git a/WPDS/src/main/java/wpds/impl/UPushRule.java b/WPDS/src/main/java/wpds/impl/UPushRule.java index c7425bcd..bb1c2c0a 100644 --- a/WPDS/src/main/java/wpds/impl/UPushRule.java +++ b/WPDS/src/main/java/wpds/impl/UPushRule.java @@ -11,8 +11,8 @@ */ package wpds.impl; +import de.fraunhofer.iem.Location; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class UPushRule extends PushRule { diff --git a/WPDS/src/main/java/wpds/impl/UnbalancedPopListener.java b/WPDS/src/main/java/wpds/impl/UnbalancedPopListener.java index 500b3460..9e38d0cb 100644 --- a/WPDS/src/main/java/wpds/impl/UnbalancedPopListener.java +++ b/WPDS/src/main/java/wpds/impl/UnbalancedPopListener.java @@ -11,7 +11,7 @@ */ package wpds.impl; -import wpds.interfaces.Location; +import de.fraunhofer.iem.Location; import wpds.interfaces.State; public interface UnbalancedPopListener { diff --git a/WPDS/src/main/java/wpds/impl/WeightedPAutomaton.java b/WPDS/src/main/java/wpds/impl/WeightedPAutomaton.java index 6c16a79d..167244d2 100644 --- a/WPDS/src/main/java/wpds/impl/WeightedPAutomaton.java +++ b/WPDS/src/main/java/wpds/impl/WeightedPAutomaton.java @@ -20,6 +20,7 @@ import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.google.common.collect.Table; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -38,7 +39,6 @@ import pathexpression.RegEx; import wpds.interfaces.ForwardDFSEpsilonVisitor; import wpds.interfaces.ForwardDFSVisitor; -import wpds.interfaces.Location; import wpds.interfaces.ReachabilityListener; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; @@ -47,7 +47,7 @@ public abstract class WeightedPAutomaton implements LabeledGraph { private static final Logger LOGGER = LoggerFactory.getLogger(WeightedPAutomaton.class); - private Map, W> transitionToWeights = new HashMap<>(); + private final Map, W> transitionToWeights = new HashMap<>(); // Set Q is implicit // Weighted Pushdown Systems and their Application to Interprocedural // Dataflow Analysis @@ -59,19 +59,20 @@ public abstract class WeightedPAutomaton states = Sets.newHashSet(); private final Multimap> transitionsOutOf = HashMultimap.create(); private final Multimap> transitionsInto = HashMultimap.create(); - private Set> listeners = Sets.newHashSet(); - private Multimap> stateListeners = HashMultimap.create(); - private Map> stateToDFS = Maps.newHashMap(); - private Map> stateToEpsilonDFS = Maps.newHashMap(); - private Set> nestedAutomatons = Sets.newHashSet(); - private Set> nestedAutomataListeners = Sets.newHashSet(); - private Map> stateToEpsilonReachabilityListener = Maps.newHashMap(); - private Map> stateToReachabilityListener = Maps.newHashMap(); - private Set connectedPushes = Sets.newHashSet(); - private Set> conntectedPushListeners = Sets.newHashSet(); - private Set> unbalancedPopListeners = Sets.newHashSet(); - private Map unbalancedPops = Maps.newHashMap(); - private Map, W> transitionsToFinalWeights = Maps.newHashMap(); + private final Set> listeners = Sets.newHashSet(); + private final Multimap> stateListeners = HashMultimap.create(); + private final Map> stateToDFS = Maps.newHashMap(); + private final Map> stateToEpsilonDFS = Maps.newHashMap(); + private final Set> nestedAutomatons = Sets.newHashSet(); + private final Set> nestedAutomataListeners = Sets.newHashSet(); + private final Map> stateToEpsilonReachabilityListener = + Maps.newHashMap(); + private final Map> stateToReachabilityListener = Maps.newHashMap(); + private final Set connectedPushes = Sets.newHashSet(); + private final Set> conntectedPushListeners = Sets.newHashSet(); + private final Set> unbalancedPopListeners = Sets.newHashSet(); + private final Map unbalancedPops = Maps.newHashMap(); + private final Map, W> transitionsToFinalWeights = Maps.newHashMap(); private ForwardDFSVisitor dfsVisitor; private ForwardDFSVisitor dfsEpsVisitor; public int failedAdditions; @@ -79,9 +80,9 @@ public abstract class WeightedPAutomaton initialAutomaton; private PathExpressionComputer pathExpressionComputer; private int lastStates = 0; - private Stopwatch watch = Stopwatch.createUnstarted(); - private Map stateToDistanceToInitial = Maps.newHashMap(); - private Map stateToUnbalancedDistance = Maps.newHashMap(); + private final Stopwatch watch = Stopwatch.createUnstarted(); + private final Map stateToDistanceToInitial = Maps.newHashMap(); + private final Map stateToUnbalancedDistance = Maps.newHashMap(); private final Map> stateCreatingTransition = Maps.newHashMap(); public abstract D createState(D d, N loc); @@ -123,13 +124,13 @@ private String wrapIfInitialOrFinalState(D s) { } private String wrapFinalState(D s) { - return finalState.contains(s) ? "TO: " + s + "" : s.toString(); + return finalState.contains(s) ? "TO: " + s : s.toString(); } private static final boolean SUMMARIZE = false; public String toDotString() { - return toDotString(Sets.>newHashSet()); + return toDotString(Sets.newHashSet()); } private String toDotString(Set> visited) { @@ -257,7 +258,7 @@ public IRegEx extractLanguage(D from) { if (res == null) { res = regEx; } else { - res = RegEx.union(res, regEx); + res = RegEx.union(res, regEx); } } if (res == null) return new RegEx.EmptySet(); @@ -498,8 +499,8 @@ public void unbalancedPop(D targetState, Transition trans, W weight) { } } - private Set> summaryEdges = Sets.newHashSet(); - private Set> summaryEdgeListener = Sets.newHashSet(); + private final Set> summaryEdges = Sets.newHashSet(); + private final Set> summaryEdgeListener = Sets.newHashSet(); public void registerSummaryEdge(Transition t) { if (summaryEdges.add(t)) { @@ -555,9 +556,8 @@ public boolean equals(Object obj) { if (other.targetState != null) return false; } else if (!targetState.equals(other.targetState)) return false; if (trans == null) { - if (other.trans != null) return false; - } else if (!trans.equals(other.trans)) return false; - return true; + return other.trans == null; + } else return trans.equals(other.trans); } private WeightedPAutomaton getOuterType() { @@ -601,9 +601,8 @@ public boolean equals(Object obj) { if (other.returnedFact != null) return false; } else if (!returnedFact.equals(other.returnedFact)) return false; if (returnedWeight == null) { - if (other.returnedWeight != null) return false; - } else if (!returnedWeight.equals(other.returnedWeight)) return false; - return true; + return other.returnedWeight == null; + } else return returnedWeight.equals(other.returnedWeight); } private WeightedPAutomaton getOuterType() { @@ -623,7 +622,7 @@ public Map, W> getTransitionsToFinalWeights() { private class ValueComputationListener extends WPAStateListener { - private W weight; + private final W weight; public ValueComputationListener(D state, W weight) { super(state); @@ -661,9 +660,8 @@ public boolean equals(Object obj) { ValueComputationListener other = (ValueComputationListener) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (weight == null) { - if (other.weight != null) return false; - } else if (!weight.equals(other.weight)) return false; - return true; + return other.weight == null; + } else return weight.equals(other.weight); } private WeightedPAutomaton getOuterType() { diff --git a/WPDS/src/main/java/wpds/impl/WeightedPushdownSystem.java b/WPDS/src/main/java/wpds/impl/WeightedPushdownSystem.java index 41d3e356..b7aa3a2f 100644 --- a/WPDS/src/main/java/wpds/impl/WeightedPushdownSystem.java +++ b/WPDS/src/main/java/wpds/impl/WeightedPushdownSystem.java @@ -14,13 +14,13 @@ import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.Wildcard; import java.util.HashSet; import java.util.Set; import wpds.interfaces.IPushdownSystem; -import wpds.interfaces.Location; import wpds.interfaces.State; import wpds.interfaces.WPDSUpdateListener; -import wpds.wildcard.Wildcard; public class WeightedPushdownSystem implements IPushdownSystem { diff --git a/WPDS/src/main/java/wpds/interfaces/ForwardDFSEpsilonVisitor.java b/WPDS/src/main/java/wpds/interfaces/ForwardDFSEpsilonVisitor.java index 7319381c..23cf3a12 100644 --- a/WPDS/src/main/java/wpds/interfaces/ForwardDFSEpsilonVisitor.java +++ b/WPDS/src/main/java/wpds/interfaces/ForwardDFSEpsilonVisitor.java @@ -11,6 +11,8 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Empty; +import de.fraunhofer.iem.Location; import wpds.impl.Transition; import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; diff --git a/WPDS/src/main/java/wpds/interfaces/ForwardDFSVisitor.java b/WPDS/src/main/java/wpds/interfaces/ForwardDFSVisitor.java index 99f2ba5d..6309ac55 100644 --- a/WPDS/src/main/java/wpds/interfaces/ForwardDFSVisitor.java +++ b/WPDS/src/main/java/wpds/interfaces/ForwardDFSVisitor.java @@ -16,6 +16,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Table; +import de.fraunhofer.iem.Location; import java.util.LinkedList; import wpds.impl.Transition; import wpds.impl.Weight; @@ -23,12 +24,12 @@ public class ForwardDFSVisitor implements WPAUpdateListener { - private Multimap> listeners = HashMultimap.create(); + private final Multimap> listeners = HashMultimap.create(); protected WeightedPAutomaton aut; - private Multimap adjacent = HashMultimap.create(); - private Multimap reaches = HashMultimap.create(); - private Multimap inverseReaches = HashMultimap.create(); - private Table refCount = HashBasedTable.create(); + private final Multimap adjacent = HashMultimap.create(); + private final Multimap reaches = HashMultimap.create(); + private final Multimap inverseReaches = HashMultimap.create(); + private final Table refCount = HashBasedTable.create(); public ForwardDFSVisitor(WeightedPAutomaton aut) { this.aut = aut; @@ -44,8 +45,8 @@ public void registerListener(D state, final ReachabilityListener l) { private class TransitiveClosure extends WPAStateListener { - private ReachabilityListener listener; - private D s; + private final ReachabilityListener listener; + private final D s; public TransitiveClosure(D state, D s, ReachabilityListener l) { super(state); @@ -82,9 +83,8 @@ public boolean equals(Object obj) { if (other.s != null) return false; } else if (!s.equals(other.s)) return false; if (listener == null) { - if (other.listener != null) return false; - } else if (!listener.equals(other.listener)) return false; - return true; + return other.listener == null; + } else return listener.equals(other.listener); } private ForwardDFSVisitor getOuterType() { @@ -188,9 +188,8 @@ public boolean equals(Object obj) { if (other.from != null) return false; } else if (!from.equals(other.from)) return false; if (to == null) { - if (other.to != null) return false; - } else if (!to.equals(other.to)) return false; - return true; + return other.to == null; + } else return to.equals(other.to); } } @@ -209,8 +208,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ForwardDFSVisitor other = (ForwardDFSVisitor) obj; if (aut == null) { - if (other.aut != null) return false; - } else if (!aut.equals(other.aut)) return false; - return true; + return other.aut == null; + } else return aut.equals(other.aut); } } diff --git a/WPDS/src/main/java/wpds/interfaces/IPushdownSystem.java b/WPDS/src/main/java/wpds/interfaces/IPushdownSystem.java index 3ad67fd3..de57068e 100644 --- a/WPDS/src/main/java/wpds/interfaces/IPushdownSystem.java +++ b/WPDS/src/main/java/wpds/interfaces/IPushdownSystem.java @@ -11,6 +11,7 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Location; import java.util.Set; import wpds.impl.NestedWeightedPAutomatons; import wpds.impl.NormalRule; diff --git a/WPDS/src/main/java/wpds/interfaces/ReachabilityListener.java b/WPDS/src/main/java/wpds/interfaces/ReachabilityListener.java index 802a603c..904a9869 100644 --- a/WPDS/src/main/java/wpds/interfaces/ReachabilityListener.java +++ b/WPDS/src/main/java/wpds/interfaces/ReachabilityListener.java @@ -11,6 +11,7 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Location; import wpds.impl.Transition; public interface ReachabilityListener { diff --git a/WPDS/src/main/java/wpds/interfaces/WPAStateListener.java b/WPDS/src/main/java/wpds/interfaces/WPAStateListener.java index d05ff97c..aeaddec3 100644 --- a/WPDS/src/main/java/wpds/interfaces/WPAStateListener.java +++ b/WPDS/src/main/java/wpds/interfaces/WPAStateListener.java @@ -11,6 +11,7 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Location; import wpds.impl.Transition; import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; @@ -48,8 +49,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WPAStateListener other = (WPAStateListener) obj; if (state == null) { - if (other.state != null) return false; - } else if (!state.equals(other.state)) return false; - return true; + return other.state == null; + } else return state.equals(other.state); } } diff --git a/WPDS/src/main/java/wpds/interfaces/WPAUpdateListener.java b/WPDS/src/main/java/wpds/interfaces/WPAUpdateListener.java index c2f5652b..8e382517 100644 --- a/WPDS/src/main/java/wpds/interfaces/WPAUpdateListener.java +++ b/WPDS/src/main/java/wpds/interfaces/WPAUpdateListener.java @@ -11,6 +11,7 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Location; import wpds.impl.Transition; import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; diff --git a/WPDS/src/main/java/wpds/interfaces/WPDSUpdateListener.java b/WPDS/src/main/java/wpds/interfaces/WPDSUpdateListener.java index 043cf9a2..89af7fcb 100644 --- a/WPDS/src/main/java/wpds/interfaces/WPDSUpdateListener.java +++ b/WPDS/src/main/java/wpds/interfaces/WPDSUpdateListener.java @@ -11,10 +11,11 @@ */ package wpds.interfaces; +import de.fraunhofer.iem.Location; import wpds.impl.Rule; import wpds.impl.Weight; public interface WPDSUpdateListener { - public void onRuleAdded(Rule rule); + void onRuleAdded(Rule rule); } diff --git a/WPDS/src/main/java/wpds/wildcard/WildcardPushdownSystem.java b/WPDS/src/main/java/wpds/wildcard/WildcardPushdownSystem.java index 4b5428f7..1a353286 100644 --- a/WPDS/src/main/java/wpds/wildcard/WildcardPushdownSystem.java +++ b/WPDS/src/main/java/wpds/wildcard/WildcardPushdownSystem.java @@ -11,6 +11,8 @@ */ package wpds.wildcard; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.Wildcard; import java.util.HashSet; import java.util.Set; import wpds.impl.NormalRule; @@ -22,7 +24,6 @@ import wpds.impl.UPopRule; import wpds.impl.UPushRule; import wpds.impl.Weight.NoWeight; -import wpds.interfaces.Location; import wpds.interfaces.State; public abstract class WildcardPushdownSystem diff --git a/WPDS/src/test/java/tests/ForwardDFSVisitorTest.java b/WPDS/src/test/java/tests/ForwardDFSVisitorTest.java index a8d9dafe..9d9f16fb 100644 --- a/WPDS/src/test/java/tests/ForwardDFSVisitorTest.java +++ b/WPDS/src/test/java/tests/ForwardDFSVisitorTest.java @@ -97,7 +97,7 @@ public void reachable(Transition t) { fa.addTransition(t(2, "n1", 4)); - Assert.assertTrue(fa.getTransitions().size() == reachables.size()); + Assert.assertEquals(fa.getTransitions().size(), reachables.size()); Assert.assertTrue(reachableMinusTrans().isEmpty()); fa.addTransition(t(3, "n1", 8)); diff --git a/WPDS/src/test/java/tests/MinSemiring.java b/WPDS/src/test/java/tests/MinSemiring.java index 455c9d0a..cbb96321 100644 --- a/WPDS/src/test/java/tests/MinSemiring.java +++ b/WPDS/src/test/java/tests/MinSemiring.java @@ -11,8 +11,8 @@ */ package tests; +import de.fraunhofer.iem.Location; import wpds.impl.Weight; -import wpds.interfaces.Location; public class MinSemiring extends Weight { int i; @@ -86,7 +86,6 @@ public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; MinSemiring other = (MinSemiring) obj; - if (i != other.i) return false; - return true; + return i == other.i; } } diff --git a/WPDS/src/test/java/tests/NumWeight.java b/WPDS/src/test/java/tests/NumWeight.java index 1a785648..b4d26ba4 100644 --- a/WPDS/src/test/java/tests/NumWeight.java +++ b/WPDS/src/test/java/tests/NumWeight.java @@ -11,8 +11,8 @@ */ package tests; +import de.fraunhofer.iem.Location; import wpds.impl.Weight; -import wpds.interfaces.Location; public class NumWeight extends Weight { @@ -99,7 +99,6 @@ public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; NumWeight other = (NumWeight) obj; - if (i != other.i) return false; - return true; + return i == other.i; } } diff --git a/WPDS/src/test/java/tests/PrefixImportTests.java b/WPDS/src/test/java/tests/PrefixImportTests.java index 93ee0ea2..6629df97 100644 --- a/WPDS/src/test/java/tests/PrefixImportTests.java +++ b/WPDS/src/test/java/tests/PrefixImportTests.java @@ -2,11 +2,11 @@ import static org.junit.Assert.assertTrue; +import de.fraunhofer.iem.Location; import org.junit.Test; import wpds.impl.PAutomaton; import wpds.impl.PrefixImport; import wpds.impl.Transition; -import wpds.interfaces.Location; import wpds.interfaces.State; public class PrefixImportTests { @@ -92,7 +92,7 @@ private Transition t(String start, String label, String } class StringState implements State { - private String rep; + private final String rep; public StringState(String string) { rep = string; @@ -119,9 +119,8 @@ public boolean equals(Object obj) { StringState other = (StringState) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } @Override @@ -153,12 +152,11 @@ public boolean equals(Object obj) { StringLoc other = (StringLoc) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } - private String rep; + private final String rep; public StringLoc(String string) { rep = string; diff --git a/WPDS/src/test/java/tests/TestHelper.java b/WPDS/src/test/java/tests/TestHelper.java index 6142922d..807aca7e 100644 --- a/WPDS/src/test/java/tests/TestHelper.java +++ b/WPDS/src/test/java/tests/TestHelper.java @@ -11,6 +11,7 @@ */ package tests; +import de.fraunhofer.iem.Location; import wpds.impl.NormalRule; import wpds.impl.PAutomaton; import wpds.impl.PopRule; @@ -20,7 +21,6 @@ import wpds.impl.UPopRule; import wpds.impl.UPushRule; import wpds.impl.WeightedPAutomaton; -import wpds.interfaces.Location; import wpds.interfaces.State; public class TestHelper { @@ -175,9 +175,8 @@ public boolean equals(Object obj) { Abstraction other = (Abstraction) obj; if (a != other.a) return false; if (s == null) { - if (other.s != null) return false; - } else if (!s.equals(other.s)) return false; - return true; + return other.s == null; + } else return s.equals(other.s); } } @@ -203,9 +202,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; StackSymbol other = (StackSymbol) obj; if (s == null) { - if (other.s != null) return false; - } else if (!s.equals(other.s)) return false; - return true; + return other.s == null; + } else return s.equals(other.s); } @Override diff --git a/boomerangPDS/pom.xml b/boomerangPDS/pom.xml index 3b6b8f9b..06bea4e7 100644 --- a/boomerangPDS/pom.xml +++ b/boomerangPDS/pom.xml @@ -1,4 +1,5 @@ - + de.fraunhofer.iem SPDS @@ -7,12 +8,13 @@ 4.0.0 boomerangPDS + org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + ${maven-surefire-plugin.version} -Xmx8G -Xss128m @@ -27,7 +29,10 @@ de.fraunhofer.iem boomerangScope - 3.2.3 + + + de.fraunhofer.iem + synchronizedPDS com.google.guava @@ -41,14 +46,14 @@ com.googlecode.json-simple json-simple 1.1.1 - - - org.slf4j - slf4j-api - - - org.slf4j - slf4j-simple + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-simple @@ -63,7 +68,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + ${maven-surefire-plugin.version} + + + integration-test + + **/*LongTest.java diff --git a/boomerangPDS/src/main/java/boomerang/Boomerang.java b/boomerangPDS/src/main/java/boomerang/Boomerang.java index e8cea8cd..f830bc5a 100644 --- a/boomerangPDS/src/main/java/boomerang/Boomerang.java +++ b/boomerangPDS/src/main/java/boomerang/Boomerang.java @@ -11,11 +11,8 @@ */ package boomerang; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Field; -import boomerang.scene.Val; import sync.pds.solver.OneWeightFunctions; import sync.pds.solver.WeightFunctions; import wpds.impl.Weight; @@ -25,12 +22,13 @@ public class Boomerang extends WeightedBoomerang { private OneWeightFunctions fieldWeights; private OneWeightFunctions callWeights; - public Boomerang(CallGraph callGraph, DataFlowScope scope) { - super(callGraph, scope); + public Boomerang(CallGraph callGraph, DataFlowScope scope, FrameworkScope scopeFactory) { + super(callGraph, scope, scopeFactory); } - public Boomerang(CallGraph callGraph, DataFlowScope scope, BoomerangOptions opt) { - super(callGraph, scope, opt); + public Boomerang( + CallGraph callGraph, DataFlowScope scope, BoomerangOptions opt, FrameworkScope scopeFactory) { + super(callGraph, scope, opt, scopeFactory); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/BoomerangOptions.java b/boomerangPDS/src/main/java/boomerang/BoomerangOptions.java index 7df3c608..38f54030 100644 --- a/boomerangPDS/src/main/java/boomerang/BoomerangOptions.java +++ b/boomerangPDS/src/main/java/boomerang/BoomerangOptions.java @@ -19,9 +19,9 @@ import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.sparse.SparseCFGCache; import boomerang.stats.IBoomerangStats; import java.util.Optional; +import sparse.SparsificationStrategy; public interface BoomerangOptions { @@ -105,7 +105,7 @@ enum ArrayStrategy { boolean allowMultipleQueries(); - SparseCFGCache.SparsificationStrategy getSparsificationStrategy(); + SparsificationStrategy getSparsificationStrategy(); boolean handleSpecialInvokeAsNormalPropagation(); diff --git a/boomerangPDS/src/main/java/boomerang/BoomerangTimeoutException.java b/boomerangPDS/src/main/java/boomerang/BoomerangTimeoutException.java index bd151398..94e201d8 100644 --- a/boomerangPDS/src/main/java/boomerang/BoomerangTimeoutException.java +++ b/boomerangPDS/src/main/java/boomerang/BoomerangTimeoutException.java @@ -15,8 +15,8 @@ public class BoomerangTimeoutException extends RuntimeException { - private IBoomerangStats stats; - private long elapsed; + private final IBoomerangStats stats; + private final long elapsed; BoomerangTimeoutException(long elapsed, IBoomerangStats stats) { this.elapsed = elapsed; diff --git a/boomerangPDS/src/main/java/boomerang/Context.java b/boomerangPDS/src/main/java/boomerang/Context.java index bcd3d663..a8832fb9 100644 --- a/boomerangPDS/src/main/java/boomerang/Context.java +++ b/boomerangPDS/src/main/java/boomerang/Context.java @@ -9,9 +9,9 @@ * @author "Johannes Spaeth" */ public interface Context { - public Statement getStmt(); + Statement getStmt(); - public int hashCode(); + int hashCode(); - public boolean equals(Object obj); + boolean equals(Object obj); } diff --git a/boomerangPDS/src/main/java/boomerang/DefaultBoomerangOptions.java b/boomerangPDS/src/main/java/boomerang/DefaultBoomerangOptions.java index 527108e6..a4a73c22 100644 --- a/boomerangPDS/src/main/java/boomerang/DefaultBoomerangOptions.java +++ b/boomerangPDS/src/main/java/boomerang/DefaultBoomerangOptions.java @@ -19,7 +19,6 @@ import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.sparse.SparseCFGCache; import boomerang.stats.IBoomerangStats; import boomerang.stats.SimpleBoomerangStats; import com.google.common.base.Joiner; @@ -27,6 +26,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import sparse.SparsificationStrategy; public class DefaultBoomerangOptions implements BoomerangOptions { @@ -218,8 +218,8 @@ public boolean allowMultipleQueries() { } @Override - public SparseCFGCache.SparsificationStrategy getSparsificationStrategy() { - return SparseCFGCache.SparsificationStrategy.NONE; + public SparsificationStrategy getSparsificationStrategy() { + return new SparsificationStrategy.NoSparsificationStrategy(); } @Override @@ -233,7 +233,7 @@ public boolean ignoreSparsificationAfterQuery() { } public void checkValid() { - if (trackPathConditions() == false && prunePathConditions()) { + if (!trackPathConditions() && prunePathConditions()) { throw new RuntimeException( "InvalidCombinations of Options, Path Conditions must be ables when pruning path conditions"); } diff --git a/boomerangPDS/src/main/java/boomerang/IContextRequester.java b/boomerangPDS/src/main/java/boomerang/IContextRequester.java index f58dbfd3..a1e97c56 100644 --- a/boomerangPDS/src/main/java/boomerang/IContextRequester.java +++ b/boomerangPDS/src/main/java/boomerang/IContextRequester.java @@ -4,7 +4,7 @@ import java.util.Collection; public interface IContextRequester { - public Collection getCallSiteOf(Context child); + Collection getCallSiteOf(Context child); - public Context initialContext(Statement stmt); + Context initialContext(Statement stmt); } diff --git a/boomerangPDS/src/main/java/boomerang/Query.java b/boomerangPDS/src/main/java/boomerang/Query.java index b4794dd1..2acfdc1e 100644 --- a/boomerangPDS/src/main/java/boomerang/Query.java +++ b/boomerangPDS/src/main/java/boomerang/Query.java @@ -64,9 +64,8 @@ public boolean equals(Object obj) { if (other.cfgEdge != null) return false; } else if (!cfgEdge.equals(other.cfgEdge)) return false; if (variable == null) { - if (other.variable != null) return false; - } else if (!variable.equals(other.variable)) return false; - return true; + return other.variable == null; + } else return variable.equals(other.variable); } public Type getType() { diff --git a/boomerangPDS/src/main/java/boomerang/QueryGraph.java b/boomerangPDS/src/main/java/boomerang/QueryGraph.java index 6d4061b9..5c85e86a 100644 --- a/boomerangPDS/src/main/java/boomerang/QueryGraph.java +++ b/boomerangPDS/src/main/java/boomerang/QueryGraph.java @@ -34,12 +34,12 @@ public class QueryGraph { private static final Logger LOGGER = LoggerFactory.getLogger(QueryGraph.class); private final ObservableICFG icfg; - private Multimap sourceToQueryEdgeLookUp = HashMultimap.create(); - private Multimap targetToQueryEdgeLookUp = HashMultimap.create(); - private Set roots = Sets.newHashSet(); - private DefaultValueMap> forwardSolvers; - private Multimap edgeAddListener = HashMultimap.create(); - private DefaultValueMap> backwardSolver; + private final Multimap sourceToQueryEdgeLookUp = HashMultimap.create(); + private final Multimap targetToQueryEdgeLookUp = HashMultimap.create(); + private final Set roots = Sets.newHashSet(); + private final DefaultValueMap> forwardSolvers; + private final Multimap edgeAddListener = HashMultimap.create(); + private final DefaultValueMap> backwardSolver; public QueryGraph(WeightedBoomerang weightedBoomerang) { this.forwardSolvers = weightedBoomerang.getSolvers(); @@ -83,9 +83,9 @@ public Set getNodes() { private class SourceListener extends WPAStateListener, W> { - private Query child; - private Query parent; - private Method callee; + private final Query child; + private final Query parent; + private final Method callee; public SourceListener(INode state, Query parent, Query child, Method callee) { super(state); @@ -151,9 +151,8 @@ public boolean equals(Object obj) { if (other.child != null) return false; } else if (!child.equals(other.child)) return false; if (parent == null) { - if (other.parent != null) return false; - } else if (!parent.equals(other.parent)) return false; - return true; + return other.parent == null; + } else return parent.equals(other.parent); } private QueryGraph getEnclosingInstance() { @@ -194,8 +193,8 @@ private interface AddTargetEdgeListener { private class UnbalancedContextListener implements AddTargetEdgeListener { private final Transition> transition; - private Query parent; - private Query child; + private final Query parent; + private final Query child; public UnbalancedContextListener(Query child, Query parent, Transition> t) { this.child = child; @@ -262,9 +261,8 @@ public boolean equals(Object obj) { if (other.parent != null) return false; } else if (!parent.equals(other.parent)) return false; if (parent == null) { - if (other.transition != null) return false; - } else if (!transition.equals(other.transition)) return false; - return true; + return other.transition == null; + } else return transition.equals(other.transition); } private QueryGraph getEnclosingInstance() { @@ -308,7 +306,7 @@ private String escapeQuotes(String string) { private static class QueryEdge { private final Query source; private final Query target; - private Node node; + private final Node node; public QueryEdge(Query source, Node node, Query target) { this.source = source; @@ -351,9 +349,8 @@ public boolean equals(Object obj) { if (other.target != null) return false; } else if (!target.equals(other.target)) return false; if (node == null) { - if (other.node != null) return false; - } else if (!node.equals(other.node)) return false; - return true; + return other.node == null; + } else return node.equals(other.node); } } diff --git a/boomerangPDS/src/main/java/boomerang/WeightedBoomerang.java b/boomerangPDS/src/main/java/boomerang/WeightedBoomerang.java index d79b25b2..0f8ca47e 100644 --- a/boomerangPDS/src/main/java/boomerang/WeightedBoomerang.java +++ b/boomerangPDS/src/main/java/boomerang/WeightedBoomerang.java @@ -28,21 +28,9 @@ import boomerang.poi.PointOfIndirection; import boomerang.results.BackwardBoomerangResults; import boomerang.results.ForwardBoomerangResults; -import boomerang.scene.AllocVal; -import boomerang.scene.CallGraph; -import boomerang.scene.ControlFlowGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Field; import boomerang.scene.Field.ArrayField; -import boomerang.scene.Method; -import boomerang.scene.Pair; -import boomerang.scene.Statement; -import boomerang.scene.StaticFieldVal; -import boomerang.scene.Val; -import boomerang.scene.jimple.JimpleField; -import boomerang.scene.jimple.JimpleMethod; -import boomerang.scene.jimple.JimpleStaticFieldVal; import boomerang.solver.AbstractBoomerangSolver; import boomerang.solver.BackwardBoomerangSolver; import boomerang.solver.ControlFlowEdgeBasedFieldTransitionListener; @@ -64,9 +52,9 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import soot.SootMethod; import sync.pds.solver.SyncPDSSolver.PDSSystem; import sync.pds.solver.WeightFunctions; import sync.pds.solver.nodes.GeneratedState; @@ -85,17 +73,19 @@ import wpds.interfaces.WPAStateListener; public abstract class WeightedBoomerang { + protected final FrameworkScope scopeFactory; protected ObservableICFG icfg; protected ObservableControlFlowGraph cfg; private static final Logger LOGGER = LoggerFactory.getLogger(WeightedBoomerang.class); - private Map>, Field>, INode>> genField = + private final Map>, Field>, INode>> genField = new HashMap<>(); private long lastTick; - private IBoomerangStats stats; - private Set visitedMethods = Sets.newHashSet(); - private Set> solverCreationListeners = Sets.newHashSet(); - private Multimap> poiListeners = HashMultimap.create(); - private Multimap>> activatedPoi = HashMultimap.create(); + private final IBoomerangStats stats; + private final Set visitedMethods = Sets.newHashSet(); + private final Set> solverCreationListeners = Sets.newHashSet(); + private final Multimap> poiListeners = + HashMultimap.create(); + private final Multimap>> activatedPoi = HashMultimap.create(); private final DefaultValueMap> queryToSolvers = new DefaultValueMap>() { @Override @@ -195,32 +185,28 @@ private void handleStaticInitializer( && node.fact().isStatic() && isFirstStatementOfEntryPoint(node.stmt().getStart())) { Val fact = node.fact(); - if (fact instanceof JimpleStaticFieldVal) { - JimpleStaticFieldVal val = ((JimpleStaticFieldVal) fact); - for (SootMethod m : - ((JimpleField) val.field()).getSootField().getDeclaringClass().getMethods()) { - if (!m.hasActiveBody()) { - continue; - } - JimpleMethod jimpleMethod = JimpleMethod.of(m); - if (m.isStaticInitializer()) { - for (Statement ep : icfg().getEndPointsOf(JimpleMethod.of(m))) { - StaticFieldVal newVal = - new JimpleStaticFieldVal(((JimpleField) val.field()), jimpleMethod); - cfg.addPredsOfListener( - new PredecessorListener(ep) { - @Override - public void getPredecessor(Statement pred) { - backwardSolver.addNormalCallFlow( - node, new Node<>(new Edge(pred, ep), newVal)); - backwardSolver.addNormalFieldFlow( - node, new Node<>(new Edge(pred, ep), newVal)); - } - }); + Stream methodStream = scopeFactory.handleStaticFieldInitializers(fact); + + methodStream.forEach( + m -> { + // TODO: [ms] check if still needed: I removed the "interner" JimpleMethod.of(m) + if (m.isStaticInitializer()) { + for (Statement ep : icfg.getEndPointsOf(m)) { + StaticFieldVal newVal = + scopeFactory.newStaticFieldVal(((StaticFieldVal) fact).field(), m); + cfg.addPredsOfListener( + new PredecessorListener(ep) { + @Override + public void getPredecessor(Statement pred) { + backwardSolver.addNormalCallFlow( + node, new Node<>(new ControlFlowGraph.Edge(pred, ep), newVal)); + backwardSolver.addNormalFieldFlow( + node, new Node<>(new ControlFlowGraph.Edge(pred, ep), newVal)); + } + }); + } } - } - } - } + }); } } @@ -388,15 +374,15 @@ public void checkTimeout() { } private ObservableICFG bwicfg; - private NestedWeightedPAutomatons, W> backwardCallSummaries = + private final NestedWeightedPAutomatons, W> backwardCallSummaries = new SummaryNestedWeightedPAutomatons<>(); - private NestedWeightedPAutomatons>, W> backwardFieldSummaries = + private final NestedWeightedPAutomatons>, W> backwardFieldSummaries = new SummaryNestedWeightedPAutomatons<>(); - private NestedWeightedPAutomatons, W> forwardCallSummaries = + private final NestedWeightedPAutomatons, W> forwardCallSummaries = new SummaryNestedWeightedPAutomatons<>(); - private NestedWeightedPAutomatons>, W> forwardFieldSummaries = + private final NestedWeightedPAutomatons>, W> forwardFieldSummaries = new SummaryNestedWeightedPAutomatons<>(); - private DefaultValueMap fieldWrites = + private final DefaultValueMap fieldWrites = new DefaultValueMap() { @Override protected FieldWritePOI createItem(FieldWritePOI key) { @@ -405,12 +391,14 @@ protected FieldWritePOI createItem(FieldWritePOI key) { } }; protected final BoomerangOptions options; - private Stopwatch analysisWatch = Stopwatch.createUnstarted(); + private final Stopwatch analysisWatch = Stopwatch.createUnstarted(); private final DataFlowScope dataFlowscope; - private CallGraph callGraph; + private final CallGraph callGraph; private INode rootQuery; - public WeightedBoomerang(CallGraph cg, DataFlowScope scope, BoomerangOptions options) { + public WeightedBoomerang( + CallGraph cg, DataFlowScope scope, BoomerangOptions options, FrameworkScope scopeFactory) { + this.scopeFactory = scopeFactory; this.options = options; this.options.checkValid(); this.stats = options.statsFactory(); @@ -432,8 +420,8 @@ public WeightedBoomerang(CallGraph cg, DataFlowScope scope, BoomerangOptions opt this.queryGraph = new QueryGraph<>(this); } - public WeightedBoomerang(CallGraph cg, DataFlowScope scope) { - this(cg, scope, new DefaultBoomerangOptions()); + public WeightedBoomerang(CallGraph cg, DataFlowScope scope, FrameworkScope scopeFactory) { + this(cg, scope, new DefaultBoomerangOptions(), scopeFactory); } protected void addVisitedMethod(Method method) { @@ -658,8 +646,8 @@ public QueryGraph getQueryGraph() { private final class EmptyFieldListener extends WPAStateListener>, W> { - private BackwardQuery key; - private Node node; + private final BackwardQuery key; + private final Node node; public EmptyFieldListener(BackwardQuery key, Node node) { super(new SingleNode<>(node)); @@ -681,8 +669,7 @@ public boolean equals(Object obj) { if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; EmptyFieldListener other = (EmptyFieldListener) obj; - if (!getEnclosingInstance().equals(other.getEnclosingInstance())) return false; - return true; + return getEnclosingInstance().equals(other.getEnclosingInstance()); } @Override @@ -725,9 +712,9 @@ private final class ArrayAllocationListener extends WPAStateListener>, W> { private final int arrayAccessIndex; - private AllocVal val; - private BackwardQuery key; - private Node node; + private final AllocVal val; + private final BackwardQuery key; + private final Node node; public ArrayAllocationListener( int arrayAccessIndex, @@ -785,8 +772,7 @@ public boolean equals(Object obj) { if (!super.equals(obj)) return false; if (getClass() != obj.getClass()) return false; ArrayAllocationListener other = (ArrayAllocationListener) obj; - if (!getEnclosingInstance().equals(other.getEnclosingInstance())) return false; - return true; + return getEnclosingInstance().equals(other.getEnclosingInstance()); } } @@ -831,9 +817,8 @@ public boolean equals(Object obj) { ForwardHandleFieldWrite other = (ForwardHandleFieldWrite) obj; if (!getOuterType().equals(other.getOuterType())) return false; if (sourceQuery == null) { - if (other.sourceQuery != null) return false; - } else if (!sourceQuery.equals(other.sourceQuery)) return false; - return true; + return other.sourceQuery == null; + } else return sourceQuery.equals(other.sourceQuery); } private WeightedBoomerang getOuterType() { @@ -893,9 +878,8 @@ public boolean equals(Object obj) { if (other.fieldWritePoi != null) return false; } else if (!fieldWritePoi.equals(other.fieldWritePoi)) return false; if (sourceQuery == null) { - if (other.sourceQuery != null) return false; - } else if (!sourceQuery.equals(other.sourceQuery)) return false; - return true; + return other.sourceQuery == null; + } else return sourceQuery.equals(other.sourceQuery); } private WeightedBoomerang getOuterType() { @@ -952,6 +936,7 @@ public ForwardBoomerangResults solve(ForwardQuery query) { analysisWatch.stop(); } return new ForwardBoomerangResults( + scopeFactory, query, icfg(), cfg(), @@ -1065,6 +1050,7 @@ public ForwardBoomerangResults solveUnderScope( analysisWatch.stop(); } return new ForwardBoomerangResults( + scopeFactory, query, icfg(), cfg(), @@ -1265,8 +1251,8 @@ public void registerActivationListener(SolverPair solverPair, ExecuteImportField private class SolverPair { - private AbstractBoomerangSolver flowSolver; - private AbstractBoomerangSolver baseSolver; + private final AbstractBoomerangSolver flowSolver; + private final AbstractBoomerangSolver baseSolver; public SolverPair( AbstractBoomerangSolver flowSolver, AbstractBoomerangSolver baseSolver) { @@ -1295,9 +1281,8 @@ public boolean equals(Object obj) { if (other.baseSolver != null) return false; } else if (!baseSolver.equals(other.baseSolver)) return false; if (flowSolver == null) { - if (other.flowSolver != null) return false; - } else if (!flowSolver.equals(other.flowSolver)) return false; - return true; + return other.flowSolver == null; + } else return flowSolver.equals(other.flowSolver); } private WeightedBoomerang getOuterType() { diff --git a/boomerangPDS/src/main/java/boomerang/WholeProgramBoomerang.java b/boomerangPDS/src/main/java/boomerang/WholeProgramBoomerang.java index 5cbc4990..2c1ab779 100644 --- a/boomerangPDS/src/main/java/boomerang/WholeProgramBoomerang.java +++ b/boomerangPDS/src/main/java/boomerang/WholeProgramBoomerang.java @@ -11,11 +11,8 @@ */ package boomerang; -import boomerang.scene.AnalysisScope; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Statement; import java.util.Collection; import java.util.Collections; import wpds.impl.Weight; @@ -23,15 +20,16 @@ public abstract class WholeProgramBoomerang extends WeightedBoomerang { private int reachableMethodCount; private int allocationSites; - private CallGraph callGraph; + private final CallGraph callGraph; - public WholeProgramBoomerang(CallGraph cg, DataFlowScope scope, BoomerangOptions opts) { - super(cg, scope, opts); + public WholeProgramBoomerang( + CallGraph cg, DataFlowScope scope, BoomerangOptions opts, FrameworkScope scopeFactory) { + super(cg, scope, opts, scopeFactory); this.callGraph = cg; } - public WholeProgramBoomerang(CallGraph cg, DataFlowScope scope) { - this(cg, scope, new DefaultBoomerangOptions()); + public WholeProgramBoomerang(CallGraph cg, DataFlowScope scope, FrameworkScope scopeFactory) { + this(cg, scope, new DefaultBoomerangOptions(), scopeFactory); } public void wholeProgramAnalysis() { diff --git a/boomerangPDS/src/main/java/boomerang/callgraph/BoomerangResolver.java b/boomerangPDS/src/main/java/boomerang/callgraph/BoomerangResolver.java index 7d1b9374..cc28d6da 100644 --- a/boomerangPDS/src/main/java/boomerang/callgraph/BoomerangResolver.java +++ b/boomerangPDS/src/main/java/boomerang/callgraph/BoomerangResolver.java @@ -7,16 +7,8 @@ import boomerang.SolverCreationListener; import boomerang.WeightedBoomerang; import boomerang.results.ExtractAllocationSiteStateListener; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.DeclaredMethod; -import boomerang.scene.InvokeExpr; -import boomerang.scene.Method; -import boomerang.scene.Statement; -import boomerang.scene.Type; -import boomerang.scene.Val; -import boomerang.scene.WrappedClass; import boomerang.solver.AbstractBoomerangSolver; import boomerang.solver.ForwardBoomerangSolver; import com.google.common.collect.HashMultimap; @@ -47,16 +39,18 @@ public enum NoCalleeFoundFallbackOptions { private static final String THREAD_START_SIGNATURE = ""; private static final String THREAD_RUN_SUB_SIGNATURE = "void run()"; - private static NoCalleeFoundFallbackOptions FALLBACK_OPTION = NoCalleeFoundFallbackOptions.BYPASS; - private static Multimap didNotFindMethodLog = HashMultimap.create(); + private static final NoCalleeFoundFallbackOptions FALLBACK_OPTION = + NoCalleeFoundFallbackOptions.BYPASS; + private static final Multimap didNotFindMethodLog = + HashMultimap.create(); - private CallGraph precomputedCallGraph; - private WeightedBoomerang solver; - private Set queriedInvokeExprAndAllocationSitesFound = Sets.newHashSet(); - private Set queriedInvokeExpr = Sets.newHashSet(); + private final CallGraph precomputedCallGraph; + private final WeightedBoomerang solver; + private final Set queriedInvokeExprAndAllocationSitesFound = Sets.newHashSet(); + private final Set queriedInvokeExpr = Sets.newHashSet(); - public BoomerangResolver(CallGraph cg, DataFlowScope scope) { - this.solver = new Boomerang(cg, scope); + public BoomerangResolver(CallGraph cg, DataFlowScope scope, FrameworkScope scopeFactory) { + this.solver = new Boomerang(cg, scope, scopeFactory); this.precomputedCallGraph = cg; } @@ -268,9 +262,8 @@ public boolean equals(Object obj) { if (other.query != null) return false; } else if (!query.equals(other.query)) return false; if (invokeExpr == null) { - if (other.invokeExpr != null) return false; - } else if (!invokeExpr.equals(other.invokeExpr)) return false; - return true; + return other.invokeExpr == null; + } else return invokeExpr.equals(other.invokeExpr); } private BoomerangResolver getOuterType() { diff --git a/boomerangPDS/src/main/java/boomerang/callgraph/ObservableDynamicICFG.java b/boomerangPDS/src/main/java/boomerang/callgraph/ObservableDynamicICFG.java index e401ff82..f7c70ea0 100644 --- a/boomerangPDS/src/main/java/boomerang/callgraph/ObservableDynamicICFG.java +++ b/boomerangPDS/src/main/java/boomerang/callgraph/ObservableDynamicICFG.java @@ -30,7 +30,7 @@ public class ObservableDynamicICFG implements ObservableICFG private int numberOfEdgesTakenFromPrecomputedCallGraph = 0; - private CallGraphOptions options = new CallGraphOptions(); + private final CallGraphOptions options = new CallGraphOptions(); private CallGraph demandDrivenCallGraph = new CallGraph(); private final Multimap> calleeListeners = diff --git a/boomerangPDS/src/main/java/boomerang/callgraph/ObservableStaticICFG.java b/boomerangPDS/src/main/java/boomerang/callgraph/ObservableStaticICFG.java index b7e6ba8e..7e9b6f48 100644 --- a/boomerangPDS/src/main/java/boomerang/callgraph/ObservableStaticICFG.java +++ b/boomerangPDS/src/main/java/boomerang/callgraph/ObservableStaticICFG.java @@ -17,7 +17,7 @@ */ public class ObservableStaticICFG implements ObservableICFG { /** Wrapped static ICFG. If available, this is used to handle all queries. */ - private CallGraph precomputedGraph; + private final CallGraph precomputedGraph; private static final Logger LOGGER = LoggerFactory.getLogger(ObservableStaticICFG.class); private static final int IMPRECISE_CALL_GRAPH_WARN_THRESHOLD = 30000; diff --git a/boomerangPDS/src/main/java/boomerang/controlflowgraph/ForwardSolverSuccessorListener.java b/boomerangPDS/src/main/java/boomerang/controlflowgraph/ForwardSolverSuccessorListener.java index fe36493d..1707e0ec 100644 --- a/boomerangPDS/src/main/java/boomerang/controlflowgraph/ForwardSolverSuccessorListener.java +++ b/boomerangPDS/src/main/java/boomerang/controlflowgraph/ForwardSolverSuccessorListener.java @@ -5,19 +5,13 @@ import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.JimpleMethod; -import boomerang.scene.jimple.JimpleStatement; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGCache; import boomerang.solver.ForwardBoomerangSolver; import java.util.Collection; -import soot.SootMethod; -import soot.jimple.Stmt; import sync.pds.solver.nodes.Node; import wpds.interfaces.State; /** - * To replace the anonymous impl in ForwardSolver, so that we can access the Edge fiel of the outer + * To replace the anonymous impl in ForwardSolver, so that we can access the Edge field of the outer * method */ public class ForwardSolverSuccessorListener extends SuccessorListener { @@ -119,6 +113,7 @@ public void getSuccessor(Statement succ) { } } + /* [ms] method was unused? private SparseAliasingCFG getSparseCFG(Method method, Statement stmt, Val currentVal) { SootMethod sootMethod = ((JimpleMethod) method).getDelegate(); Stmt sootStmt = ((JimpleStatement) stmt).getDelegate(); @@ -128,4 +123,5 @@ private SparseAliasingCFG getSparseCFG(Method method, Statement stmt, Val curren sparseCFGCache.getSparseCFGForForwardPropagation(sootMethod, sootStmt, currentVal); return sparseCFG; } + */ } diff --git a/boomerangPDS/src/main/java/boomerang/controlflowgraph/StaticCFG.java b/boomerangPDS/src/main/java/boomerang/controlflowgraph/StaticCFG.java index f8e0675f..63349258 100644 --- a/boomerangPDS/src/main/java/boomerang/controlflowgraph/StaticCFG.java +++ b/boomerangPDS/src/main/java/boomerang/controlflowgraph/StaticCFG.java @@ -4,22 +4,13 @@ import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.JimpleMethod; -import boomerang.scene.jimple.JimpleStatement; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGCache; -import boomerang.scene.sparse.eval.PropagationCounter; -import java.util.*; -import soot.SootMethod; -import soot.Unit; -import soot.jimple.Stmt; +import sparse.SparsificationStrategy; public class StaticCFG implements ObservableControlFlowGraph { - private SparseCFGCache.SparsificationStrategy sparsificationStrategy; + private final SparsificationStrategy sparsificationStrategy; - private BoomerangOptions options; + private final BoomerangOptions options; private Val currentVal; @@ -43,7 +34,9 @@ public void addPredsOfListener(PredecessorListener l) { public void addSuccsOfListener(SuccessorListener l) { Method method = l.getCurr().getMethod(); Statement curr = l.getCurr(); - if (sparsificationStrategy != SparseCFGCache.SparsificationStrategy.NONE) { + /* + TODO: [ms] reenable sparsification + if (sparsificationStrategy != SparsificationStrategy.NONE) { SparseAliasingCFG sparseCFG = getSparseCFG(method, curr, currentVal); if (sparseCFG != null) { propagateSparse(l, method, curr, sparseCFG); @@ -52,27 +45,33 @@ public void addSuccsOfListener(SuccessorListener l) { } else { propagateDefault(l); // back up when not found } - } else { + } else */ + { propagateDefault(l); } } + /* + TODO: [ms] reenable sparsification private void propagateSparse( SuccessorListener l, Method method, Statement curr, SparseAliasingCFG sparseCFG) { Set successors = sparseCFG.getGraph().successors(SootAdapter.asStmt(curr)); for (Unit succ : successors) { - PropagationCounter.getInstance(sparsificationStrategy).countForward(); + sparsificationStrategy.getCounter().countForward(); l.getSuccessor(SootAdapter.asStatement(succ, method)); } } + */ private void propagateDefault(SuccessorListener l) { for (Statement s : l.getCurr().getMethod().getControlFlowGraph().getSuccsOf(l.getCurr())) { - PropagationCounter.getInstance(sparsificationStrategy).countForward(); + sparsificationStrategy.getCounter().countForwardPropagation(); l.getSuccessor(s); } } + /* + TODO: [ms] reenable sparsification private SparseAliasingCFG getSparseCFG(Method method, Statement stmt, Val currentVal) { SootMethod sootMethod = ((JimpleMethod) method).getDelegate(); Stmt sootStmt = ((JimpleStatement) stmt).getDelegate(); @@ -83,6 +82,7 @@ private SparseAliasingCFG getSparseCFG(Method method, Statement stmt, Val curren sparseCFGCache.getSparseCFGForForwardPropagation(sootMethod, sootStmt, currentVal); return sparseCFG; } + */ @Override public void step(Statement curr, Statement succ) {} diff --git a/boomerangPDS/src/main/java/boomerang/debugger/CallGraphDebugger.java b/boomerangPDS/src/main/java/boomerang/debugger/CallGraphDebugger.java index df8dc992..6c8dab4d 100644 --- a/boomerangPDS/src/main/java/boomerang/debugger/CallGraphDebugger.java +++ b/boomerangPDS/src/main/java/boomerang/debugger/CallGraphDebugger.java @@ -30,17 +30,17 @@ public class CallGraphDebugger extends Debugger { private static final Logger logger = LoggerFactory.getLogger(CallGraphDebugger.class); private File dotFile; - private ObservableICFG icfg; + private final ObservableICFG icfg; private CallGraph callGraph; - private HashSet totalCallSites = new HashSet<>(); - private Multimap virtualCallSites = HashMultimap.create(); + private final HashSet totalCallSites = new HashSet<>(); + private final Multimap virtualCallSites = HashMultimap.create(); private int numVirtualCallSites; private int numVirtualCallSitesSingleTarget; private int numVirtualCallSitesMultipleTarget; private float avgNumTargetsVirtualCallSites; private float avgNumTargetMultiTargetCallSites; - private Multimap predecessors = HashMultimap.create(); + private final Multimap predecessors = HashMultimap.create(); private float avgNumOfPredecessors; private int numOfEdgesInCallGraph; private int numEdgesFromPrecomputed; diff --git a/boomerangPDS/src/main/java/boomerang/debugger/IDEVizDebugger.java b/boomerangPDS/src/main/java/boomerang/debugger/IDEVizDebugger.java index 3e2b4c6b..f4f522db 100644 --- a/boomerangPDS/src/main/java/boomerang/debugger/IDEVizDebugger.java +++ b/boomerangPDS/src/main/java/boomerang/debugger/IDEVizDebugger.java @@ -56,12 +56,13 @@ public class IDEVizDebugger extends Debugger { - private static boolean ONLY_CFG = false; + private static final boolean ONLY_CFG = false; private static final Logger logger = LoggerFactory.getLogger(IDEVizDebugger.class); - private File ideVizFile; + private final File ideVizFile; private ObservableICFG icfg; - private Table, W>>> rules = HashBasedTable.create(); - private Map objectToInteger = new HashMap<>(); + private final Table, W>>> rules = + HashBasedTable.create(); + private final Map objectToInteger = new HashMap<>(); private int charSize; private ObservableControlFlowGraph cfg; @@ -129,7 +130,6 @@ public void done( queryJSON.put("methods", data); eventualData.add(queryJSON); } - ; logger.info("Computing visualization took: {}", watch.elapsed()); try (FileWriter file = new FileWriter(ideVizFile)) { logger.info("Writing visualization to file {}", ideVizFile.getAbsolutePath()); diff --git a/boomerangPDS/src/main/java/boomerang/flowfunction/DefaultForwardFlowFunction.java b/boomerangPDS/src/main/java/boomerang/flowfunction/DefaultForwardFlowFunction.java index 5787a082..dbc89372 100644 --- a/boomerangPDS/src/main/java/boomerang/flowfunction/DefaultForwardFlowFunction.java +++ b/boomerangPDS/src/main/java/boomerang/flowfunction/DefaultForwardFlowFunction.java @@ -185,17 +185,13 @@ protected boolean killFlow(Statement curr, Val value) { // But not for a statement x = x.f if (curr.isFieldLoad()) { Pair ifr = curr.getFieldLoad(); - if (ifr.getX().equals(value)) { - return false; - } + return !ifr.getX().equals(value); } return true; } if (curr.isStaticFieldStore()) { StaticFieldVal sf = curr.getStaticField(); - if (value.isStatic() && value.equals(sf)) { - return true; - } + return value.isStatic() && value.equals(sf); } } return false; diff --git a/boomerangPDS/src/main/java/boomerang/guided/DemandDrivenGuidedAnalysis.java b/boomerangPDS/src/main/java/boomerang/guided/DemandDrivenGuidedAnalysis.java index c4721a4b..007e391e 100644 --- a/boomerangPDS/src/main/java/boomerang/guided/DemandDrivenGuidedAnalysis.java +++ b/boomerangPDS/src/main/java/boomerang/guided/DemandDrivenGuidedAnalysis.java @@ -10,21 +10,17 @@ import boomerang.results.AbstractBoomerangResults.Context; import boomerang.results.BackwardBoomerangResults; import boomerang.results.ForwardBoomerangResults; +import boomerang.scene.CallGraph; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.DataFlowScope; -import boomerang.scene.SootDataFlowScope; +import boomerang.scene.FrameworkScope; import boomerang.scene.Val; -import boomerang.scene.jimple.SootCallGraph; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.collect.Table; import com.google.common.collect.Table.Cell; -import java.util.Collection; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; -import soot.Scene; import sync.pds.solver.nodes.Node; import wpds.impl.Weight.NoWeight; @@ -33,7 +29,7 @@ public class DemandDrivenGuidedAnalysis { private final BoomerangOptions customBoomerangOptions; private final IDemandDrivenGuidedManager spec; private final DataFlowScope scope; - private final SootCallGraph callGraph; + private final CallGraph callGraph; private final LinkedList queryQueue = Lists.newLinkedList(); private final Set visited = Sets.newHashSet(); private final Boomerang solver; @@ -42,21 +38,18 @@ public class DemandDrivenGuidedAnalysis { public DemandDrivenGuidedAnalysis( IDemandDrivenGuidedManager specification, BoomerangOptions options, - DataFlowScope dataFlowScope) { + DataFlowScope dataFlowScope, + CallGraph callGraph, + FrameworkScope scopeFactory) { spec = specification; - callGraph = new SootCallGraph(); scope = dataFlowScope; + this.callGraph = callGraph; if (!options.allowMultipleQueries()) { throw new RuntimeException( "Boomerang options allowMultipleQueries is set to false. Please enable it."); } customBoomerangOptions = options; - solver = new Boomerang(callGraph, scope, customBoomerangOptions); - } - - public DemandDrivenGuidedAnalysis( - IDemandDrivenGuidedManager specification, BoomerangOptions options) { - this(specification, options, SootDataFlowScope.make(Scene.v())); + solver = new Boomerang(callGraph, scope, customBoomerangOptions, scopeFactory); } /** @@ -78,6 +71,7 @@ public QueryGraph run(Query query) { } triggered = true; queryQueue.add(new QueryWithContext(query)); + while (!queryQueue.isEmpty()) { QueryWithContext pop = queryQueue.pop(); if (pop.query instanceof ForwardQuery) { @@ -92,7 +86,7 @@ public QueryGraph run(Query query) { Table forwardResults = results.asEdgeValWeightTable((ForwardQuery) pop.query); // Any ForwardQuery may trigger additional ForwardQuery under its own scope. - triggerNewBackwardQueries(forwardResults, currentQuery, QueryDirection.FORWARD); + triggerNewQueries(forwardResults, currentQuery, QueryDirection.FORWARD); } else { BackwardBoomerangResults results; if (pop.parentQuery == null) { @@ -102,14 +96,16 @@ public QueryGraph run(Query query) { solver.solveUnderScope( (BackwardQuery) pop.query, pop.triggeringNode, pop.parentQuery); } + Table backwardResults = solver.getBackwardSolvers().get(query).asEdgeValWeightTable(); - - triggerNewBackwardQueries(backwardResults, pop.query, QueryDirection.BACKWARD); + // TODO: [ms] figure out why its structurally + // different than with Forwardqueries - potential? + triggerNewQueries(backwardResults, pop.query, QueryDirection.BACKWARD); Map allocationSites = results.getAllocationSites(); for (Entry entry : allocationSites.entrySet()) { - triggerNewBackwardQueries( + triggerNewQueries( results.asEdgeValWeightTable(entry.getKey()), entry.getKey(), QueryDirection.FORWARD); } } @@ -131,7 +127,7 @@ public Boomerang getSolver() { return solver; } - private void triggerNewBackwardQueries( + private void triggerNewQueries( Table backwardResults, Query lastQuery, QueryDirection direction) { for (Cell cell : backwardResults.cellSet()) { Edge triggeringEdge = cell.getRowKey(); @@ -145,17 +141,15 @@ private void triggerNewBackwardQueries( spec.onBackwardFlow((BackwardQuery) lastQuery, cell.getRowKey(), cell.getColumnKey()); } for (Query q : queries) { - addToQueue(new QueryWithContext(q, new Node<>(triggeringEdge, fact), lastQuery)); + if (visited.add(q)) { + QueryWithContext nextQuery = + new QueryWithContext(q, new Node<>(triggeringEdge, fact), lastQuery); + queryQueue.add(nextQuery); + } } } } - private void addToQueue(QueryWithContext nextQuery) { - if (visited.add(nextQuery.query)) { - queryQueue.add(nextQuery); - } - } - private static class QueryWithContext { private QueryWithContext(Query query) { this.query = query; diff --git a/boomerangPDS/src/main/java/boomerang/guided/SimpleSpecificationGuidedManager.java b/boomerangPDS/src/main/java/boomerang/guided/SimpleSpecificationGuidedManager.java index b9f9fdcf..701d701e 100644 --- a/boomerangPDS/src/main/java/boomerang/guided/SimpleSpecificationGuidedManager.java +++ b/boomerangPDS/src/main/java/boomerang/guided/SimpleSpecificationGuidedManager.java @@ -3,22 +3,20 @@ import boomerang.BackwardQuery; import boomerang.ForwardQuery; import boomerang.Query; +import boomerang.guided.Specification.MethodWithSelector; import boomerang.guided.Specification.Parameter; import boomerang.guided.Specification.QueryDirection; import boomerang.guided.Specification.QuerySelector; -import boomerang.guided.Specification.SootMethodWithSelector; import boomerang.scene.AllocVal; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.JimpleStatement; import com.google.common.collect.Sets; import java.util.Collection; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; -import soot.jimple.Stmt; public class SimpleSpecificationGuidedManager implements IDemandDrivenGuidedManager { @@ -33,11 +31,11 @@ public Collection onForwardFlow(ForwardQuery query, Edge dataFlowEdge, Va Statement stmt = dataFlowEdge.getStart(); Set res = Sets.newHashSet(); if (stmt.containsInvokeExpr()) { - Set selectors = + Set selectors = spec.getMethodAndQueries().stream() .filter(x -> isInOnList(x, stmt, dataFlowVal, QueryDirection.FORWARD)) .collect(Collectors.toSet()); - for (SootMethodWithSelector sel : selectors) { + for (MethodWithSelector sel : selectors) { res.addAll(createNewQueries(sel, stmt)); } } @@ -49,18 +47,18 @@ public Collection onBackwardFlow(BackwardQuery query, Edge dataFlowEdge, Statement stmt = dataFlowEdge.getStart(); Set res = Sets.newHashSet(); if (stmt.containsInvokeExpr()) { - Set selectors = + Set selectors = spec.getMethodAndQueries().stream() .filter(x -> isInOnList(x, stmt, dataFlowVal, QueryDirection.BACKWARD)) .collect(Collectors.toSet()); - for (SootMethodWithSelector sel : selectors) { + for (MethodWithSelector sel : selectors) { res.addAll(createNewQueries(sel, stmt)); } } return res; } - private Collection createNewQueries(SootMethodWithSelector sel, Statement stmt) { + private Collection createNewQueries(MethodWithSelector sel, Statement stmt) { Set results = Sets.newHashSet(); Method method = stmt.getMethod(); for (QuerySelector qSel : sel.getGo()) { @@ -84,19 +82,20 @@ private Collection createNewQueries(SootMethodWithSelector sel, Statement } public boolean isInOnList( - SootMethodWithSelector methodSelector, Statement stmt, Val fact, QueryDirection direction) { - if (stmt instanceof JimpleStatement) { - // This only works for Soot propagations - Stmt jimpleStmt = ((JimpleStatement) stmt).getDelegate(); - if (jimpleStmt - .getInvokeExpr() - .getMethod() - .getSignature() - .equals(methodSelector.getSootMethod())) { - Collection on = methodSelector.getOn(); - return isInList(on, direction, stmt, fact); - } + MethodWithSelector methodSelector, Statement stmt, Val fact, QueryDirection direction) { + + // [spaeth] This only works for Soot propagations + // TODO: [ms] refactored soot checks away.. lets investigate why! maybe it needs just some + // translation/mapping for other frameworks + if (!stmt.getClass().toString().contains("Jimple")) { + // lets notify us in such a case.. + throw new UnsupportedOperationException("possibly unspported case? investigate!"); } + if (stmt.getInvokeExpr().getMethod().getSignature().equals(methodSelector.getMethodStr())) { + Collection on = methodSelector.getOn(); + return isInList(on, direction, stmt, fact); + } + return false; } diff --git a/boomerangPDS/src/main/java/boomerang/guided/Specification.java b/boomerangPDS/src/main/java/boomerang/guided/Specification.java index a59e45dc..4dc390d3 100644 --- a/boomerangPDS/src/main/java/boomerang/guided/Specification.java +++ b/boomerangPDS/src/main/java/boomerang/guided/Specification.java @@ -22,13 +22,13 @@ public enum QueryDirection { BACKWARD } - private final Set methodAndQueries; + private final Set methodAndQueries; private Specification(Collection spec) { methodAndQueries = spec.stream().map(x -> parse(x)).collect(Collectors.toSet()); } - private SootMethodWithSelector parse(String input) { + private MethodWithSelector parse(String input) { Pattern arguments = Pattern.compile("\\((.*?)\\)"); Matcher argumentMatcher = arguments.matcher(input); Set on = Sets.newHashSet(); @@ -71,14 +71,14 @@ private SootMethodWithSelector parse(String input) { + go.stream().filter(x -> x.direction == QueryDirection.FORWARD).count(); if (input.length() != sootMethod.length() - + (on.size() * ON_SELECTOR.length() - + go.size() * GO_SELECTOR.length() + + ((long) on.size() * ON_SELECTOR.length() + + (long) go.size() * GO_SELECTOR.length() + backwardQueryCount * BACKWARD.length() + forwardQueryCount * FORWARD.length())) { throw new RuntimeException("Parsing Specification failed. Please check your specification"); } - return new SootMethodWithSelector(sootMethod, on, go); + return new MethodWithSelector(sootMethod, on, go); } private void createQuerySelector( @@ -95,17 +95,17 @@ private void createQuerySelector( } } - public static class SootMethodWithSelector { - SootMethodWithSelector( - String sootMethod, Collection on, Collection go) { - this.sootMethod = sootMethod; + public static class MethodWithSelector { + MethodWithSelector( + String methodStr, Collection on, Collection go) { + this.methodStr = methodStr; this.on = on; this.go = go; } - private String sootMethod; - private Collection on; - private Collection go; + private final String methodStr; + private final Collection on; + private final Collection go; public Collection getOn() { return on; @@ -115,8 +115,8 @@ public Collection getGo() { return go; } - public String getSootMethod() { - return sootMethod; + public String getMethodStr() { + return methodStr; } } @@ -164,7 +164,7 @@ public int hashCode() { } } - public class QuerySelector { + public static class QuerySelector { QuerySelector(QueryDirection direction, Parameter argumentSelection) { this.direction = direction; this.argumentSelection = argumentSelection; @@ -182,7 +182,7 @@ public static Specification create(String... spec) { return new Specification(Sets.newHashSet(spec)); } - public Set getMethodAndQueries() { + public Set getMethodAndQueries() { return methodAndQueries; } } diff --git a/boomerangPDS/src/main/java/boomerang/poi/AbstractPOI.java b/boomerangPDS/src/main/java/boomerang/poi/AbstractPOI.java index 4953acf3..8e8bb258 100644 --- a/boomerangPDS/src/main/java/boomerang/poi/AbstractPOI.java +++ b/boomerangPDS/src/main/java/boomerang/poi/AbstractPOI.java @@ -19,7 +19,7 @@ public abstract class AbstractPOI private final Val baseVar; private final Field field; private final Val storedVar; - private Edge cfgEdge; + private final Edge cfgEdge; public AbstractPOI(Edge cfgEdge, Val baseVar, Field field, Val storedVar) { this.cfgEdge = cfgEdge; @@ -71,9 +71,8 @@ public boolean equals(Object obj) { if (other.storedVar != null) return false; } else if (!storedVar.equals(other.storedVar)) return false; if (cfgEdge == null) { - if (other.cfgEdge != null) return false; - } else if (!cfgEdge.equals(other.cfgEdge)) return false; - return true; + return other.cfgEdge == null; + } else return cfgEdge.equals(other.cfgEdge); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/poi/CopyAccessPathChain.java b/boomerangPDS/src/main/java/boomerang/poi/CopyAccessPathChain.java index ec782763..1de8f3d0 100644 --- a/boomerangPDS/src/main/java/boomerang/poi/CopyAccessPathChain.java +++ b/boomerangPDS/src/main/java/boomerang/poi/CopyAccessPathChain.java @@ -23,11 +23,11 @@ public class CopyAccessPathChain { private static final int MAX_WALK_DEPTH = -1; - private ForwardBoomerangSolver forwardSolver; - private BackwardBoomerangSolver backwardSolver; - private Edge fieldWriteStatement; + private final ForwardBoomerangSolver forwardSolver; + private final BackwardBoomerangSolver backwardSolver; + private final Edge fieldWriteStatement; // TODO: Source of non-determinsim: not part of hashCode/equals....but also shall not be. - private INode> killedTransitionTarget; + private final INode> killedTransitionTarget; public CopyAccessPathChain( ForwardBoomerangSolver forwardSolver, @@ -54,8 +54,8 @@ public void exec() { private class WalkForwardSolverListener extends WPAStateListener>, W> { - private INode> stateInBwSolver; - private int walkDepth; + private final INode> stateInBwSolver; + private final int walkDepth; public WalkForwardSolverListener( INode> target, INode> stateInBwSolver, int walkDepth) { @@ -134,8 +134,8 @@ private CopyAccessPathChain getEnclosingInstance() { // Copied from ExecuteImportFielStmtPOI - private Set>> reachable = Sets.newHashSet(); - private Multimap>, InsertFieldTransitionCallback> delayedTransitions = + private final Set>> reachable = Sets.newHashSet(); + private final Multimap>, InsertFieldTransitionCallback> delayedTransitions = HashMultimap.create(); public void addReachable(INode> node) { @@ -185,9 +185,8 @@ public boolean equals(Object obj) { InsertFieldTransitionCallback other = (InsertFieldTransitionCallback) obj; if (!getEnclosingInstance().equals(other.getEnclosingInstance())) return false; if (trans == null) { - if (other.trans != null) return false; - } else if (!trans.equals(other.trans)) return false; - return true; + return other.trans == null; + } else return trans.equals(other.trans); } private CopyAccessPathChain getEnclosingInstance() { @@ -223,8 +222,7 @@ public boolean equals(Object obj) { if (other.forwardSolver != null) return false; } else if (!forwardSolver.equals(other.forwardSolver)) return false; if (killedTransitionTarget == null) { - if (other.killedTransitionTarget != null) return false; - } else if (!killedTransitionTarget.equals(other.killedTransitionTarget)) return false; - return true; + return other.killedTransitionTarget == null; + } else return killedTransitionTarget.equals(other.killedTransitionTarget); } } diff --git a/boomerangPDS/src/main/java/boomerang/poi/ExecuteImportFieldStmtPOI.java b/boomerangPDS/src/main/java/boomerang/poi/ExecuteImportFieldStmtPOI.java index e821fd31..a2def588 100644 --- a/boomerangPDS/src/main/java/boomerang/poi/ExecuteImportFieldStmtPOI.java +++ b/boomerangPDS/src/main/java/boomerang/poi/ExecuteImportFieldStmtPOI.java @@ -28,8 +28,8 @@ public abstract class ExecuteImportFieldStmtPOI { private static final Logger LOGGER = LoggerFactory.getLogger(ExecuteImportFieldStmtPOI.class); private static final int MAX_IMPORT_DEPTH = -1; - private Set>> reachable = Sets.newHashSet(); - private Multimap>, InsertFieldTransitionCallback> delayedTransitions = + private final Set>> reachable = Sets.newHashSet(); + private final Multimap>, InsertFieldTransitionCallback> delayedTransitions = HashMultimap.create(); protected final ForwardBoomerangSolver baseSolver; protected final ForwardBoomerangSolver flowSolver; @@ -63,9 +63,9 @@ private final class ImportTransitionFromCall extends ControlFlowEdgeBasedCallTransitionListener { private final INode start; - private AbstractBoomerangSolver flowSolver; - private INode target; - private W w; + private final AbstractBoomerangSolver flowSolver; + private final INode target; + private final W w; public ImportTransitionFromCall( AbstractBoomerangSolver flowSolver, @@ -122,14 +122,13 @@ public boolean equals(Object obj) { if (other.target != null) return false; } else if (!target.equals(other.target)) return false; if (w == null) { - if (other.w != null) return false; - } else if (!w.equals(other.w)) return false; - return true; + return other.w == null; + } else return w.equals(other.w); } } private final class ImportOnReachStatement extends ControlFlowEdgeBasedCallTransitionListener { - private AbstractBoomerangSolver flowSolver; + private final AbstractBoomerangSolver flowSolver; private ImportOnReachStatement(AbstractBoomerangSolver flowSolver, Edge callSiteOrExitStmt) { super(callSiteOrExitStmt); @@ -163,14 +162,13 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ImportOnReachStatement other = (ImportOnReachStatement) obj; if (flowSolver == null) { - if (other.flowSolver != null) return false; - } else if (!flowSolver.equals(other.flowSolver)) return false; - return true; + return other.flowSolver == null; + } else return flowSolver.equals(other.flowSolver); } } private class ForAnyCallSiteOrExitStmt implements WPAUpdateListener, W> { - private AbstractBoomerangSolver baseSolver; + private final AbstractBoomerangSolver baseSolver; public ForAnyCallSiteOrExitStmt(AbstractBoomerangSolver baseSolver) { this.baseSolver = baseSolver; @@ -229,9 +227,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ForAnyCallSiteOrExitStmt other = (ForAnyCallSiteOrExitStmt) obj; if (baseSolver == null) { - if (other.baseSolver != null) return false; - } else if (!baseSolver.equals(other.baseSolver)) return false; - return true; + return other.baseSolver == null; + } else return baseSolver.equals(other.baseSolver); } } @@ -244,7 +241,7 @@ public void solve() { private class BaseVarPointsTo extends ControlFlowEdgeBasedFieldTransitionListener { - private ExecuteImportFieldStmtPOI poi; + private final ExecuteImportFieldStmtPOI poi; public BaseVarPointsTo(Edge curr, ExecuteImportFieldStmtPOI executeImportFieldStmtPOI) { super(curr); @@ -278,9 +275,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; BaseVarPointsTo other = (BaseVarPointsTo) obj; if (poi == null) { - if (other.poi != null) return false; - } else if (!poi.equals(other.poi)) return false; - return true; + return other.poi == null; + } else return poi.equals(other.poi); } } @@ -308,7 +304,7 @@ private void handlingAtCallSites() { private final class ImportIndirectCallAliases extends ControlFlowEdgeBasedCallTransitionListener { - private AbstractBoomerangSolver flowSolver; + private final AbstractBoomerangSolver flowSolver; public ImportIndirectCallAliases(Edge stmt, AbstractBoomerangSolver flowSolver) { super(stmt); @@ -338,17 +334,16 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ImportIndirectCallAliases other = (ImportIndirectCallAliases) obj; if (flowSolver == null) { - if (other.flowSolver != null) return false; - } else if (!flowSolver.equals(other.flowSolver)) return false; - return true; + return other.flowSolver == null; + } else return flowSolver.equals(other.flowSolver); } } private final class ImportIndirectCallAliasesAtSucc extends ControlFlowEdgeBasedCallTransitionListener { - private INode target; - private W w; + private final INode target; + private final W w; public ImportIndirectCallAliasesAtSucc(Edge succ, INode target, W w) { super(succ); @@ -385,16 +380,15 @@ public boolean equals(Object obj) { if (other.target != null) return false; } else if (!target.equals(other.target)) return false; if (w == null) { - if (other.w != null) return false; - } else if (!w.equals(other.w)) return false; - return true; + return other.w == null; + } else return w.equals(other.w); } } private final class ImportIndirectAliases extends ControlFlowEdgeBasedFieldTransitionListener { - private AbstractBoomerangSolver flowSolver; - private AbstractBoomerangSolver baseSolver; + private final AbstractBoomerangSolver flowSolver; + private final AbstractBoomerangSolver baseSolver; public ImportIndirectAliases( Edge succ, AbstractBoomerangSolver flowSolver, AbstractBoomerangSolver baseSolver) { @@ -432,18 +426,17 @@ public boolean equals(Object obj) { if (other.baseSolver != null) return false; } else if (!baseSolver.equals(other.baseSolver)) return false; if (flowSolver == null) { - if (other.flowSolver != null) return false; + return other.flowSolver == null; } else return flowSolver.equals(other.flowSolver); - return true; } } private final class CallSiteOrExitStmtFieldImport extends ControlFlowEdgeBasedFieldTransitionListener { - private AbstractBoomerangSolver flowSolver; - private AbstractBoomerangSolver baseSolver; - private Val fact; + private final AbstractBoomerangSolver flowSolver; + private final AbstractBoomerangSolver baseSolver; + private final Val fact; private CallSiteOrExitStmtFieldImport( AbstractBoomerangSolver flowSolver, @@ -489,9 +482,8 @@ public boolean equals(Object obj) { if (other.flowSolver != null) return false; } else if (!flowSolver.equals(other.flowSolver)) return false; if (fact == null) { - if (other.fact != null) return false; - } else if (!fact.equals(other.fact)) return false; - return true; + return other.fact == null; + } else return fact.equals(other.fact); } } @@ -559,8 +551,8 @@ public void trigger(INode> start) { private final class ImportFieldTransitionsFrom extends WPAStateListener>, W> { - private AbstractBoomerangSolver flowSolver; - private int importDepth; + private final AbstractBoomerangSolver flowSolver; + private final int importDepth; public ImportFieldTransitionsFrom( INode> target, AbstractBoomerangSolver flowSolver, int importDepth) { @@ -599,9 +591,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; ImportFieldTransitionsFrom other = (ImportFieldTransitionsFrom) obj; if (flowSolver == null) { - if (other.flowSolver != null) return false; - } else if (!flowSolver.equals(other.flowSolver)) return false; - return true; + return other.flowSolver == null; + } else return flowSolver.equals(other.flowSolver); } } @@ -628,9 +619,8 @@ public boolean equals(Object obj) { if (other.flowSolver != null) return false; } else if (!flowSolver.equals(other.flowSolver)) return false; if (curr == null) { - if (other.curr != null) return false; - } else if (!curr.equals(other.curr)) return false; - return true; + return other.curr == null; + } else return curr.equals(other.curr); } private class InsertFieldTransitionCallback { @@ -660,9 +650,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; InsertFieldTransitionCallback other = (InsertFieldTransitionCallback) obj; if (trans == null) { - if (other.trans != null) return false; - } else if (!trans.equals(other.trans)) return false; - return true; + return other.trans == null; + } else return trans.equals(other.trans); } } } diff --git a/boomerangPDS/src/main/java/boomerang/poi/PointOfIndirection.java b/boomerangPDS/src/main/java/boomerang/poi/PointOfIndirection.java index 1d2a23d1..9485d38f 100644 --- a/boomerangPDS/src/main/java/boomerang/poi/PointOfIndirection.java +++ b/boomerangPDS/src/main/java/boomerang/poi/PointOfIndirection.java @@ -20,8 +20,8 @@ public abstract class PointOfIndirection { - private Set actualBaseAllocations = Sets.newHashSet(); - private Set flowAllocations = Sets.newHashSet(); + private final Set actualBaseAllocations = Sets.newHashSet(); + private final Set flowAllocations = Sets.newHashSet(); public abstract void execute(ForwardQuery baseAllocation, Query flowAllocation); diff --git a/boomerangPDS/src/main/java/boomerang/results/AbstractBoomerangResults.java b/boomerangPDS/src/main/java/boomerang/results/AbstractBoomerangResults.java index fc6e2794..78237d23 100644 --- a/boomerangPDS/src/main/java/boomerang/results/AbstractBoomerangResults.java +++ b/boomerangPDS/src/main/java/boomerang/results/AbstractBoomerangResults.java @@ -69,9 +69,9 @@ public Table asStatementValWeightTable(ForwardQuery query) { private static class OpeningCallStackExtracter extends WPAStateListener, W> { - private AbstractBoomerangSolver solver; - private INode source; - private Context context; + private final AbstractBoomerangSolver solver; + private final INode source; + private final Context context; public OpeningCallStackExtracter( INode state, INode source, Context context, AbstractBoomerangSolver solver) { @@ -135,18 +135,17 @@ public boolean equals(Object obj) { if (other.solver != null) return false; } else if (!solver.equals(other.solver)) return false; if (source == null) { - if (other.source != null) return false; - } else if (!source.equals(other.source)) return false; - return true; + return other.source == null; + } else return source.equals(other.source); } } private static class ClosingCallStackExtracter extends WPAStateListener, W> { - private AbstractBoomerangSolver solver; - private INode source; - private Context context; + private final AbstractBoomerangSolver solver; + private final INode source; + private final Context context; public ClosingCallStackExtracter( INode state, INode source, Context context, AbstractBoomerangSolver solver) { @@ -197,9 +196,8 @@ public boolean equals(Object obj) { if (other.solver != null) return false; } else if (!solver.equals(other.solver)) return false; if (source == null) { - if (other.source != null) return false; - } else if (!source.equals(other.source)) return false; - return true; + return other.source == null; + } else return source.equals(other.source); } } @@ -265,9 +263,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; Context other = (Context) obj; if (node == null) { - if (other.node != null) return false; - } else if (!node.equals(other.node)) return false; - return true; + return other.node == null; + } else return node.equals(other.node); } public PAutomaton> getOpeningContext() { diff --git a/boomerangPDS/src/main/java/boomerang/results/BackwardBoomerangResults.java b/boomerangPDS/src/main/java/boomerang/results/BackwardBoomerangResults.java index a08122fa..a4fe4d22 100644 --- a/boomerangPDS/src/main/java/boomerang/results/BackwardBoomerangResults.java +++ b/boomerangPDS/src/main/java/boomerang/results/BackwardBoomerangResults.java @@ -32,8 +32,8 @@ public class BackwardBoomerangResults extends AbstractBoomeran private Map allocationSites; private final boolean timedout; private final IBoomerangStats stats; - private Stopwatch analysisWatch; - private long maxMemory; + private final Stopwatch analysisWatch; + private final long maxMemory; public BackwardBoomerangResults( BackwardQuery query, @@ -77,7 +77,7 @@ private void computeAllocations() { fw.getValue() .getFieldAutomaton() .registerListener( - new ExtractAllocationSiteStateListener(node, query, (ForwardQuery) fw.getKey()) { + new ExtractAllocationSiteStateListener(node, query, fw.getKey()) { @Override protected void allocationSiteFound( diff --git a/boomerangPDS/src/main/java/boomerang/results/ExtractAllAliasListener.java b/boomerangPDS/src/main/java/boomerang/results/ExtractAllAliasListener.java index 5df4e9bf..a052826c 100644 --- a/boomerangPDS/src/main/java/boomerang/results/ExtractAllAliasListener.java +++ b/boomerangPDS/src/main/java/boomerang/results/ExtractAllAliasListener.java @@ -7,6 +7,7 @@ import boomerang.util.AccessPath; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Empty; import java.util.Collection; import java.util.List; import java.util.Set; @@ -17,14 +18,13 @@ import wpds.impl.Transition; import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; -import wpds.interfaces.Empty; import wpds.interfaces.WPAStateListener; import wpds.interfaces.WPAUpdateListener; public class ExtractAllAliasListener implements SyncPDSUpdateListener { private final Set results; private final Edge stmt; - private AbstractBoomerangSolver fwSolver; + private final AbstractBoomerangSolver fwSolver; public ExtractAllAliasListener( AbstractBoomerangSolver fwSolver, Set results, Edge stmt) { @@ -74,10 +74,10 @@ public void onWeightAdded( class ExtractAccessPathStateListener extends WPAStateListener>, W> { - private INode> allocNode; - private Collection>>> fields; - private Set results; - private Val base; + private final INode> allocNode; + private final Collection>>> fields; + private final Set results; + private final Val base; public ExtractAccessPathStateListener( INode> state, @@ -157,14 +157,13 @@ public boolean equals(Object obj) { if (other.allocNode != null) return false; } else if (!allocNode.equals(other.allocNode)) return false; if (base == null) { - if (other.base != null) return false; - } else if (!base.equals(other.base)) return false; + return other.base == null; + } else return base.equals(other.base); // if (fields == null) { // if (other.fields != null) // return false; // } else if (!fields.equals(other.fields)) // return false; - return true; } private ExtractAllAliasListener getOuterType() { @@ -191,8 +190,7 @@ public boolean equals(Object obj) { if (other.fwSolver != null) return false; } else if (!fwSolver.equals(other.fwSolver)) return false; if (stmt == null) { - if (other.stmt != null) return false; - } else if (!stmt.equals(other.stmt)) return false; - return true; + return other.stmt == null; + } else return stmt.equals(other.stmt); } } diff --git a/boomerangPDS/src/main/java/boomerang/results/ExtractAllocationSiteStateListener.java b/boomerangPDS/src/main/java/boomerang/results/ExtractAllocationSiteStateListener.java index 5984c689..86bc263e 100644 --- a/boomerangPDS/src/main/java/boomerang/results/ExtractAllocationSiteStateListener.java +++ b/boomerangPDS/src/main/java/boomerang/results/ExtractAllocationSiteStateListener.java @@ -16,9 +16,9 @@ public abstract class ExtractAllocationSiteStateListener extends WPAStateListener>, W> { /** */ - private ForwardQuery query; + private final ForwardQuery query; - private BackwardQuery bwQuery; + private final BackwardQuery bwQuery; public ExtractAllocationSiteStateListener( INode> state, BackwardQuery bwQuery, ForwardQuery query) { diff --git a/boomerangPDS/src/main/java/boomerang/results/ForwardBoomerangResults.java b/boomerangPDS/src/main/java/boomerang/results/ForwardBoomerangResults.java index 302b0a02..a6df56e9 100644 --- a/boomerangPDS/src/main/java/boomerang/results/ForwardBoomerangResults.java +++ b/boomerangPDS/src/main/java/boomerang/results/ForwardBoomerangResults.java @@ -6,15 +6,9 @@ import boomerang.callgraph.ObservableICFG; import boomerang.controlflowgraph.ObservableControlFlowGraph; import boomerang.controlflowgraph.PredecessorListener; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DeclaredMethod; -import boomerang.scene.Field; -import boomerang.scene.IfStatement; import boomerang.scene.IfStatement.Evaluation; -import boomerang.scene.Method; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.jimple.JimpleVal; import boomerang.solver.AbstractBoomerangSolver; import boomerang.solver.ForwardBoomerangSolver; import boomerang.stats.IBoomerangStats; @@ -34,7 +28,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import soot.jimple.IntConstant; import sync.pds.solver.nodes.GeneratedState; import sync.pds.solver.nodes.INode; import sync.pds.solver.nodes.Node; @@ -45,19 +38,21 @@ public class ForwardBoomerangResults extends AbstractBoomerangResults { + private final FrameworkScope scopeFactory; private final ForwardQuery query; private final boolean timedout; private final IBoomerangStats stats; - private Stopwatch analysisWatch; - private long maxMemory; - private ObservableICFG icfg; - private Set visitedMethods; + private final Stopwatch analysisWatch; + private final long maxMemory; + private final ObservableICFG icfg; + private final Set visitedMethods; private final boolean trackDataFlowPath; private final boolean pruneContradictoryDataFlowPath; - private ObservableControlFlowGraph cfg; - private boolean pruneImplictFlows; + private final ObservableControlFlowGraph cfg; + private final boolean pruneImplictFlows; public ForwardBoomerangResults( + FrameworkScope scopeFactory, ForwardQuery query, ObservableICFG icfg, ObservableControlFlowGraph cfg, @@ -70,6 +65,7 @@ public ForwardBoomerangResults( boolean pruneContradictoryDataFlowPath, boolean pruneImplictFlows) { super(queryToSolvers); + this.scopeFactory = scopeFactory; this.query = query; this.icfg = icfg; this.cfg = cfg; @@ -338,14 +334,15 @@ private boolean contradiction( if (pruneImplictFlows) { for (Entry e : evaluationMap.entrySet()) { - if (ifStmt1.uses(e.getKey())) { + Val key = e.getKey(); + if (ifStmt1.uses(key)) { Evaluation eval = null; if (e.getValue().equals(ConditionDomain.TRUE)) { // Map first to JimpleVal - eval = ifStmt1.evaluate(new JimpleVal(IntConstant.v(1), e.getKey().m())); + eval = ifStmt1.evaluate(scopeFactory.getTrueValue(key.m())); } else if (e.getValue().equals(ConditionDomain.FALSE)) { // Map first to JimpleVal - eval = ifStmt1.evaluate(new JimpleVal(IntConstant.v(0), e.getKey().m())); + eval = ifStmt1.evaluate(scopeFactory.getFalseValue(key.m())); } if (eval != null) { if (mustBeVal.equals(ConditionDomain.FALSE)) { diff --git a/boomerangPDS/src/main/java/boomerang/results/NullPointerDereference.java b/boomerangPDS/src/main/java/boomerang/results/NullPointerDereference.java index 55c8a601..20ff4ad3 100644 --- a/boomerangPDS/src/main/java/boomerang/results/NullPointerDereference.java +++ b/boomerangPDS/src/main/java/boomerang/results/NullPointerDereference.java @@ -17,12 +17,12 @@ public class NullPointerDereference implements AffectedLocation { private final ControlFlowGraph.Edge statement; private final Val variable; - private PAutomaton> openingContext; - private PAutomaton> closingContext; - private List dataFlowPath; + private final PAutomaton> openingContext; + private final PAutomaton> closingContext; + private final List dataFlowPath; private final ControlFlowGraph.Edge sourceStatement; private final Val sourceVariable; - private Query query; + private final Query query; public NullPointerDereference(ControlFlowGraph.Edge statement) { this(null, statement, null, null, null, null); @@ -213,9 +213,7 @@ public static boolean isNullPointerNode(Node nullPoi } if (curr.getRightOp().isLengthExpr()) { Val lengthOp = curr.getRightOp().getLengthOp(); - if (lengthOp.equals(fact)) { - return true; - } + return lengthOp.equals(fact); } } return false; diff --git a/boomerangPDS/src/main/java/boomerang/results/QueryResults.java b/boomerangPDS/src/main/java/boomerang/results/QueryResults.java index 534215a8..0c7c158d 100644 --- a/boomerangPDS/src/main/java/boomerang/results/QueryResults.java +++ b/boomerangPDS/src/main/java/boomerang/results/QueryResults.java @@ -6,7 +6,7 @@ import java.util.Set; public class QueryResults { - private Query query; + private final Query query; private final Collection visitedMethods; private final Collection affectedLocations; private final boolean timedout; diff --git a/boomerangPDS/src/main/java/boomerang/scene/AnalysisScope.java b/boomerangPDS/src/main/java/boomerang/scene/AnalysisScope.java index d4f16ad3..98d7b215 100644 --- a/boomerangPDS/src/main/java/boomerang/scene/AnalysisScope.java +++ b/boomerangPDS/src/main/java/boomerang/scene/AnalysisScope.java @@ -14,7 +14,7 @@ public abstract class AnalysisScope { private static final Logger LOGGER = LoggerFactory.getLogger(AnalysisScope.class); - private CallGraph cg; + private final CallGraph cg; private boolean scanLibraryClasses = false; public AnalysisScope(CallGraph cg) { @@ -23,7 +23,7 @@ public AnalysisScope(CallGraph cg) { private final Set seeds = Sets.newHashSet(); - private Collection processed = Sets.newHashSet(); + private final Collection processed = Sets.newHashSet(); private int statementCount; public void setScanLibraryClasses(boolean enabled) { diff --git a/boomerangPDS/src/main/java/boomerang/scene/jimple/AccessPathParser.java b/boomerangPDS/src/main/java/boomerang/scene/jimple/AccessPathParser.java index b6d31aba..956c4535 100644 --- a/boomerangPDS/src/main/java/boomerang/scene/jimple/AccessPathParser.java +++ b/boomerangPDS/src/main/java/boomerang/scene/jimple/AccessPathParser.java @@ -1,20 +1,16 @@ package boomerang.scene.jimple; -import boomerang.scene.Field; +import boomerang.scene.Method; import boomerang.util.AccessPath; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import java.util.Collection; import java.util.List; import java.util.Set; -import soot.Local; -import soot.RefType; -import soot.SootField; -import soot.util.Chain; public class AccessPathParser { - public static Collection parseAllFromString(String value, JimpleMethod m) { + public static Collection parseAllFromString(String value, Method m) { Set results = Sets.newHashSet(); for (String v : value.split(";")) { results.add(parseAccessPathFromString(v, m)); @@ -22,7 +18,7 @@ public static Collection parseAllFromString(String value, return results; } - private static AccessPath parseAccessPathFromString(String value, JimpleMethod m) { + private static AccessPath parseAccessPathFromString(String value, Method m) { List fieldNames = Lists.newArrayList(); String baseName; boolean overApproximated = value.endsWith("*"); @@ -35,6 +31,11 @@ private static AccessPath parseAccessPathFromString(String value, JimpleMethod m Lists.newArrayList( value.substring(i + 1, value.length() - (!overApproximated ? 1 : 2)).split(",")); } + + throw new UnsupportedOperationException("not refactored yet"); + } + /* + // TODO: [ms] refactor! List fields = Lists.newArrayList(); Local base = getLocal(m, baseName); soot.Type type = base.getType(); @@ -46,8 +47,7 @@ private static AccessPath parseAccessPathFromString(String value, JimpleMethod m type = fieldByName.getType(); } } - return new AccessPath( - new JimpleVal(base, m), (!overApproximated ? fields : Sets.newHashSet(fields))); + return new AccessPath( new JimpleVal(base, m), (!overApproximated ? fields : Sets.newHashSet(fields))); } private static Local getLocal(JimpleMethod m, String baseName) { @@ -58,4 +58,5 @@ private static Local getLocal(JimpleMethod m, String baseName) { throw new RuntimeException( "Could not find local with name " + baseName + " in method " + m.getDelegate()); } + */ } diff --git a/boomerangPDS/src/main/java/boomerang/solver/AbstractBoomerangSolver.java b/boomerangPDS/src/main/java/boomerang/solver/AbstractBoomerangSolver.java index 00e972f4..894a7519 100644 --- a/boomerangPDS/src/main/java/boomerang/solver/AbstractBoomerangSolver.java +++ b/boomerangPDS/src/main/java/boomerang/solver/AbstractBoomerangSolver.java @@ -70,21 +70,22 @@ public abstract class AbstractBoomerangSolver Entry>, Field>, INode>> generatedFieldState; - private Multimap>>> + private final Multimap>>> perMethodFieldTransitions = HashMultimap.create(); - private Multimap> + private final Multimap> perMethodFieldTransitionsListener = HashMultimap.create(); protected Multimap< ControlFlowGraph.Edge, Transition>>> perStatementFieldTransitions = HashMultimap.create(); - private Multimap> + private final Multimap> perStatementFieldTransitionsListener = HashMultimap.create(); - private HashBasedTable>, W> + private final HashBasedTable< + ControlFlowGraph.Edge, Transition>, W> perStatementCallTransitions = HashBasedTable.create(); - private Multimap> + private final Multimap> perStatementCallTransitionsListener = HashMultimap.create(); - private Multimap> unbalancedDataFlows = HashMultimap.create(); - private Multimap unbalancedDataFlowListeners = + private final Multimap> unbalancedDataFlows = HashMultimap.create(); + private final Multimap unbalancedDataFlowListeners = HashMultimap.create(); protected final DataFlowScope dataFlowScope; protected final BoomerangOptions options; @@ -100,7 +101,7 @@ public AbstractBoomerangSolver( DataFlowScope scope, Type propagationType) { super( - icfg instanceof BackwardsObservableICFG ? false : options.callSummaries(), + !(icfg instanceof BackwardsObservableICFG) && options.callSummaries(), callSummaries, options.fieldSummaries(), fieldSummaries, @@ -169,8 +170,8 @@ public void synchedEmptyStackReachable( synchedReachable( sourceNode, new WitnessListener() { - Multimap> potentialFieldCandidate = HashMultimap.create(); - Set potentialCallCandidate = Sets.newHashSet(); + final Multimap> potentialFieldCandidate = HashMultimap.create(); + final Set potentialCallCandidate = Sets.newHashSet(); @Override public void fieldWitness(Transition>> t) { @@ -520,11 +521,11 @@ protected boolean preventFieldTransitionAdd( return false; } if (!(targetVal.isRefType()) || !(sourceVal.isRefType())) { - if (options.killNullAtCast() && targetVal.isNullType() && isCastNode(t.getStart().fact())) { - // A null pointer cannot be cast to any object - return true; - } - return false; // !allocVal.value().getType().equals(varVal.value().getType()); + // A null pointer cannot be cast to any object + return options.killNullAtCast() + && targetVal.isNullType() + && isCastNode( + t.getStart().fact()); // !allocVal.value().getType().equals(varVal.value().getType()); } return sourceVal.doesCastFail(targetVal, target); } @@ -534,9 +535,7 @@ private boolean isCastNode(Node node) { if (isCast) { Val rightOp = node.stmt().getStart().getRightOp(); if (rightOp.isCast()) { - if (rightOp.getCastOp().equals(node.fact())) { - return true; - } + return rightOp.getCastOp().equals(node.fact()); } } return false; @@ -621,7 +620,7 @@ public void unregisterAllListeners() { private static class UnbalancedDataFlow { private final Method callee; - private Transition> trans; + private final Transition> trans; public UnbalancedDataFlow(Method callee, Transition> trans) { this.callee = callee; @@ -651,15 +650,14 @@ public boolean equals(Object obj) { if (other.callee != null) return false; } else if (!callee.equals(other.callee)) return false; if (trans == null) { - if (other.trans != null) return false; - } else if (!trans.equals(other.trans)) return false; - return true; + return other.trans == null; + } else return trans.equals(other.trans); } } private static class UnbalancedDataFlowListener { - private Method callee; - private Statement callSite; + private final Method callee; + private final Statement callSite; public UnbalancedDataFlowListener(Method callee, Statement callSite) { this.callee = callee; @@ -689,9 +687,8 @@ public boolean equals(Object obj) { if (other.callee != null) return false; } else if (!callee.equals(other.callee)) return false; if (callSite == null) { - if (other.callSite != null) return false; - } else if (!callSite.equals(other.callSite)) return false; - return true; + return other.callSite == null; + } else return callSite.equals(other.callSite); } } } diff --git a/boomerangPDS/src/main/java/boomerang/solver/BackwardBoomerangSolver.java b/boomerangPDS/src/main/java/boomerang/solver/BackwardBoomerangSolver.java index 768bc182..7101e7b8 100644 --- a/boomerangPDS/src/main/java/boomerang/solver/BackwardBoomerangSolver.java +++ b/boomerangPDS/src/main/java/boomerang/solver/BackwardBoomerangSolver.java @@ -19,22 +19,11 @@ import boomerang.controlflowgraph.PredecessorListener; import boomerang.controlflowgraph.SuccessorListener; import boomerang.flowfunction.IBackwardFlowFunction; -import boomerang.scene.AllocVal; -import boomerang.scene.ControlFlowGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Field; -import boomerang.scene.InvokeExpr; -import boomerang.scene.Method; -import boomerang.scene.Statement; -import boomerang.scene.Type; -import boomerang.scene.Val; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGCache; -import boomerang.scene.sparse.eval.PropagationCounter; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.Map; @@ -43,18 +32,12 @@ import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import soot.Unit; -import soot.jimple.Stmt; -import sync.pds.solver.nodes.GeneratedState; -import sync.pds.solver.nodes.INode; -import sync.pds.solver.nodes.Node; -import sync.pds.solver.nodes.PopNode; -import sync.pds.solver.nodes.PushNode; -import sync.pds.solver.nodes.SingleNode; +import sparse.SparseAliasingCFG; +import sparse.SparseCFGCache; +import sync.pds.solver.nodes.*; import wpds.impl.NestedWeightedPAutomatons; import wpds.impl.Transition; import wpds.impl.Weight; -import wpds.interfaces.Location; import wpds.interfaces.State; public abstract class BackwardBoomerangSolver extends AbstractBoomerangSolver { @@ -85,12 +68,10 @@ public BackwardBoomerangSolver( } private boolean notUsedInMethod(Method m, Statement curr, Val value) { - if (value.isStatic()) return false; - if (!m.getLocals().stream() - .filter(e -> e.toString().equals(value.toString())) - .findAny() - .isPresent()) return true; - return false; + if (value.isStatic()) { + return false; + } + return m.getLocals().stream().noneMatch(local -> local.toString().equals(value.toString())); } public INode> generateFieldState( @@ -186,59 +167,57 @@ private boolean checkSpecialInvoke(Edge edge) { protected void normalFlow(Method method, Node currNode) { Edge curr = currNode.stmt(); Val value = currNode.fact(); - if (options.getSparsificationStrategy() != SparseCFGCache.SparsificationStrategy.NONE) { - propagateSparse(method, currNode, curr, value); - } else { + + /* TODO: [ms] re-enable sparse + refactor if/else into own method! + if (options.getSparsificationStrategy() != SparsificationStrategy.NONE) { + propagateSparse(method, currNode, curr, value); + } else */ + { for (Statement pred : curr.getStart().getMethod().getControlFlowGraph().getPredsOf(curr.getStart())) { Collection flow = computeNormalFlow(method, new Edge(pred, curr.getStart()), value); for (State s : flow) { - PropagationCounter.getInstance(options.getSparsificationStrategy()).countBackward(); + options.getSparsificationStrategy().getCounter().countBackwardProgragation(); propagate(currNode, s); } } } } - private void propagateSparse(Method method, Node currNode, Edge curr, Val value) { - Statement propStmt = curr.getStart(); - SparseAliasingCFG sparseCFG = getSparseCFG(query, method, value, propStmt); - Stmt stmt = SootAdapter.asStmt(propStmt); - if (sparseCFG.getGraph().nodes().contains(stmt)) { - Set predecessors = sparseCFG.getGraph().predecessors(stmt); - for (Unit pred : predecessors) { - Collection flow = - computeNormalFlow( - method, new Edge(SootAdapter.asStatement(pred, method), propStmt), value); - for (State s : flow) { - PropagationCounter.getInstance(options.getSparsificationStrategy()).countBackward(); - propagate(currNode, s); + /* + // TODO: [ms] re-enable sparse + private void propagateSparse(Method method, Node currNode, Edge curr, Val value) { + Statement propStmt = curr.getStart(); + SparseAliasingCFG sparseCFG = getSparseCFG(query, method, value, propStmt); + Stmt stmt = SootAdapter.asStmt(propStmt); + if (sparseCFG.getGraph().nodes().contains(stmt)) { + Set predecessors = sparseCFG.getGraph().predecessors(stmt); + for (Unit pred : predecessors) { + Collection flow = + computeNormalFlow( + method, new Edge(SootAdapter.asStatement(pred, method), propStmt), value); + for (State s : flow) { + options.getSparsificationStrategy().getCounter().countBackward(); + propagate(currNode, s); + } } + } else { + System.out.println("node not in cfg:" + stmt); } - } else { - System.out.println("node not in cfg:" + stmt); } - } + */ /** - * BackwardQuery: (b2 (target.aliasing.Aliasing1.),b2.secret = $stack9 -> return) - * - * @param method - * @param val - * @param stmt - * @return */ private SparseAliasingCFG getSparseCFG( BackwardQuery query, Method method, Val val, Statement stmt) { - SparseAliasingCFG sparseCFG; SparseCFGCache sparseCFGCache = SparseCFGCache.getInstance( options.getSparsificationStrategy(), options.ignoreSparsificationAfterQuery()); - sparseCFG = - sparseCFGCache.getSparseCFGForBackwardPropagation( - query.var(), query.asNode().stmt().getStart(), method, val, stmt); - return sparseCFG; + return sparseCFGCache.getSparseCFGForBackwardPropagation( + query.var(), query.asNode().stmt().getStart(), method, val, stmt); } protected Collection computeCallFlow( @@ -401,9 +380,8 @@ public boolean equals(Object obj) { if (other.caller != null) return false; } else if (!caller.equals(other.caller)) return false; if (curr == null) { - if (other.curr != null) return false; - } else if (!curr.equals(other.curr)) return false; - return true; + return other.curr == null; + } else return curr.equals(other.curr); } private BackwardBoomerangSolver getOuterType() { diff --git a/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedCallTransitionListener.java b/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedCallTransitionListener.java index f94e4e75..3a3e52e1 100644 --- a/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedCallTransitionListener.java +++ b/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedCallTransitionListener.java @@ -59,8 +59,7 @@ public boolean equals(Object obj) { ControlFlowEdgeBasedCallTransitionListener other = (ControlFlowEdgeBasedCallTransitionListener) obj; if (edge == null) { - if (other.edge != null) return false; - } else if (!edge.equals(other.edge)) return false; - return true; + return other.edge == null; + } else return edge.equals(other.edge); } } diff --git a/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedFieldTransitionListener.java b/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedFieldTransitionListener.java index 5269a967..5f9355e5 100644 --- a/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedFieldTransitionListener.java +++ b/boomerangPDS/src/main/java/boomerang/solver/ControlFlowEdgeBasedFieldTransitionListener.java @@ -61,8 +61,7 @@ public boolean equals(Object obj) { ControlFlowEdgeBasedFieldTransitionListener other = (ControlFlowEdgeBasedFieldTransitionListener) obj; if (cfgEdge == null) { - if (other.cfgEdge != null) return false; - } else if (!cfgEdge.equals(other.cfgEdge)) return false; - return true; + return other.cfgEdge == null; + } else return cfgEdge.equals(other.cfgEdge); } } diff --git a/boomerangPDS/src/main/java/boomerang/solver/ForwardBoomerangSolver.java b/boomerangPDS/src/main/java/boomerang/solver/ForwardBoomerangSolver.java index b3f73619..2db55b4c 100644 --- a/boomerangPDS/src/main/java/boomerang/solver/ForwardBoomerangSolver.java +++ b/boomerangPDS/src/main/java/boomerang/solver/ForwardBoomerangSolver.java @@ -30,6 +30,7 @@ import boomerang.scene.Val; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.Collections; import java.util.Map; @@ -47,7 +48,6 @@ import wpds.impl.Transition; import wpds.impl.Weight; import wpds.impl.WeightedPAutomaton; -import wpds.interfaces.Location; import wpds.interfaces.State; import wpds.interfaces.WPAStateListener; @@ -131,9 +131,8 @@ public boolean equals(Object obj) { OverwriteAtFieldStore other = (OverwriteAtFieldStore) obj; if (!getEnclosingInstance().equals(other.getEnclosingInstance())) return false; if (nextStmt == null) { - if (other.nextStmt != null) return false; - } else if (!nextStmt.equals(other.nextStmt)) return false; - return true; + return other.nextStmt == null; + } else return nextStmt.equals(other.nextStmt); } private ForwardBoomerangSolver getEnclosingInstance() { @@ -184,9 +183,8 @@ public boolean equals(Object obj) { OverwriteAtArrayStore other = (OverwriteAtArrayStore) obj; if (!getEnclosingInstance().equals(other.getEnclosingInstance())) return false; if (nextStmt == null) { - if (other.nextStmt != null) return false; - } else if (!nextStmt.equals(other.nextStmt)) return false; - return true; + return other.nextStmt == null; + } else return nextStmt.equals(other.nextStmt); } private ForwardBoomerangSolver getEnclosingInstance() { @@ -284,9 +282,8 @@ public boolean equals(Object obj) { if (other.caller != null) return false; } else if (!caller.equals(other.caller)) return false; if (currNode == null) { - if (other.currNode != null) return false; - } else if (!currNode.equals(other.currNode)) return false; - return true; + return other.currNode == null; + } else return currNode.equals(other.currNode); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/staticfields/SingletonStaticFieldStrategy.java b/boomerangPDS/src/main/java/boomerang/staticfields/SingletonStaticFieldStrategy.java index f7f52332..dfae2015 100644 --- a/boomerangPDS/src/main/java/boomerang/staticfields/SingletonStaticFieldStrategy.java +++ b/boomerangPDS/src/main/java/boomerang/staticfields/SingletonStaticFieldStrategy.java @@ -14,9 +14,9 @@ public class SingletonStaticFieldStrategy implements StaticFieldStrategy { - private Multimap fieldStoreStatements; - private Multimap fieldLoadStatements; - private AbstractBoomerangSolver solver; + private final Multimap fieldStoreStatements; + private final Multimap fieldLoadStatements; + private final AbstractBoomerangSolver solver; public SingletonStaticFieldStrategy( AbstractBoomerangSolver solver, diff --git a/boomerangPDS/src/main/java/boomerang/stats/AdvancedBoomerangStats.java b/boomerangPDS/src/main/java/boomerang/stats/AdvancedBoomerangStats.java index fcc88a4b..dffc9e81 100644 --- a/boomerangPDS/src/main/java/boomerang/stats/AdvancedBoomerangStats.java +++ b/boomerangPDS/src/main/java/boomerang/stats/AdvancedBoomerangStats.java @@ -27,6 +27,7 @@ import boomerang.solver.ForwardBoomerangSolver; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.Comparator; import java.util.Map; @@ -37,36 +38,36 @@ import wpds.impl.Rule; import wpds.impl.Transition; import wpds.impl.Weight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class AdvancedBoomerangStats implements IBoomerangStats { - private Map> queries = Maps.newHashMap(); - private Set>, W>> globalFieldTransitions = + private final Map> queries = Maps.newHashMap(); + private final Set>, W>> globalFieldTransitions = Sets.newHashSet(); private int fieldTransitionCollisions; - private Set, W>> globalCallTransitions = Sets.newHashSet(); + private final Set, W>> globalCallTransitions = + Sets.newHashSet(); private int callTransitionCollisions; - private Set>, W>> globalFieldRules = Sets.newHashSet(); + private final Set>, W>> globalFieldRules = Sets.newHashSet(); private int fieldRulesCollisions; - private Set, W>> globalCallRules = Sets.newHashSet(); + private final Set, W>> globalCallRules = Sets.newHashSet(); private int callRulesCollisions; - private Set> reachedForwardNodes = Sets.newHashSet(); + private final Set> reachedForwardNodes = Sets.newHashSet(); private int reachedForwardNodeCollisions; - private Set> reachedBackwardNodes = Sets.newHashSet(); + private final Set> reachedBackwardNodes = Sets.newHashSet(); private int reachedBackwardNodeCollisions; - private Set callVisitedMethods = Sets.newHashSet(); - private Set fieldVisitedMethods = Sets.newHashSet(); + private final Set callVisitedMethods = Sets.newHashSet(); + private final Set fieldVisitedMethods = Sets.newHashSet(); private int arrayFlows; private int staticFlows; - private boolean COUNT_TOP_METHODS = false; - private Map backwardFieldMethodsRules = new TreeMap<>(); - private Map backwardCallMethodsRules = new TreeMap<>(); + private final boolean COUNT_TOP_METHODS = false; + private final Map backwardFieldMethodsRules = new TreeMap<>(); + private final Map backwardCallMethodsRules = new TreeMap<>(); - private Map forwardFieldMethodsRules = new TreeMap<>(); - private Map forwardCallMethodsRules = new TreeMap<>(); + private final Map forwardFieldMethodsRules = new TreeMap<>(); + private final Map forwardCallMethodsRules = new TreeMap<>(); public static Map sortByValues(final Map map) { Comparator valueComparator = @@ -159,7 +160,7 @@ public void registerSolver(Query key, final AbstractBoomerangSolver solver) { private void increaseMethod(String method, Map map) { Integer i = map.get(method); if (i == null) { - i = new Integer(0); + i = Integer.valueOf(0); } map.put(method, ++i); } @@ -179,7 +180,7 @@ public String toString() { s += String.format( "Queries (Forward/Backward/Total): \t\t %s/%s/%s\n", - forwardQuery, backwardQuery, queries.keySet().size()); + forwardQuery, backwardQuery, queries.size()); s += String.format( "Visited Methods (Field/Call): \t\t %s/%s\n", @@ -258,7 +259,7 @@ private String computeMetrics() { } max = Math.max(size, max); } - float average = ((float) totalReached) / queries.keySet().size(); + float average = ((float) totalReached) / queries.size(); String s = String.format("Reachable nodes (Min/Avg/Max): \t\t%s/%s/%s\n", min, average, max); s += String.format("Maximal Query: \t\t%s\n", maxQuery); return s; @@ -292,9 +293,8 @@ public boolean equals(Object obj) { if (other.t != null) return false; } else if (!t.equals(other.t)) return false; if (w == null) { - if (other.w != null) return false; - } else if (!w.equals(other.w)) return false; - return true; + return other.w == null; + } else return w.equals(other.w); } } diff --git a/boomerangPDS/src/main/java/boomerang/stats/CSVBoomerangStatsWriter.java b/boomerangPDS/src/main/java/boomerang/stats/CSVBoomerangStatsWriter.java index a1bb0186..930c315e 100644 --- a/boomerangPDS/src/main/java/boomerang/stats/CSVBoomerangStatsWriter.java +++ b/boomerangPDS/src/main/java/boomerang/stats/CSVBoomerangStatsWriter.java @@ -29,6 +29,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -46,42 +47,42 @@ import wpds.impl.Rule; import wpds.impl.Transition; import wpds.impl.Weight; -import wpds.interfaces.Location; import wpds.interfaces.State; public class CSVBoomerangStatsWriter implements IBoomerangStats { - private Map> queries = Maps.newHashMap(); - private Set>, W>> globalFieldTransitions = + private final Map> queries = Maps.newHashMap(); + private final Set>, W>> globalFieldTransitions = Sets.newHashSet(); private int fieldTransitionCollisions; - private Set, W>> globalCallTransitions = Sets.newHashSet(); + private final Set, W>> globalCallTransitions = + Sets.newHashSet(); private int callTransitionCollisions; - private Set>, W>> globalFieldRules = Sets.newHashSet(); + private final Set>, W>> globalFieldRules = Sets.newHashSet(); private int fieldRulesCollisions; - private Set, W>> globalCallRules = Sets.newHashSet(); + private final Set, W>> globalCallRules = Sets.newHashSet(); private int callRulesCollisions; - private Set> reachedForwardNodes = Sets.newHashSet(); + private final Set> reachedForwardNodes = Sets.newHashSet(); private int reachedForwardNodeCollisions; - private Set> reachedBackwardNodes = Sets.newHashSet(); + private final Set> reachedBackwardNodes = Sets.newHashSet(); private int reachedBackwardNodeCollisions; - private Set callVisitedMethods = Sets.newHashSet(); - private Set fieldVisitedMethods = Sets.newHashSet(); - private Set callVisitedStmts = Sets.newHashSet(); - private Set fieldVisitedStmts = Sets.newHashSet(); - private Set>> fieldGeneratedStates = Sets.newHashSet(); - private Set> callGeneratedStates = Sets.newHashSet(); + private final Set callVisitedMethods = Sets.newHashSet(); + private final Set fieldVisitedMethods = Sets.newHashSet(); + private final Set callVisitedStmts = Sets.newHashSet(); + private final Set fieldVisitedStmts = Sets.newHashSet(); + private final Set>> fieldGeneratedStates = Sets.newHashSet(); + private final Set> callGeneratedStates = Sets.newHashSet(); private int arrayFlows; private int staticFlows; private int fieldWritePOIs; private int fieldReadPOIs; - private String outputFileName; + private final String outputFileName; private static final String CSV_SEPARATOR = ";"; - private List headers = Lists.newArrayList(); - private Map headersToValues = Maps.newHashMap(); - private long memoryBefore; + private final List headers = Lists.newArrayList(); + private final Map headersToValues = Maps.newHashMap(); + private final long memoryBefore; private enum Headers { Query, @@ -235,7 +236,7 @@ public String toString() { s += String.format( "Queries (Forward/Backward/Total): \t\t %s/%s/%s\n", - forwardQuery, backwardQuery, queries.keySet().size()); + forwardQuery, backwardQuery, queries.size()); s += String.format( "Visited Methods (Field/Call): \t\t %s/%s\n", @@ -292,7 +293,7 @@ private String computeMetrics() { } max = Math.max(size, max); } - float average = ((float) totalReached) / queries.keySet().size(); + float average = ((float) totalReached) / queries.size(); String s = String.format("Reachable nodes (Min/Avg/Max): \t\t%s/%s/%s\n", min, average, max); s += String.format("Maximal Query: \t\t%s\n", maxQuery); return s; @@ -326,9 +327,8 @@ public boolean equals(Object obj) { if (other.t != null) return false; } else if (!t.equals(other.t)) return false; if (w == null) { - if (other.w != null) return false; - } else if (!w.equals(other.w)) return false; - return true; + return other.w == null; + } else return w.equals(other.w); } } diff --git a/boomerangPDS/src/main/java/boomerang/stats/SimpleBoomerangStats.java b/boomerangPDS/src/main/java/boomerang/stats/SimpleBoomerangStats.java index 39b49767..85a86d92 100644 --- a/boomerangPDS/src/main/java/boomerang/stats/SimpleBoomerangStats.java +++ b/boomerangPDS/src/main/java/boomerang/stats/SimpleBoomerangStats.java @@ -36,9 +36,9 @@ /** Created by johannesspath on 06.12.17. */ public class SimpleBoomerangStats implements IBoomerangStats { - private Map> queries = Maps.newHashMap(); - private Set callVisitedMethods = Sets.newHashSet(); - private Set fieldVisitedMethods = Sets.newHashSet(); + private final Map> queries = Maps.newHashMap(); + private final Set callVisitedMethods = Sets.newHashSet(); + private final Set fieldVisitedMethods = Sets.newHashSet(); @Override public void registerSolver(Query key, final AbstractBoomerangSolver solver) { @@ -80,7 +80,7 @@ public String toString() { s += String.format( "Queries (Forward/Backward/Total): \t\t %s/%s/%s\n", - forwardQuery, backwardQuery, queries.keySet().size()); + forwardQuery, backwardQuery, queries.size()); s += String.format( "Visited Methods (Field/Call): \t\t %s/%s/(%s/%s)\n", diff --git a/boomerangPDS/src/main/java/boomerang/util/AccessPath.java b/boomerangPDS/src/main/java/boomerang/util/AccessPath.java index 570ac1b9..de442e35 100644 --- a/boomerangPDS/src/main/java/boomerang/util/AccessPath.java +++ b/boomerangPDS/src/main/java/boomerang/util/AccessPath.java @@ -29,7 +29,6 @@ public AccessPath(Val value, Collection fields) { @Override public String toString() { return val.toString() - + "" + (fieldChain.isEmpty() ? "" : fieldChain.toString()) + (isOverApproximated() ? "*" : ""); } @@ -88,12 +87,7 @@ public boolean equals(Object obj) { return false; } if (val == null) { - if (other.val != null) { - return false; - } - } else if (!val.equals(other.val)) { - return false; - } - return true; + return other.val == null; + } else return val.equals(other.val); } } diff --git a/boomerangPDS/src/main/java/boomerang/util/DefaultValueMap.java b/boomerangPDS/src/main/java/boomerang/util/DefaultValueMap.java index 5915c8ac..6dbe2424 100644 --- a/boomerangPDS/src/main/java/boomerang/util/DefaultValueMap.java +++ b/boomerangPDS/src/main/java/boomerang/util/DefaultValueMap.java @@ -18,7 +18,7 @@ public abstract class DefaultValueMap implements Map { - private HashMap map; + private final HashMap map; public DefaultValueMap() { map = new HashMap(); @@ -48,8 +48,8 @@ public boolean containsValue(Object value) { public V getOrCreate(K key) { if (!map.containsKey(key)) { - V value = createItem((K) key); - map.put((K) key, value); + V value = createItem(key); + map.put(key, value); return value; } diff --git a/boomerangPDS/src/main/java/boomerang/util/RegExAccessPath.java b/boomerangPDS/src/main/java/boomerang/util/RegExAccessPath.java index 1f54c689..fdc15d51 100644 --- a/boomerangPDS/src/main/java/boomerang/util/RegExAccessPath.java +++ b/boomerangPDS/src/main/java/boomerang/util/RegExAccessPath.java @@ -45,8 +45,7 @@ public boolean equals(Object obj) { if (other.fields != null) return false; } else if (!fields.equals(other.fields)) return false; if (val == null) { - if (other.val != null) return false; - } else if (!val.equals(other.val)) return false; - return true; + return other.val == null; + } else return val.equals(other.val); } } diff --git a/boomerangPDS/src/main/java/boomerang/weights/DataFlowPathWeight.java b/boomerangPDS/src/main/java/boomerang/weights/DataFlowPathWeight.java index c7d49a56..4ad53146 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/DataFlowPathWeight.java +++ b/boomerangPDS/src/main/java/boomerang/weights/DataFlowPathWeight.java @@ -15,8 +15,8 @@ public class DataFlowPathWeight extends Weight { private static DataFlowPathWeight one; - private PathTrackingWeight path; - private PathConditionWeight condition; + private final PathTrackingWeight path; + private final PathConditionWeight condition; private DataFlowPathWeight() { path = PathTrackingWeight.one(); diff --git a/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeight.java b/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeight.java index c709fced..ae0c06df 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeight.java +++ b/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeight.java @@ -63,9 +63,8 @@ public boolean equals(Object obj) { if (other.minDistance != null) return false; } else if (!minDistance.equals(other.minDistance)) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeightFunctions.java b/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeightFunctions.java index e73bfc54..8645112c 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeightFunctions.java +++ b/boomerangPDS/src/main/java/boomerang/weights/MinDistanceWeightFunctions.java @@ -12,7 +12,7 @@ public class MinDistanceWeightFunctions public MinDistanceWeight push( Node curr, Node succ, Statement callSite) { if (!curr.fact().isStatic()) { - return new MinDistanceWeight(new Integer(1)); + return new MinDistanceWeight(Integer.valueOf(1)); } return MinDistanceWeight.one(); } @@ -20,10 +20,10 @@ public MinDistanceWeight push( @Override public MinDistanceWeight normal(Node curr, Node succ) { if (!curr.fact().equals(succ.fact())) { - return new MinDistanceWeight(new Integer(1)); + return new MinDistanceWeight(Integer.valueOf(1)); } if (succ.stmt().containsInvokeExpr() && succ.stmt().uses(curr.fact())) { - return new MinDistanceWeight(new Integer(1)); + return new MinDistanceWeight(Integer.valueOf(1)); } return MinDistanceWeight.one(); } diff --git a/boomerangPDS/src/main/java/boomerang/weights/PathConditionWeight.java b/boomerangPDS/src/main/java/boomerang/weights/PathConditionWeight.java index 3f37b61e..bde8cc83 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/PathConditionWeight.java +++ b/boomerangPDS/src/main/java/boomerang/weights/PathConditionWeight.java @@ -213,13 +213,8 @@ public boolean equals(Object obj) { return false; } if (rep == null) { - if (other.rep != null) { - return false; - } - } else if (!rep.equals(other.rep)) { - return false; - } - return true; + return other.rep == null; + } else return rep.equals(other.rep); } public Map getConditions() { diff --git a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingBoomerang.java b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingBoomerang.java index 1d680379..7597bb21 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingBoomerang.java +++ b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingBoomerang.java @@ -14,11 +14,8 @@ import boomerang.BoomerangOptions; import boomerang.ForwardQuery; import boomerang.WeightedBoomerang; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Field; -import boomerang.scene.Val; import sync.pds.solver.OneWeightFunctions; import sync.pds.solver.WeightFunctions; @@ -27,12 +24,13 @@ public abstract class PathTrackingBoomerang extends WeightedBoomerang fieldWeights; private PathTrackingWeightFunctions callWeights; - public PathTrackingBoomerang(CallGraph cg, DataFlowScope scope) { - super(cg, scope); + public PathTrackingBoomerang(CallGraph cg, DataFlowScope scope, FrameworkScope frameworkScope) { + super(cg, scope, frameworkScope); } - public PathTrackingBoomerang(CallGraph cg, DataFlowScope scope, BoomerangOptions opt) { - super(cg, scope, opt); + public PathTrackingBoomerang( + CallGraph cg, DataFlowScope scope, BoomerangOptions opt, FrameworkScope frameworkScope) { + super(cg, scope, opt, frameworkScope); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeight.java b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeight.java index 844cc38e..0aca957c 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeight.java +++ b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeight.java @@ -134,9 +134,8 @@ public boolean equals(Object obj) { if (other.allPathWitness != null) return false; } else if (!allPathWitness.equals(other.allPathWitness)) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } @Override diff --git a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeightFunctions.java b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeightFunctions.java index 41e94297..82be394f 100644 --- a/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeightFunctions.java +++ b/boomerangPDS/src/main/java/boomerang/weights/PathTrackingWeightFunctions.java @@ -9,9 +9,9 @@ public class PathTrackingWeightFunctions implements WeightFunctions { - private boolean trackDataFlowPath; - private boolean trackPathConditions; - private boolean implicitBooleanCondition; + private final boolean trackDataFlowPath; + private final boolean trackPathConditions; + private final boolean implicitBooleanCondition; public PathTrackingWeightFunctions( boolean trackDataFlowPath, boolean trackPathConditions, boolean implicitBooleanCondition) { diff --git a/boomerangPDS/src/test/java/boomerang/guided/CustomFlowFunctionTest.java b/boomerangPDS/src/test/java/boomerang/guided/CustomFlowFunctionTest.java index e9593c81..c189f388 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/CustomFlowFunctionTest.java +++ b/boomerangPDS/src/test/java/boomerang/guided/CustomFlowFunctionTest.java @@ -11,77 +11,73 @@ import boomerang.guided.targets.CustomFlowFunctionTarget; import boomerang.results.BackwardBoomerangResults; import boomerang.results.ForwardBoomerangResults; -import boomerang.scene.AllocVal; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.Method; -import boomerang.scene.SootDataFlowScope; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; import boomerang.scene.jimple.IntAndStringBoomerangOptions; -import boomerang.scene.jimple.JimpleMethod; -import boomerang.scene.jimple.SootCallGraph; import boomerang.solver.BackwardBoomerangSolver; -import com.google.common.collect.Lists; import com.google.common.collect.Table; -import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; import org.junit.Assert; import org.junit.Test; -import soot.G; -import soot.PackManager; -import soot.Scene; -import soot.SootClass; -import soot.SootMethod; -import soot.options.Options; +import test.FrameworkScopeFactory; import wpds.impl.Weight.NoWeight; public class CustomFlowFunctionTest { public static String CG = "cha"; + private final String classPathStr = Paths.get("target/test-classes").toAbsolutePath().toString(); @Test public void killOnSystemExitBackwardTestInteger() { - setupSoot(CustomFlowFunctionTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, CustomFlowFunctionTarget.class.getName()); + String s = + ""; + Method m = scopeFactory.getMethod(s); BackwardQuery query = selectQueryForStatement(m); - SootCallGraph sootCallGraph = new SootCallGraph(); + CallGraph CallGraph = scopeFactory.getCallGraph(); Boomerang solver = new Boomerang( - sootCallGraph, - SootDataFlowScope.make(Scene.v()), - new CustomIntAndStringBoomerangOptions()); + scopeFactory.getCallGraph(), + scopeFactory.getDataFlowScope(), + new CustomIntAndStringBoomerangOptions(), + scopeFactory); System.out.println("Solving query: " + query); BackwardBoomerangResults backwardQueryResults = solver.solve(query); for (BackwardBoomerangSolver bw : solver.getBackwardSolvers().values()) { - Assert.assertEquals(true, bw.getCallAutomaton().getTransitions().size() < 3); + Assert.assertTrue(bw.getCallAutomaton().getTransitions().size() < 3); } System.out.println(backwardQueryResults.getAllocationSites()); // For the query no allocation site is found, as between queryFor and the allocation site there // exists a System.exit call. - Assert.assertEquals(true, backwardQueryResults.isEmpty()); + Assert.assertTrue(backwardQueryResults.isEmpty()); } + /* + soot uses 1829 classes here: + methodname: + methodname: exit + methodname: queryFor + Solving query: BackwardQuery: (z (boomerang.guided.targets.CustomFlowFunctionTarget.),exit(y) -> queryFor(z)) + {} + * */ @Test public void killOnSystemExitBackwardTest() { - setupSoot(CustomFlowFunctionTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, CustomFlowFunctionTarget.class.getName()); + String s = ""; + Method m = scopeFactory.getMethod(s); BackwardQuery query = selectQueryForStatement(m); - SootCallGraph sootCallGraph = new SootCallGraph(); Boomerang solver = new Boomerang( - sootCallGraph, SootDataFlowScope.make(Scene.v()), new CustomBoomerangOptions()); + scopeFactory.getCallGraph(), + scopeFactory.getDataFlowScope(), + new CustomBoomerangOptions(), + scopeFactory); System.out.println("Solving query: " + query); BackwardBoomerangResults backwardQueryResults = solver.solve(query); @@ -89,22 +85,23 @@ public void killOnSystemExitBackwardTest() { // For the query no allocation site is found, as between queryFor and the allocation site there // exists a System.exit call. - Assert.assertEquals(true, backwardQueryResults.isEmpty()); + Assert.assertTrue(backwardQueryResults.isEmpty()); } @Test public void killOnSystemExitForwardTest() { - setupSoot(CustomFlowFunctionTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, CustomFlowFunctionTarget.class.getName()); + String s = ""; + Method m = scopeFactory.getMethod(s); ForwardQuery query = selectFirstIntAssignment(m); - SootCallGraph sootCallGraph = new SootCallGraph(); Boomerang solver = new Boomerang( - sootCallGraph, SootDataFlowScope.make(Scene.v()), new CustomBoomerangOptions()); + scopeFactory.getCallGraph(), + scopeFactory.getDataFlowScope(), + new CustomBoomerangOptions(), + scopeFactory); System.out.println("Solving query: " + query); ForwardBoomerangResults res = solver.solve(query); @@ -117,16 +114,18 @@ public void killOnSystemExitForwardTest() { statement -> statement.containsInvokeExpr() && statement.getInvokeExpr().getMethod().getName().equals("queryFor")); - Assert.assertEquals(false, t); + Assert.assertFalse(t); } - public static BackwardQuery selectQueryForStatement(SootMethod m) { - Method method = JimpleMethod.of(m); - method.getStatements().stream().filter(x -> x.containsInvokeExpr()).forEach(x -> x.toString()); + public static BackwardQuery selectQueryForStatement(Method method) { Statement queryStatement = method.getStatements().stream() - .filter(x -> x.containsInvokeExpr()) - .filter(x -> x.getInvokeExpr().getMethod().getName().equals("queryFor")) + .filter(Statement::containsInvokeExpr) + .filter( + x -> { + System.out.println("methodname: " + x.getInvokeExpr().getMethod().getName()); + return x.getInvokeExpr().getMethod().getName().equals("queryFor"); + }) .findFirst() .get(); Val arg = queryStatement.getInvokeExpr().getArg(0); @@ -137,9 +136,8 @@ public static BackwardQuery selectQueryForStatement(SootMethod m) { return BackwardQuery.make(cfgEdge, arg); } - public static ForwardQuery selectFirstIntAssignment(SootMethod m) { - Method method = JimpleMethod.of(m); - method.getStatements().stream().forEach(x -> System.out.println(x.toString())); + public static ForwardQuery selectFirstIntAssignment(Method method) { + method.getStatements().forEach(x -> System.out.println(x.toString())); Statement intAssignStmt = method.getStatements().stream() .filter(x -> x.isAssign() && !x.getLeftOp().getType().isRefType()) @@ -153,47 +151,7 @@ public static ForwardQuery selectFirstIntAssignment(SootMethod m) { return new ForwardQuery(cfgEdge, arg); } - protected void setupSoot(Class cls) { - G.v().reset(); - setupSoot(); - setApplicationClass(cls); - PackManager.v().runPacks(); - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - } - - private void setupSoot() { - Options.v().set_whole_program(true); - Options.v().setPhaseOption("cg." + CG, "on"); - Options.v().setPhaseOption("cg." + CG, "verbose:true"); - Options.v().set_output_format(Options.output_format_none); - Options.v().set_no_bodies_for_excluded(true); - Options.v().set_allow_phantom_refs(true); - Options.v().setPhaseOption("jb", "use-original-names:true"); - Options.v().set_keep_line_number(true); - Options.v().set_prepend_classpath(true); - Options.v().set_process_dir(getProcessDir()); - } - - private void setApplicationClass(Class cls) { - Scene.v().loadNecessaryClasses(); - List eps = Lists.newArrayList(); - for (SootClass sootClass : Scene.v().getClasses()) { - if (sootClass.toString().equals(cls.getName()) - || (sootClass.toString().contains(cls.getName() + "$"))) { - sootClass.setApplicationClass(); - eps.addAll(sootClass.getMethods()); - } - } - Scene.v().setEntryPoints(eps); - } - - private List getProcessDir() { - Path path = Paths.get("target/test-classes"); - return Lists.newArrayList(path.toAbsolutePath().toString()); - } - - private class CustomBoomerangOptions extends DefaultBoomerangOptions { + private static class CustomBoomerangOptions extends DefaultBoomerangOptions { @Override public IForwardFlowFunction getForwardFlowFunctions() { @@ -206,7 +164,7 @@ public IBackwardFlowFunction getBackwardFlowFunction() { } } - private class CustomIntAndStringBoomerangOptions extends IntAndStringBoomerangOptions { + private static class CustomIntAndStringBoomerangOptions extends IntAndStringBoomerangOptions { @Override public IForwardFlowFunction getForwardFlowFunctions() { diff --git a/boomerangPDS/src/test/java/boomerang/guided/DemandDrivenGuidedAnalysisTest.java b/boomerangPDS/src/test/java/boomerang/guided/DemandDrivenGuidedAnalysisTest.java index 53338084..5a8a241e 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/DemandDrivenGuidedAnalysisTest.java +++ b/boomerangPDS/src/test/java/boomerang/guided/DemandDrivenGuidedAnalysisTest.java @@ -4,301 +4,279 @@ import boomerang.ForwardQuery; import boomerang.Query; import boomerang.QueryGraph; -import boomerang.guided.targets.ArrayContainerTarget; -import boomerang.guided.targets.BasicTarget; -import boomerang.guided.targets.BranchingAfterNewStringTest; -import boomerang.guided.targets.BranchingTest; -import boomerang.guided.targets.ContextSensitiveAndLeftUnbalanced2StacksTarget; -import boomerang.guided.targets.ContextSensitiveAndLeftUnbalancedFieldTarget; -import boomerang.guided.targets.ContextSensitiveAndLeftUnbalancedTarget; -import boomerang.guided.targets.ContextSensitiveAndLeftUnbalancedTarget2; -import boomerang.guided.targets.ContextSensitiveAndLeftUnbalancedThisFieldTarget; -import boomerang.guided.targets.ContextSensitiveTarget; -import boomerang.guided.targets.IntegerCastTarget; -import boomerang.guided.targets.LeftUnbalancedTarget; -import boomerang.guided.targets.NestedContextAndBranchingTarget; -import boomerang.guided.targets.NestedContextTarget; -import boomerang.guided.targets.PingPongInterproceduralTarget; -import boomerang.guided.targets.PingPongTarget; -import boomerang.guided.targets.ValueOfTarget; -import boomerang.guided.targets.WrappedInNewStringInnerTarget; -import boomerang.guided.targets.WrappedInNewStringTarget; -import boomerang.guided.targets.WrappedInStringTwiceTest; -import boomerang.scene.AllocVal; +import boomerang.guided.targets.*; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.Method; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; import boomerang.scene.jimple.IntAndStringBoomerangOptions; -import boomerang.scene.jimple.JimpleMethod; -import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import java.nio.file.Path; +import java.io.Serializable; import java.nio.file.Paths; -import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import soot.G; -import soot.PackManager; -import soot.Scene; -import soot.SootClass; -import soot.SootMethod; -import soot.options.Options; +import test.FrameworkScopeFactory; import wpds.impl.Weight.NoWeight; public class DemandDrivenGuidedAnalysisTest { - public static String CG = "cha"; + private final String classPathStr = Paths.get("target/test-classes").toAbsolutePath().toString(); @Test public void integerCastTest() { - setupSoot(IntegerCastTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, IntegerCastTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); + BackwardQuery query = selectFirstBaseOfToString(m); Specification spec = Specification.create(""); - runAnalysis(spec, query, 1); + runAnalysis(scopeFactory, spec, query, 1); } @Test public void basicTarget() { - setupSoot(BasicTarget.class); - SootMethod m = - Scene.v() - .getMethod(""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, BasicTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test @Ignore( "We need additional logic to tell the analysis to continue at some unknown parent context") public void leftUnbalancedTargetTest() { - setupSoot(LeftUnbalancedTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, LeftUnbalancedTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void contextSensitiveTest() { - setupSoot(ContextSensitiveTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, ContextSensitiveTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void nestedContextTest() { - setupSoot(NestedContextTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, NestedContextTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void nestedContextAndBranchingTest() { - setupSoot(NestedContextAndBranchingTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, NestedContextAndBranchingTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar", "foo"); + runAnalysis(scopeFactory, query, "bar", "foo"); } @Test public void contextSensitiveAndLeftUnbalanced2StacksTest() { - setupSoot(ContextSensitiveAndLeftUnbalanced2StacksTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init( + classPathStr, ContextSensitiveAndLeftUnbalanced2StacksTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void contextSensitiveAndLeftUnbalancedTest() { - setupSoot(ContextSensitiveAndLeftUnbalancedTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init( + classPathStr, ContextSensitiveAndLeftUnbalancedTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void contextSensitiveAndLeftUnbalancedWithFieldTest() { - setupSoot(ContextSensitiveAndLeftUnbalancedFieldTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init( + classPathStr, ContextSensitiveAndLeftUnbalancedFieldTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void contextSensitiveAndLeftUnbalancedWithThisFieldTest() { - setupSoot(ContextSensitiveAndLeftUnbalancedThisFieldTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init( + classPathStr, ContextSensitiveAndLeftUnbalancedThisFieldTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void contextSensitiveAndLeftUnbalancedWithFieldTest2() { - setupSoot(ContextSensitiveAndLeftUnbalancedTarget2.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init( + classPathStr, ContextSensitiveAndLeftUnbalancedTarget2.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstBaseOfToString(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void wrappedInNewStringTest() { - setupSoot(WrappedInNewStringTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, WrappedInNewStringTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void wrappedInNewStringInnerTest() { - setupSoot(WrappedInNewStringInnerTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, WrappedInNewStringInnerTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void wrappedInNewStringTwiceTest() { - setupSoot(WrappedInStringTwiceTest.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, WrappedInStringTwiceTest.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar"); + runAnalysis(scopeFactory, query, "bar"); } @Test public void branchingTest() { - setupSoot(BranchingTest.class); - SootMethod m = - Scene.v() - .getMethod(""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, BranchingTest.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar", "foo"); + runAnalysis(scopeFactory, query, "bar", "foo"); } @Test public void branchingAfterNewTest() { - setupSoot(BranchingAfterNewStringTest.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, BranchingAfterNewStringTest.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(query, "bar", "foo"); + runAnalysis(scopeFactory, query, "bar", "foo"); } @Test public void pingPongTest() { - setupSoot(PingPongTarget.class); - SootMethod m = - Scene.v() - .getMethod(""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, PingPongTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(getPingPongSpecification(), query, "hello", "world"); + runAnalysis(scopeFactory, getPingPongSpecification(), query, "hello", "world"); } @Test public void pingPongInterpoceduralTest() { - setupSoot(PingPongInterproceduralTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, PingPongInterproceduralTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstFileInitArgument(m); - runAnalysis(getPingPongSpecification(), query, "hello", "world"); + runAnalysis(scopeFactory, getPingPongSpecification(), query, "hello", "world"); } @Test public void arrayContainerTest() { - setupSoot(ArrayContainerTarget.class); - SootMethod m = - Scene.v() - .getMethod( - ""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, ArrayContainerTarget.class.getName()); + String methodSignatureStr = + ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstBaseOfToString(m); - runAnalysis(new ArrayContainerCollectionManager(), query, "hello", "world"); + runAnalysis(scopeFactory, new ArrayContainerCollectionManager(), query, "hello", "world"); } @Test public void valueOfTarget() { - setupSoot(ValueOfTarget.class); - SootMethod m = - Scene.v().getMethod(""); + FrameworkScope scopeFactory = + FrameworkScopeFactory.init(classPathStr, ValueOfTarget.class.getName()); + String methodSignatureStr = ""; + Method m = scopeFactory.getMethod(methodSignatureStr); BackwardQuery query = selectFirstArgOfQueryTarget(m); - runAnalysis(query, 1); + runAnalysis(scopeFactory, query, 1); } - public static BackwardQuery selectFirstArgOfQueryTarget(SootMethod m) { - Method method = JimpleMethod.of(m); - method.getStatements().stream().filter(x -> x.containsInvokeExpr()).forEach(x -> x.toString()); + public static BackwardQuery selectFirstArgOfQueryTarget(Method method) { Statement newFileStatement = method.getStatements().stream() - .filter(x -> x.containsInvokeExpr()) + .filter(Statement::containsInvokeExpr) .filter( x -> x.getInvokeExpr().getMethod().getName().equals("queryFor") @@ -325,12 +303,11 @@ private Specification getPingPongSpecification() { ""); } - public static BackwardQuery selectFirstFileInitArgument(SootMethod m) { - Method method = JimpleMethod.of(m); - method.getStatements().stream().filter(x -> x.containsInvokeExpr()).forEach(x -> x.toString()); + public static BackwardQuery selectFirstFileInitArgument(Method method) { + Statement newFileStatement = method.getStatements().stream() - .filter(x -> x.containsInvokeExpr()) + .filter(Statement::containsInvokeExpr) .filter( x -> x.getInvokeExpr().getMethod().getName().equals("") @@ -349,12 +326,10 @@ public static BackwardQuery selectFirstFileInitArgument(SootMethod m) { return BackwardQuery.make(cfgEdge, arg); } - public static BackwardQuery selectFirstBaseOfToString(SootMethod m) { - Method method = JimpleMethod.of(m); - method.getStatements().stream().filter(x -> x.containsInvokeExpr()).forEach(x -> x.toString()); + public static BackwardQuery selectFirstBaseOfToString(Method method) { Statement newFileStatement = method.getStatements().stream() - .filter(x -> x.containsInvokeExpr()) + .filter(Statement::containsInvokeExpr) .filter(x -> x.getInvokeExpr().getMethod().getName().equals("toString")) .findFirst() .get(); @@ -366,7 +341,8 @@ public static BackwardQuery selectFirstBaseOfToString(SootMethod m) { return BackwardQuery.make(cfgEdge, arg); } - protected void runAnalysis(BackwardQuery query, Object... expectedValues) { + protected void runAnalysis( + FrameworkScope scopeFactory, BackwardQuery query, Object... expectedValues) { Specification specification = Specification.create( "", @@ -374,7 +350,7 @@ protected void runAnalysis(BackwardQuery query, Object... expectedValues) { "(ON{F}java.lang.String)>", "(GO{B}java.lang.String)>", ""); - runAnalysis(specification, query, expectedValues); + runAnalysis(scopeFactory, specification, query, expectedValues); } private boolean isStringOrIntAllocation(Statement stmt) { @@ -383,12 +359,19 @@ private boolean isStringOrIntAllocation(Statement stmt) { } protected void runAnalysis( - Specification specification, BackwardQuery query, Object... expectedValues) { - runAnalysis(new SimpleSpecificationGuidedManager(specification), query, expectedValues); + FrameworkScope scopeFactory, + Specification specification, + BackwardQuery query, + Object... expectedValues) { + runAnalysis( + scopeFactory, new SimpleSpecificationGuidedManager(specification), query, expectedValues); } protected void runAnalysis( - IDemandDrivenGuidedManager queryManager, BackwardQuery query, Object... expectedValues) { + FrameworkScope scopeFactory, + IDemandDrivenGuidedManager queryManager, + BackwardQuery query, + Object... expectedValues) { DemandDrivenGuidedAnalysis demandDrivenGuidedAnalysis = new DemandDrivenGuidedAnalysis( queryManager, @@ -412,10 +395,16 @@ public int analysisTimeoutMS() { public boolean allowMultipleQueries() { return true; } - }); + }, + scopeFactory.getDataFlowScope(), + scopeFactory.getCallGraph(), + scopeFactory); QueryGraph queryGraph = demandDrivenGuidedAnalysis.run(query); demandDrivenGuidedAnalysis.cleanUp(); + + // Assert.assertFalse(queryGraph.getNodes().isEmpty()); + // Filter out query graph's node to only return the queries of interest (ForwardQueries & // String/Int Allocation sites). Stream res = @@ -424,51 +413,13 @@ public boolean allowMultipleQueries() { x -> x instanceof ForwardQuery && isStringOrIntAllocation(x.asNode().stmt().getStart())); - Assert.assertEquals( - Sets.newHashSet(expectedValues), + + Set collect = res.map(t -> ((AllocVal) t.var()).getAllocVal()) .filter(x -> x.isStringConstant() || x.isIntConstant()) .map(x -> (x.isIntConstant() ? x.getIntValue() : x.getStringValue())) - .collect(Collectors.toSet())); - } - - protected void setupSoot(Class cls) { - G.v().reset(); - setupSoot(); - setApplicationClass(cls); - PackManager.v().runPacks(); - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - } - - private void setupSoot() { - Options.v().set_whole_program(true); - Options.v().setPhaseOption("cg." + CG, "on"); - Options.v().setPhaseOption("cg." + CG, "verbose:true"); - Options.v().set_output_format(Options.output_format_none); - Options.v().set_no_bodies_for_excluded(true); - Options.v().set_allow_phantom_refs(true); - Options.v().setPhaseOption("jb", "use-original-names:true"); - Options.v().set_keep_line_number(true); - Options.v().set_prepend_classpath(true); - Options.v().set_process_dir(getProcessDir()); - } - - private void setApplicationClass(Class cls) { - Scene.v().loadNecessaryClasses(); - List eps = Lists.newArrayList(); - for (SootClass sootClass : Scene.v().getClasses()) { - if (sootClass.toString().equals(cls.getName()) - || (sootClass.toString().contains(cls.getName() + "$"))) { - sootClass.setApplicationClass(); - eps.addAll(sootClass.getMethods()); - } - } - Scene.v().setEntryPoints(eps); - } + .collect(Collectors.toSet()); - private List getProcessDir() { - Path path = Paths.get("target/test-classes"); - return Lists.newArrayList(path.toAbsolutePath().toString()); + Assert.assertEquals(Sets.newHashSet(expectedValues), collect); } } diff --git a/boomerangPDS/src/test/java/boomerang/guided/flowfunction/CustomForwardFlowFunction.java b/boomerangPDS/src/test/java/boomerang/guided/flowfunction/CustomForwardFlowFunction.java index b7966817..46554345 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/flowfunction/CustomForwardFlowFunction.java +++ b/boomerangPDS/src/test/java/boomerang/guided/flowfunction/CustomForwardFlowFunction.java @@ -43,11 +43,8 @@ public Set normalFlow(ForwardQuery query, Edge nextEdge, Val fact) { public boolean declaredMethodIsSystemExit(Statement callSite) { DeclaredMethod method = callSite.getInvokeExpr().getMethod(); - if (method.getDeclaringClass().getFullyQualifiedName().equals("java.lang.System") - && method.getName().equals("exit")) { - return true; - } - return false; + return method.getDeclaringClass().getFullyQualifiedName().equals("java.lang.System") + && method.getName().equals("exit"); } @Override diff --git a/boomerangPDS/src/test/java/boomerang/guided/targets/BasicTarget.java b/boomerangPDS/src/test/java/boomerang/guided/targets/BasicTarget.java index 62c39ff4..080c875d 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/targets/BasicTarget.java +++ b/boomerangPDS/src/test/java/boomerang/guided/targets/BasicTarget.java @@ -7,6 +7,5 @@ public class BasicTarget { public static void main(String... args) { String x = "bar"; new File(x); - ; } } diff --git a/boomerangPDS/src/test/java/boomerang/guided/targets/BranchingTest.java b/boomerangPDS/src/test/java/boomerang/guided/targets/BranchingTest.java index 7efa92b2..22baa16e 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/targets/BranchingTest.java +++ b/boomerangPDS/src/test/java/boomerang/guided/targets/BranchingTest.java @@ -8,7 +8,6 @@ public static void main(String... args) { String x = new String(Math.random() > 0 ? "bar" : "foo"); String bar = doPassArgument(x); new File(bar); - ; } public static String doPassArgument(String param) { diff --git a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringInnerTarget.java b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringInnerTarget.java index d17446a2..641c71ee 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringInnerTarget.java +++ b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringInnerTarget.java @@ -8,7 +8,6 @@ public static void main(String... args) { String x = "bar"; String bar = doPassArgument(x); new File(bar); - ; } public static String doPassArgument(String param) { diff --git a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringTarget.java b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringTarget.java index 26672836..d2c58028 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringTarget.java +++ b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInNewStringTarget.java @@ -5,11 +5,9 @@ public class WrappedInNewStringTarget { public static void main(String... args) { - String x = new String("bar"); String bar = doPassArgument(x); new File(bar); - ; } public static String doPassArgument(String param) { diff --git a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInStringTwiceTest.java b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInStringTwiceTest.java index bdb5e2a6..3616ae0f 100644 --- a/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInStringTwiceTest.java +++ b/boomerangPDS/src/test/java/boomerang/guided/targets/WrappedInStringTwiceTest.java @@ -8,7 +8,6 @@ public static void main(String... args) { String x = new String("bar"); String bar = doPassArgument(x); new File(bar); - ; } public static String doPassArgument(String param) { diff --git a/boomerangPDS/src/main/java/boomerang/example/ExampleMain1.java b/boomerangPDS/src/test/java/example/ExampleMain1.java similarity index 89% rename from boomerangPDS/src/main/java/boomerang/example/ExampleMain1.java rename to boomerangPDS/src/test/java/example/ExampleMain1.java index 31a21fe8..1742a761 100644 --- a/boomerangPDS/src/main/java/boomerang/example/ExampleMain1.java +++ b/boomerangPDS/src/test/java/example/ExampleMain1.java @@ -9,7 +9,10 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.example; +/* + sven said this example did not work before refactoring + +package example; import boomerang.BackwardQuery; import boomerang.Boomerang; @@ -18,33 +21,20 @@ import boomerang.results.BackwardBoomerangResults; import boomerang.scene.AnalysisScope; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.SootDataFlowScope; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.jimple.SootCallGraph; import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Map; -import soot.G; -import soot.PackManager; -import soot.Scene; -import soot.SceneTransformer; -import soot.SootClass; -import soot.SootMethod; -import soot.Transform; -import soot.Transformer; -import soot.options.Options; import wpds.impl.Weight; public class ExampleMain1 { public static void main(String... args) { String sootClassPath = getSootClassPath(); - String mainClass = "boomerang.example.BoomerangExampleTarget1"; - setupSoot(sootClassPath, mainClass); + setupSoot(sootClassPath, "boomerang.example.BoomerangExampleTarget1"); analyze(); } @@ -134,7 +124,10 @@ protected Collection generate(Edge cfgEdge) { // 1. Create a Boomerang solver. Boomerang solver = new Boomerang( - sootCallGraph, SootDataFlowScope.make(Scene.v()), new DefaultBoomerangOptions()); + sootCallGraph, + SootDataFlowScope.make(Scene.v()), + new DefaultBoomerangOptions(), + new SootFrameworkFactory()); // 2. Submit a query to the solver. Collection seeds = scope.computeSeeds(); @@ -152,3 +145,5 @@ protected Collection generate(Edge cfgEdge) { }; } } + + */ diff --git a/boomerangPDS/src/main/java/boomerang/example/ExampleMain2.java b/boomerangPDS/src/test/java/example/ExampleMain2.java similarity index 93% rename from boomerangPDS/src/main/java/boomerang/example/ExampleMain2.java rename to boomerangPDS/src/test/java/example/ExampleMain2.java index b0599e21..dacbffa3 100644 --- a/boomerangPDS/src/main/java/boomerang/example/ExampleMain2.java +++ b/boomerangPDS/src/test/java/example/ExampleMain2.java @@ -9,21 +9,26 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.example; + +/* + sven said this example did not work before refactoring + +package example; import boomerang.Boomerang; import boomerang.DefaultBoomerangOptions; import boomerang.ForwardQuery; import boomerang.Query; +import boomerang.framework.soot.SootDataFlowScope; +import boomerang.framework.soot.SootFrameworkFactory; +import boomerang.framework.soot.jimple.BoomerangPretransformer; +import boomerang.framework.soot.jimple.SootCallGraph; import boomerang.results.ForwardBoomerangResults; import boomerang.scene.AllocVal; import boomerang.scene.AnalysisScope; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.SootDataFlowScope; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.jimple.SootCallGraph; import com.google.common.collect.Table; import java.io.File; import java.util.Collection; @@ -150,7 +155,10 @@ protected Collection generate(Edge cfgEdge) { // 1. Create a Boomerang solver. Boomerang solver = new Boomerang( - sootCallGraph, SootDataFlowScope.make(Scene.v()), new DefaultBoomerangOptions()); + sootCallGraph, + SootDataFlowScope.make(Scene.v()), + new DefaultBoomerangOptions(), + new SootFrameworkFactory()); System.out.println("Solving query: " + query); // 2. Submit a query to the solver. ForwardBoomerangResults forwardBoomerangResults = @@ -175,3 +183,4 @@ protected Collection generate(Edge cfgEdge) { }; } } + */ diff --git a/boomerangPDS/src/test/java/test/cases/bugfixes/Repro.java b/boomerangPDS/src/test/java/test/cases/bugfixes/Repro.java index 201e7203..a3c2607b 100644 --- a/boomerangPDS/src/test/java/test/cases/bugfixes/Repro.java +++ b/boomerangPDS/src/test/java/test/cases/bugfixes/Repro.java @@ -1,77 +1,87 @@ package test.cases.bugfixes; import boomerang.Boomerang; -import boomerang.BoomerangOptions; import boomerang.ForwardQuery; import boomerang.results.ForwardBoomerangResults; import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.jimple.*; import com.google.common.collect.Sets; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; +import java.util.*; import org.junit.Test; -import soot.*; -import soot.options.Options; +import test.AbstractTestingFramework; +import test.FrameworkScopeFactory; import wpds.impl.Weight.NoWeight; /** * This code was added to test https://github.com/CodeShield-Security/SPDS/issues/5. * Thanks @copumpkin for sharing code for testing purpose. */ -public class Repro { - static BoomerangOptions opts = new IntAndStringBoomerangOptions(); +public class Repro extends AbstractTestingFramework { @Test public void excludeFoo() { - G.reset(); - setupSoot("src/test/resources/Test.jar", true); - analyze("", "", "()>"); + FrameworkScope scope = setup(Collections.singletonList("Foo")); + assertResults("", "", "()>"); } @Test public void includeFoo() { - G.reset(); - setupSoot("src/test/resources/Test.jar", false); - analyze( + FrameworkScope scope = setup(Collections.emptyList()); + assertResults( "", "", "()>", "()>"); } - private static void setupSoot(String classPath, boolean excludeFoo) { - Options.v().set_whole_program(true); - Options.v().setPhaseOption("cg.spark", "on"); - Options.v().set_no_bodies_for_excluded(true); - Options.v().set_allow_phantom_refs(true); - Options.v().set_keep_line_number(true); + @Override + protected void initializeWithEntryPoint() { + // empty + } + + private FrameworkScope setup(List excluded) { + return FrameworkScopeFactory.init( + "src/test/resources/Test.jar", + getTestCaseClassName(), + testMethodName.getMethodName(), + Collections.emptyList(), + excluded); + } - /* ********* Uncomment this line to see methods invoked on Foo! ********* */ - if (excludeFoo) { - Options.v().set_exclude(Collections.singletonList("Foo")); + @Override + public void analyze() {} + + private void assertResults(String... expectedCalledMethodsOnFoo) { + Method method = frameworkScope.getMethod(""); + System.out.println("All method units:"); + for (Statement s : method.getControlFlowGraph().getStatements()) { + System.out.println("\t" + s.toString()); } - Options.v().setPhaseOption("jb", "use-original-names:true"); - Options.v().set_soot_classpath(classPath); - Options.v().set_prepend_classpath(true); - Options.v().set_process_dir(Arrays.asList(classPath.split(":"))); - Scene.v().loadNecessaryClasses(); - } + Statement newFoo = + method.getControlFlowGraph().getStatements().stream() + .filter(x -> x.toString().contains("$stack2 = new Foo")) + .findFirst() + .get(); + + // This will only show results if set_exclude above gets uncommented + System.out.println("\nFoo invoked methods:"); + Collection statements = + getMethodsInvokedFromInstanceInStatement(frameworkScope, newFoo); + Set methodCalledOnFoo = Sets.newHashSet(); + for (Statement s : statements) { + System.out.println("\t" + s); + DeclaredMethod calledMethod = s.getInvokeExpr().getMethod(); + System.out.println("\t\t" + calledMethod); + methodCalledOnFoo.add(calledMethod.toString()); + } - private static void analyze(String... expectedCallSignatureOnFoo) { - PackManager.v() - .getPack("wjtp") - .add(new Transform("wjtp.repro", new ReproTransformer(expectedCallSignatureOnFoo))); - PackManager.v().getPack("cg").apply(); - PackManager.v().getPack("wjtp").apply(); + assert methodCalledOnFoo.equals(Sets.newHashSet(expectedCalledMethodsOnFoo)); } private static Collection getMethodsInvokedFromInstanceInStatement( - Statement queryStatement) { + FrameworkScope scopeFactory, Statement queryStatement) { Val var = new AllocVal(queryStatement.getLeftOp(), queryStatement, queryStatement.getRightOp()); ForwardQuery fwq = new ForwardQuery( @@ -81,51 +91,13 @@ private static Collection getMethodsInvokedFromInstanceInStatement( .findFirst() .get()), var); - Boomerang solver = new Boomerang(new SootCallGraph(), SootDataFlowScope.make(Scene.v()), opts); + Boomerang solver = + new Boomerang( + scopeFactory.getCallGraph(), + scopeFactory.getDataFlowScope(), + new IntAndStringBoomerangOptions(), + scopeFactory); ForwardBoomerangResults results = solver.solve(fwq); return results.getInvokeStatementsOnInstance(); } - - static class ReproTransformer extends SceneTransformer { - - Set expectedCalledMethodsOnFoo; - - public ReproTransformer(String... expectedCallSignatureOnFoo) { - expectedCalledMethodsOnFoo = Sets.newHashSet(expectedCallSignatureOnFoo); - } - - @Override - protected void internalTransform(String name, Map options) { - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - - SootMethod m = Scene.v().getMethod(""); - Method method = JimpleMethod.of(m); - - System.out.println("All method units:"); - for (Statement s : method.getControlFlowGraph().getStatements()) { - System.out.println("\t" + s.toString()); - } - - Statement newFoo = - method.getControlFlowGraph().getStatements().stream() - .filter(x -> x.toString().contains("$stack2 = new Foo")) - .findFirst() - .get(); - - // This will only show results if set_exclude above gets uncommented - System.out.println("\nFoo invoked methods:"); - Collection statements = getMethodsInvokedFromInstanceInStatement(newFoo); - Set methodCalledOnFoo = Sets.newHashSet(); - for (Statement s : statements) { - System.out.println("\t" + s); - - DeclaredMethod calledMethod = s.getInvokeExpr().getMethod(); - System.out.println("\t\t" + calledMethod); - methodCalledOnFoo.add(calledMethod.toString()); - } - - assert methodCalledOnFoo.equals(Sets.newHashSet(expectedCalledMethodsOnFoo)); - } - } } diff --git a/boomerangPDS/src/test/java/test/cases/fields/CallPOITest.java b/boomerangPDS/src/test/java/test/cases/fields/CallPOITest.java index 881d0f86..e4b3b6cb 100644 --- a/boomerangPDS/src/test/java/test/cases/fields/CallPOITest.java +++ b/boomerangPDS/src/test/java/test/cases/fields/CallPOITest.java @@ -37,7 +37,7 @@ public void simpleButDiffer() { } public static class T { - private Object value; + private final Object value; T(Object o) { this.value = o; diff --git a/boomerangPDS/src/test/java/test/cases/fields/complexity/Recursion2LongTest.java b/boomerangPDS/src/test/java/test/cases/fields/complexity/Recursion2LongTest.java index ff9f5d48..8bf751c5 100644 --- a/boomerangPDS/src/test/java/test/cases/fields/complexity/Recursion2LongTest.java +++ b/boomerangPDS/src/test/java/test/cases/fields/complexity/Recursion2LongTest.java @@ -23,7 +23,7 @@ public void test() { queryFor(alias); } - public static interface IFoo { + public interface IFoo { DS before(DS ds); DS after(DS ds); diff --git a/boomerangPDS/src/test/java/test/cases/hashmap/AllAliasLongTest.java b/boomerangPDS/src/test/java/test/cases/hashmap/AllAliasLongTest.java index 52ffac19..5462f128 100644 --- a/boomerangPDS/src/test/java/test/cases/hashmap/AllAliasLongTest.java +++ b/boomerangPDS/src/test/java/test/cases/hashmap/AllAliasLongTest.java @@ -19,7 +19,7 @@ public class AllAliasLongTest extends AbstractBoomerangTest { public void test() { TreeNode a = new TreeNode(0, new Object(), new Object(), null); TreeNode t = new TreeNode(0, null, new Object(), a); - t.balanceDeletion(t, a); + TreeNode.balanceDeletion(t, a); // t.balanceInsertion(t, t); t.treeify(new TreeNode[] {a, t}); // t.moveRootToFront(new TreeNode[]{a,t},a); diff --git a/boomerangPDS/src/test/java/test/cases/hashmap/KeySensitiveTest.java b/boomerangPDS/src/test/java/test/cases/hashmap/KeySensitiveTest.java index 20e4f517..418f64fe 100644 --- a/boomerangPDS/src/test/java/test/cases/hashmap/KeySensitiveTest.java +++ b/boomerangPDS/src/test/java/test/cases/hashmap/KeySensitiveTest.java @@ -12,11 +12,9 @@ package test.cases.hashmap; import boomerang.scene.DataFlowScope; -import boomerang.scene.SootDataFlowScope; import java.util.HashMap; import java.util.Map; import org.junit.Test; -import soot.Scene; import test.cases.array.ArrayTest.NoAllocation; import test.cases.basic.Allocation; import test.cases.fields.Alloc; @@ -66,6 +64,20 @@ public void accessWithAliasedKey() { queryFor(t); } + /* + classes: 3413 + [main] INFO boomerang.scene.AnalysisScope - Computing seeds starting at 1 entry method(s). + [main] INFO boomerang.scene.AnalysisScope - Found 1 seeds in 35.17 ms in 3588 LOC . + [main] INFO boomerang.scene.AnalysisScope - Computing seeds starting at 1 entry method(s). + [main] INFO boomerang.scene.AnalysisScope - Found 1 seeds in 24.64 ms in 3588 LOC . + [main] INFO boomerang.scene.AnalysisScope - Computing seeds starting at 1 entry method(s). + [main] INFO boomerang.scene.AnalysisScope - Found 1 seeds in 5.280 ms in 3588 LOC . + [main] INFO test.core.AbstractBoomerangTest - Solving query took: 168.5 ms + [main] INFO test.core.AbstractBoomerangTest - Expected results: PT0.168372811S + [main] INFO test.core.AbstractBoomerangTest - Boomerang Results: [($stack4 (test.cases.hashmap.KeySensitiveTest.),$stack4 = new Alloc -> $stack4.())] + [main] INFO test.core.AbstractBoomerangTest - Expected Results: [ForwardQuery: ($stack4 (test.cases.hashmap.KeySensitiveTest.),$stack4 = new Alloc -> $stack4.())] + + */ @Test public void accessWithKeyFromReturn() { AllocatedObject someValue = new Alloc(); @@ -98,6 +110,6 @@ private String getKey() { @Override protected DataFlowScope getDataFlowScope() { - return SootDataFlowScope.excludeComplex(Scene.v()); + return frameworkScope.createDataFlowScopeWithoutComplex(); } } diff --git a/boomerangPDS/src/test/java/test/cases/statics/Singleton.java b/boomerangPDS/src/test/java/test/cases/statics/Singleton.java index 0b472857..eb9d050e 100644 --- a/boomerangPDS/src/test/java/test/cases/statics/Singleton.java +++ b/boomerangPDS/src/test/java/test/cases/statics/Singleton.java @@ -46,14 +46,14 @@ public static Alloc i() { return allocation; } - public static interface GlobalObjectGetter { - public Alloc getG(); + public interface GlobalObjectGetter { + Alloc getG(); - public void reset(); + void reset(); } private static Alloc alloc; - private static GlobalObjectGetter objectGetter = + private static final GlobalObjectGetter objectGetter = new GlobalObjectGetter() { Alloc instance = new Alloc(); diff --git a/boomerangPDS/src/test/java/test/cases/statics/StaticInitializer.java b/boomerangPDS/src/test/java/test/cases/statics/StaticInitializer.java index ddd8c84e..de6b83a0 100644 --- a/boomerangPDS/src/test/java/test/cases/statics/StaticInitializer.java +++ b/boomerangPDS/src/test/java/test/cases/statics/StaticInitializer.java @@ -16,7 +16,7 @@ import test.core.AbstractBoomerangTest; public class StaticInitializer extends AbstractBoomerangTest { - private static Object alloc = new Alloc(); + private static final Object alloc = new Alloc(); @Test public void doubleSingleton() { diff --git a/boomerangPDS/src/test/java/test/cases/statics/StaticWithSuperclasses.java b/boomerangPDS/src/test/java/test/cases/statics/StaticWithSuperclasses.java index 1b8ab287..791f840f 100644 --- a/boomerangPDS/src/test/java/test/cases/statics/StaticWithSuperclasses.java +++ b/boomerangPDS/src/test/java/test/cases/statics/StaticWithSuperclasses.java @@ -25,7 +25,7 @@ public void simple() { private static class List { - private static Object elementData = new Alloc(); + private static final Object elementData = new Alloc(); public Object get() { return elementData; @@ -41,7 +41,7 @@ public void supclass() { private static class MyList extends List { - private static Object elementData2 = new Alloc(); + private static final Object elementData2 = new Alloc(); public Object get() { return elementData2; diff --git a/boomerangPDS/src/test/java/test/cases/subclassing/AbstractClassWithInnerSubclassTest.java b/boomerangPDS/src/test/java/test/cases/subclassing/AbstractClassWithInnerSubclassTest.java index ed2447fc..56891849 100644 --- a/boomerangPDS/src/test/java/test/cases/subclassing/AbstractClassWithInnerSubclassTest.java +++ b/boomerangPDS/src/test/java/test/cases/subclassing/AbstractClassWithInnerSubclassTest.java @@ -46,7 +46,7 @@ public void typingIssue() { queryFor(query); } - private static interface Element { + private interface Element { AnotherClass get(); } } diff --git a/boomerangPDS/src/test/java/test/cases/typing/InterfaceInvocation.java b/boomerangPDS/src/test/java/test/cases/typing/InterfaceInvocation.java index 1eddc436..070ec054 100644 --- a/boomerangPDS/src/test/java/test/cases/typing/InterfaceInvocation.java +++ b/boomerangPDS/src/test/java/test/cases/typing/InterfaceInvocation.java @@ -42,7 +42,7 @@ private void foo(I a) { a.bar(); } - private static interface I { + private interface I { void bar(); } diff --git a/boomerangPDS/src/test/java/test/core/AbstractBoomerangTest.java b/boomerangPDS/src/test/java/test/core/AbstractBoomerangTest.java index ef76078b..4b4138a5 100644 --- a/boomerangPDS/src/test/java/test/core/AbstractBoomerangTest.java +++ b/boomerangPDS/src/test/java/test/core/AbstractBoomerangTest.java @@ -9,16 +9,9 @@ import boomerang.WeightedBoomerang; import boomerang.WholeProgramBoomerang; import boomerang.results.BackwardBoomerangResults; -import boomerang.scene.AllocVal; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Field; -import boomerang.scene.SootDataFlowScope; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; import boomerang.scene.jimple.IntAndStringBoomerangOptions; -import boomerang.scene.jimple.SootCallGraph; import boomerang.solver.ForwardBoomerangSolver; import boomerang.util.AccessPath; import boomerang.util.DefaultValueMap; @@ -31,20 +24,18 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.junit.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import soot.Scene; -import soot.SceneTransformer; import sync.pds.solver.OneWeightFunctions; import sync.pds.solver.WeightFunctions; import sync.pds.solver.nodes.INode; import sync.pds.solver.nodes.Node; import sync.pds.solver.nodes.SingleNode; -import test.core.selfrunning.AbstractTestingFramework; +import test.AbstractTestingFramework; +import test.FrameworkScopeFactory; import wpds.impl.Transition; import wpds.impl.Weight.NoWeight; import wpds.impl.WeightedPAutomaton; @@ -75,12 +66,10 @@ public class AbstractBoomerangTest extends AbstractTestingFramework { private static Duration globalQueryTime = Duration.ofMillis(0); protected int analysisTimeout = 3000 * 1000; - private CallGraph callGraph; - private DataFlowScope dataFlowScope; public enum AnalysisMode { WholeProgram, - DemandDrivenBackward; + DemandDrivenBackward } protected AnalysisMode[] getAnalyses() { @@ -94,26 +83,29 @@ public int getIterations() { return 1; } - @Before - public void beforeTestCaseExecution() { - super.beforeTestCaseExecution(); + @Override + protected void initializeWithEntryPoint() { + frameworkScope = + FrameworkScopeFactory.init( + buildClassPath(), + getTestCaseClassName(), + testMethodName.getMethodName(), + getIncludedPackagesList(), + getExludedPackageList()); } - protected SceneTransformer createAnalysisTransformer() { - return new SceneTransformer() { + @Override + protected void analyze() { + analyzeWithCallGraph(); + } - protected void internalTransform( - String phaseName, @SuppressWarnings("rawtypes") Map options) { - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - callGraph = new SootCallGraph(); - dataFlowScope = getDataFlowScope(); - analyzeWithCallGraph(); - } - }; + @Before + public void beforeTestCaseExecution() { + super.beforeTestCaseExecution(); } private void analyzeWithCallGraph() { + CallGraph callGraph = frameworkScope.getCallGraph(); queryDetector = new QueryForCallSiteDetector(callGraph); queryForCallSites = queryDetector.computeSeeds(); @@ -155,8 +147,8 @@ private void runWholeProgram() { final Set> results = Sets.newHashSet(); WholeProgramBoomerang solver = new WholeProgramBoomerang( - callGraph, - dataFlowScope, + frameworkScope.getCallGraph(), + frameworkScope.getDataFlowScope(), new DefaultBoomerangOptions() { @Override public int analysisTimeoutMS() { @@ -167,7 +159,8 @@ public int analysisTimeoutMS() { public boolean onTheFlyCallGraph() { return false; } - }) { + }, + frameworkScope) { @Override protected WeightFunctions getForwardFieldWeights() { @@ -230,7 +223,6 @@ public void onInTransitionAdded( } compareQuery(expectedAllocationSites, results, AnalysisMode.WholeProgram); - System.out.println(); } private void runDemandDrivenBackward() { @@ -278,7 +270,8 @@ private Set> runQuery(Collection queries) { for (final Query query : queries) { BoomerangOptions options = createBoomerangOptions(); - Boomerang solver = new Boomerang(callGraph, getDataFlowScope(), options) {}; + Boomerang solver = + new Boomerang(frameworkScope.getCallGraph(), getDataFlowScope(), options, frameworkScope); if (query instanceof BackwardQuery) { Stopwatch watch = Stopwatch.createStarted(); @@ -305,7 +298,7 @@ private Set> runQuery(Collection queries) { } protected DataFlowScope getDataFlowScope() { - return SootDataFlowScope.make(Scene.v()); + return frameworkScope.getDataFlowScope(); } protected BoomerangOptions createBoomerangOptions() { diff --git a/boomerangPDS/src/test/java/test/core/AllocationSiteOf.java b/boomerangPDS/src/test/java/test/core/AllocationSiteOf.java index ff7dd1dd..6793bd9c 100644 --- a/boomerangPDS/src/test/java/test/core/AllocationSiteOf.java +++ b/boomerangPDS/src/test/java/test/core/AllocationSiteOf.java @@ -10,7 +10,7 @@ import java.util.Optional; class AllocationSiteOf implements ValueOfInterestInUnit { - private String type; + private final String type; public AllocationSiteOf(String type) { this.type = type; @@ -25,7 +25,7 @@ public Optional test(Edge cfgEdge) { Val local = stmt.getLeftOp(); ForwardQuery forwardQuery = new ForwardQuery(cfgEdge, new AllocVal(local, stmt, stmt.getRightOp())); - return Optional.of(forwardQuery); + return Optional.of(forwardQuery); } } } diff --git a/boomerangPDS/src/test/java/test/core/FirstArgumentOf.java b/boomerangPDS/src/test/java/test/core/FirstArgumentOf.java index 74bc4a68..7a2aba86 100644 --- a/boomerangPDS/src/test/java/test/core/FirstArgumentOf.java +++ b/boomerangPDS/src/test/java/test/core/FirstArgumentOf.java @@ -8,7 +8,7 @@ public class FirstArgumentOf implements ValueOfInterestInUnit { - private String methodNameMatcher; + private final String methodNameMatcher; public FirstArgumentOf(String methodNameMatcher) { this.methodNameMatcher = methodNameMatcher; diff --git a/boomerangPDS/src/test/java/test/core/MultiQueryBoomerangTest.java b/boomerangPDS/src/test/java/test/core/MultiQueryBoomerangTest.java index 73b976bc..f21d7004 100644 --- a/boomerangPDS/src/test/java/test/core/MultiQueryBoomerangTest.java +++ b/boomerangPDS/src/test/java/test/core/MultiQueryBoomerangTest.java @@ -17,81 +17,76 @@ import boomerang.Query; import boomerang.WeightedBoomerang; import boomerang.results.BackwardBoomerangResults; -import boomerang.scene.AnalysisScope; -import boomerang.scene.CallGraph; -import boomerang.scene.DataFlowScope; -import boomerang.scene.SootDataFlowScope; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.jimple.SootCallGraph; +import boomerang.scene.*; import com.google.common.base.Joiner; import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; +import java.nio.file.Paths; import java.util.Collection; import java.util.HashSet; -import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; import org.junit.Rule; import org.junit.rules.Timeout; -import soot.RefType; -import soot.Scene; -import soot.SceneTransformer; -import soot.SootClass; -import soot.jimple.NewExpr; -import test.core.selfrunning.AbstractTestingFramework; +import test.AbstractTestingFramework; +import test.FrameworkScopeFactory; import wpds.impl.Weight; public class MultiQueryBoomerangTest extends AbstractTestingFramework { private static final boolean FAIL_ON_IMPRECISE = false; - @Rule public Timeout timeout = new Timeout(10000000, TimeUnit.MILLISECONDS); private Collection allocationSites; protected Collection queryForCallSites; protected Multimap expectedAllocsForQuery = HashMultimap.create(); protected Collection unsoundErrors = Sets.newHashSet(); protected Collection imprecisionErrors = Sets.newHashSet(); - private CallGraph callGraph; - private DataFlowScope dataFlowScope; protected int analysisTimeout = 300 * 1000; + private final String classPathStr = Paths.get("target/test-classes").toAbsolutePath().toString(); private WeightedBoomerang solver; - protected SceneTransformer createAnalysisTransformer() { - return new SceneTransformer() { - - protected void internalTransform( - String phaseName, @SuppressWarnings("rawtypes") Map options) { - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - callGraph = new SootCallGraph(); - dataFlowScope = SootDataFlowScope.make(Scene.v()); - AnalysisScope analysisScope = new Preanalysis(callGraph, new FirstArgumentOf("queryFor.*")); - - queryForCallSites = analysisScope.computeSeeds(); - - for (Query q : queryForCallSites) { - Val arg2 = q.cfgEdge().getStart().getInvokeExpr().getArg(1); - if (arg2.isClassConstant()) { - Preanalysis analysis = - new Preanalysis( - callGraph, new AllocationSiteOf(arg2.getClassConstantType().toString())); - expectedAllocsForQuery.putAll(q, analysis.computeSeeds()); - } - } - runDemandDrivenBackward(); - if (!unsoundErrors.isEmpty()) { - throw new RuntimeException(Joiner.on("\n").join(unsoundErrors)); - } - if (!imprecisionErrors.isEmpty() && FAIL_ON_IMPRECISE) { - throw new AssertionError(Joiner.on("\n").join(imprecisionErrors)); - } + @Override + protected void initializeWithEntryPoint() { + frameworkScope = + FrameworkScopeFactory.init( + classPathStr, + getTestCaseClassName(), + testMethodName.getMethodName(), + getIncludedPackagesList(), + getExludedPackageList()); + } + + @Override + protected void analyze() { + assertResults(); + } + + private void assertResults() { + AnalysisScope analysisScope = + new Preanalysis(frameworkScope.getCallGraph(), new FirstArgumentOf("queryFor.*")); + queryForCallSites = analysisScope.computeSeeds(); + + for (Query q : queryForCallSites) { + Val arg2 = q.cfgEdge().getStart().getInvokeExpr().getArg(1); + if (arg2.isClassConstant()) { + Preanalysis analysis = + new Preanalysis( + frameworkScope.getCallGraph(), + new AllocationSiteOf(arg2.getClassConstantType().toString())); + expectedAllocsForQuery.putAll(q, analysis.computeSeeds()); } - }; + } + runDemandDrivenBackward(); + if (!unsoundErrors.isEmpty()) { + throw new RuntimeException(Joiner.on("\n").join(unsoundErrors)); + } + if (!imprecisionErrors.isEmpty() && FAIL_ON_IMPRECISE) { + throw new AssertionError(Joiner.on("\n").join(imprecisionErrors)); + } } private void compareQuery(Query query, Collection results) { @@ -146,7 +141,12 @@ public boolean allowMultipleQueries() { return true; } }; - solver = new Boomerang(callGraph, dataFlowScope, options); + solver = + new Boomerang( + frameworkScope.getCallGraph(), + frameworkScope.getDataFlowScope(), + options, + frameworkScope); for (final Query query : queryForCallSites) { if (query instanceof BackwardQuery) { BackwardBoomerangResults res = solver.solve((BackwardQuery) query); @@ -156,6 +156,8 @@ public boolean allowMultipleQueries() { solver.unregisterAllListeners(); } + /* + // TODO: is it really not used? private boolean allocatesObjectOfInterest(NewExpr rightOp, String type) { SootClass interfaceType = Scene.v().getSootClass(type); if (!interfaceType.isInterface()) return false; @@ -164,7 +166,7 @@ private boolean allocatesObjectOfInterest(NewExpr rightOp, String type) { .getActiveHierarchy() .getImplementersOf(interfaceType) .contains(allocatedType.getSootClass()); - } + }*/ protected Collection errorOnVisitMethod() { return Lists.newLinkedList(); diff --git a/boomerangPDS/src/test/java/test/core/Preanalysis.java b/boomerangPDS/src/test/java/test/core/Preanalysis.java index b6a1204d..cd0664fe 100644 --- a/boomerangPDS/src/test/java/test/core/Preanalysis.java +++ b/boomerangPDS/src/test/java/test/core/Preanalysis.java @@ -9,7 +9,7 @@ public class Preanalysis extends AnalysisScope { - private ValueOfInterestInUnit f; + private final ValueOfInterestInUnit f; public Preanalysis(CallGraph cg, ValueOfInterestInUnit f) { super(cg); diff --git a/boomerangPDS/src/test/java/test/core/QueryForCallSiteDetector.java b/boomerangPDS/src/test/java/test/core/QueryForCallSiteDetector.java index 2a04d7d6..94ab041d 100644 --- a/boomerangPDS/src/test/java/test/core/QueryForCallSiteDetector.java +++ b/boomerangPDS/src/test/java/test/core/QueryForCallSiteDetector.java @@ -7,7 +7,6 @@ import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Val; import boomerang.scene.jimple.AccessPathParser; -import boomerang.scene.jimple.JimpleMethod; import boomerang.util.AccessPath; import java.util.Collection; import java.util.Collections; @@ -30,14 +29,13 @@ private void getAllExpectedAccessPath(Edge u) { Val arg = u.getStart().getInvokeExpr().getArg(1); if (arg.isStringConstant()) { String value = arg.getStringValue(); - expectedAccessPaths.addAll( - AccessPathParser.parseAllFromString(value, (JimpleMethod) u.getMethod())); + expectedAccessPaths.addAll(AccessPathParser.parseAllFromString(value, u.getMethod())); } } private class FirstArgumentOf implements ValueOfInterestInUnit { - private String methodNameMatcher; + private final String methodNameMatcher; public FirstArgumentOf(String methodNameMatcher) { this.methodNameMatcher = methodNameMatcher; diff --git a/boomerangPDS/visualization/index.html b/boomerangPDS/visualization/index.html index edcd6f12..ac74024f 100644 --- a/boomerangPDS/visualization/index.html +++ b/boomerangPDS/visualization/index.html @@ -440,7 +440,7 @@ addClassWhileOver(tgt, elements, "bold"); }); return cy; - }; + } // getElementById function $id(id) { diff --git a/boomerangPDS/visualization/libs/cytoscape.js b/boomerangPDS/visualization/libs/cytoscape.js index 30419d24..bf7627d3 100644 --- a/boomerangPDS/visualization/libs/cytoscape.js +++ b/boomerangPDS/visualization/libs/cytoscape.js @@ -2575,7 +2575,7 @@ function defineDegreeFunction( callback ){ return degree; } else { - return; + } }; } @@ -7843,7 +7843,7 @@ var corefn = ({ }; } - return; + }, minZoom: function( zoom ){ @@ -9413,7 +9413,7 @@ BreadthFirstLayout.prototype.run = function(){ var ele = nodes[ i ]; if( foundByBfs[ ele.id() ] ){ - continue; + } else { orphanNodes.push( ele ); } @@ -10339,7 +10339,7 @@ CoseLayout.prototype.run = function(){ // s += "\nForceX: " + forceX + " ForceY: " + forceY; // logDebug(s); - return; + }; /** @@ -10762,7 +10762,7 @@ CoseLayout.prototype.run = function(){ // s += ". No changes in boundaries/position of parent node " + p.id; // logDebug(s); - return; + }; var separateComponents = function( layutInfo, options ){ @@ -11179,7 +11179,7 @@ var findLCA_aux = function( node1, node2, graphIx, layoutInfo ){ var result = findLCA_aux( node1, node2, childGraphIx, layoutInfo ); if( 0 === result.count ){ // Neither node1 nor node2 are present in this subgraph - continue; + } else if( 1 === result.count ){ // One of (node1, node2) is present in this subgraph c++; @@ -11258,7 +11258,7 @@ var printLayoutInfo = function( layoutInfo ){ s += '\ntemperature: ' + layoutInfo.temperature; console.debug( s ); - return; + /* eslint-enable */ }; @@ -14679,7 +14679,7 @@ BRp.load = function(){ r.hoverData.tapholdTimeout = setTimeout( function(){ if( r.hoverData.tapholdCancelled ){ - return; + } else { var ele = r.hoverData.down; @@ -21675,7 +21675,7 @@ math.solveCubic = function( a, b, c, d, result ){ result[2] = -term1 + r13 * Math.cos( (dum1 + 2.0 * Math.PI) / 3.0 ); result[4] = -term1 + r13 * Math.cos( (dum1 + 4.0 * Math.PI) / 3.0 ); - return; + }; math.sqdistToQuadraticBezier = function( @@ -21808,7 +21808,7 @@ math.pointInsidePolygonPoints = function( x, y, points ){ } } else { - continue; + } } diff --git a/boomerangPDS/visualization/webix/codebase/webix_debug.js b/boomerangPDS/visualization/webix/codebase/webix_debug.js index 3514293d..6de47f8d 100644 --- a/boomerangPDS/visualization/webix/codebase/webix_debug.js +++ b/boomerangPDS/visualization/webix/codebase/webix_debug.js @@ -6918,7 +6918,7 @@ webix.Movable = { webix.DragControl.top = webix.DragControl.left = 5; this.master.callEvent("onViewMoveEnd", []); - return; + }, $dragPos:function(pos, e){ this.master.callEvent("onViewMove", [pos, e]); @@ -9201,7 +9201,7 @@ webix.protoUI({ }, customCheckbox_setter: function(value){ if( value === true && webix.skin.$active.customCheckbox){ - value = ""; + value = ""; } return value; }, @@ -9339,7 +9339,7 @@ webix.protoUI({ blur: function(){ this._blur(); }, customRadio_setter: function(value){ if(value === true && webix.skin.$active.customRadio) - value = ""; + value = ""; return value; }, $skin:function(){ diff --git a/boomerangScope-Soot/.gitignore b/boomerangScope-Soot/.gitignore new file mode 100644 index 00000000..0f630157 --- /dev/null +++ b/boomerangScope-Soot/.gitignore @@ -0,0 +1,2 @@ +/target/ +/bin/ diff --git a/boomerangScope-Soot/LICENSE.txt b/boomerangScope-Soot/LICENSE.txt new file mode 100644 index 00000000..e23ece2c --- /dev/null +++ b/boomerangScope-Soot/LICENSE.txt @@ -0,0 +1,277 @@ +Eclipse Public License - v 2.0 + + THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE + PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION + OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. + +1. DEFINITIONS + +"Contribution" means: + + a) in the case of the initial Contributor, the initial content + Distributed under this Agreement, and + + b) in the case of each subsequent Contributor: + i) changes to the Program, and + ii) additions to the Program; + where such changes and/or additions to the Program originate from + and are Distributed by that particular Contributor. A Contribution + "originates" from a Contributor if it was added to the Program by + such Contributor itself or anyone acting on such Contributor's behalf. + Contributions do not include changes or additions to the Program that + are not Modified Works. + +"Contributor" means any person or entity that Distributes the Program. + +"Licensed Patents" mean patent claims licensable by a Contributor which +are necessarily infringed by the use or sale of its Contribution alone +or when combined with the Program. + +"Program" means the Contributions Distributed in accordance with this +Agreement. + +"Recipient" means anyone who receives the Program under this Agreement +or any Secondary License (as applicable), including Contributors. + +"Derivative Works" shall mean any work, whether in Source Code or other +form, that is based on (or derived from) the Program and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. + +"Modified Works" shall mean any work in Source Code or other form that +results from an addition to, deletion from, or modification of the +contents of the Program, including, for purposes of clarity any new file +in Source Code form that contains any contents of the Program. Modified +Works shall not include works that contain only declarations, +interfaces, types, classes, structures, or files of the Program solely +in each case in order to link to, bind by name, or subclass the Program +or Modified Works thereof. + +"Distribute" means the acts of a) distributing or b) making available +in any manner that enables the transfer of a copy. + +"Source Code" means the form of a Program preferred for making +modifications, including but not limited to software source code, +documentation source, and configuration files. + +"Secondary License" means either the GNU General Public License, +Version 2.0, or any later versions of that license, including any +exceptions or additional permissions as identified by the initial +Contributor. + +2. GRANT OF RIGHTS + + a) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free copyright + license to reproduce, prepare Derivative Works of, publicly display, + publicly perform, Distribute and sublicense the Contribution of such + Contributor, if any, and such Derivative Works. + + b) Subject to the terms of this Agreement, each Contributor hereby + grants Recipient a non-exclusive, worldwide, royalty-free patent + license under Licensed Patents to make, use, sell, offer to sell, + import and otherwise transfer the Contribution of such Contributor, + if any, in Source Code or other form. This patent license shall + apply to the combination of the Contribution and the Program if, at + the time the Contribution is added by the Contributor, such addition + of the Contribution causes such combination to be covered by the + Licensed Patents. The patent license shall not apply to any other + combinations which include the Contribution. No hardware per se is + licensed hereunder. + + c) Recipient understands that although each Contributor grants the + licenses to its Contributions set forth herein, no assurances are + provided by any Contributor that the Program does not infringe the + patent or other intellectual property rights of any other entity. + Each Contributor disclaims any liability to Recipient for claims + brought by any other entity based on infringement of intellectual + property rights or otherwise. As a condition to exercising the + rights and licenses granted hereunder, each Recipient hereby + assumes sole responsibility to secure any other intellectual + property rights needed, if any. For example, if a third party + patent license is required to allow Recipient to Distribute the + Program, it is Recipient's responsibility to acquire that license + before distributing the Program. + + d) Each Contributor represents that to its knowledge it has + sufficient copyright rights in its Contribution, if any, to grant + the copyright license set forth in this Agreement. + + e) Notwithstanding the terms of any Secondary License, no + Contributor makes additional grants to any Recipient (other than + those set forth in this Agreement) as a result of such Recipient's + receipt of the Program under the terms of a Secondary License + (if permitted under the terms of Section 3). + +3. REQUIREMENTS + +3.1 If a Contributor Distributes the Program in any form, then: + + a) the Program must also be made available as Source Code, in + accordance with section 3.2, and the Contributor must accompany + the Program with a statement that the Source Code for the Program + is available under this Agreement, and informs Recipients how to + obtain it in a reasonable manner on or through a medium customarily + used for software exchange; and + + b) the Contributor may Distribute the Program under a license + different than this Agreement, provided that such license: + i) effectively disclaims on behalf of all other Contributors all + warranties and conditions, express and implied, including + warranties or conditions of title and non-infringement, and + implied warranties or conditions of merchantability and fitness + for a particular purpose; + + ii) effectively excludes on behalf of all other Contributors all + liability for damages, including direct, indirect, special, + incidental and consequential damages, such as lost profits; + + iii) does not attempt to limit or alter the recipients' rights + in the Source Code under section 3.2; and + + iv) requires any subsequent distribution of the Program by any + party to be under a license that satisfies the requirements + of this section 3. + +3.2 When the Program is Distributed as Source Code: + + a) it must be made available under this Agreement, or if the + Program (i) is combined with other material in a separate file or + files made available under a Secondary License, and (ii) the initial + Contributor attached to the Source Code the notice described in + Exhibit A of this Agreement, then the Program may be made available + under the terms of such Secondary Licenses, and + + b) a copy of this Agreement must be included with each copy of + the Program. + +3.3 Contributors may not remove or alter any copyright, patent, +trademark, attribution notices, disclaimers of warranty, or limitations +of liability ("notices") contained within the Program from any copy of +the Program which they Distribute, provided that Contributors may add +their own appropriate notices. + +4. COMMERCIAL DISTRIBUTION + +Commercial distributors of software may accept certain responsibilities +with respect to end users, business partners and the like. While this +license is intended to facilitate the commercial use of the Program, +the Contributor who includes the Program in a commercial product +offering should do so in a manner which does not create potential +liability for other Contributors. Therefore, if a Contributor includes +the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and indemnify every +other Contributor ("Indemnified Contributor") against any losses, +damages and costs (collectively "Losses") arising from claims, lawsuits +and other legal actions brought by a third party against the Indemnified +Contributor to the extent caused by the acts or omissions of such +Commercial Contributor in connection with its distribution of the Program +in a commercial product offering. The obligations in this section do not +apply to any claims or Losses relating to any actual or alleged +intellectual property infringement. In order to qualify, an Indemnified +Contributor must: a) promptly notify the Commercial Contributor in +writing of such claim, and b) allow the Commercial Contributor to control, +and cooperate with the Commercial Contributor in, the defense and any +related settlement negotiations. The Indemnified Contributor may +participate in any such claim at its own expense. + +For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those performance +claims and warranties, and if a court requires any other Contributor to +pay any damages as a result, the Commercial Contributor must pay +those damages. + +5. NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing the Program and assumes all +risks associated with its exercise of rights under this Agreement, +including but not limited to the risks and costs of program errors, +compliance with applicable laws, damage to or loss of data, programs +or equipment, and unavailability or interruption of operations. + +6. DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT +PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST +PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +7. GENERAL + +If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further +action by the parties hereto, such provision shall be reformed to the +minimum extent necessary to make such provision valid and enforceable. + +If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other software +or hardware) infringes such Recipient's patent(s), then such Recipient's +rights granted under Section 2(b) shall terminate as of the date such +litigation is filed. + +All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of +time after becoming aware of such noncompliance. If all Recipient's +rights under this Agreement terminate, Recipient agrees to cease use +and distribution of the Program as soon as reasonably practicable. +However, Recipient's obligations under this Agreement and any licenses +granted by Recipient relating to the Program shall continue and survive. + +Everyone is permitted to copy and distribute copies of this Agreement, +but in order to avoid inconsistency the Agreement is copyrighted and +may only be modified in the following manner. The Agreement Steward +reserves the right to publish new versions (including revisions) of +this Agreement from time to time. No one other than the Agreement +Steward has the right to modify this Agreement. The Eclipse Foundation +is the initial Agreement Steward. The Eclipse Foundation may assign the +responsibility to serve as the Agreement Steward to a suitable separate +entity. Each new version of the Agreement will be given a distinguishing +version number. The Program (including Contributions) may always be +Distributed subject to the version of the Agreement under which it was +received. In addition, after a new version of the Agreement is published, +Contributor may elect to Distribute the Program (including its +Contributions) under the new version. + +Except as expressly stated in Sections 2(a) and 2(b) above, Recipient +receives no rights or licenses to the intellectual property of any +Contributor under this Agreement, whether expressly, by implication, +estoppel or otherwise. All rights in the Program not expressly granted +under this Agreement are reserved. Nothing in this Agreement is intended +to be enforceable by any entity that is not a Contributor or Recipient. +No third-party beneficiary rights are created under this Agreement. + +Exhibit A - Form of Secondary Licenses Notice + +"This Source Code may also be made available under the following +Secondary Licenses when the conditions for such availability set forth +in the Eclipse Public License, v. 2.0 are satisfied: {name license(s), +version(s), and exceptions or additional permissions here}." + + Simply including a copy of this Agreement, including this Exhibit A + is not sufficient to license the Source Code under Secondary Licenses. + + If it is not possible or desirable to put the notice in a particular + file, then You may include the notice in a location (such as a LICENSE + file in a relevant directory) where a recipient would be likely to + look for such a notice. + + You may add additional accurate notices of copyright ownership. \ No newline at end of file diff --git a/boomerangScope-Soot/pom.xml b/boomerangScope-Soot/pom.xml new file mode 100644 index 00000000..dca5105d --- /dev/null +++ b/boomerangScope-Soot/pom.xml @@ -0,0 +1,26 @@ + + + de.fraunhofer.iem + SPDS + 3.2.3 + ../pom.xml + + 4.0.0 + boomerangScope-Soot + + + org.soot-oss + soot + 4.5.0 + + + junit + junit + + + de.fraunhofer.iem + boomerangScope + + + \ No newline at end of file diff --git a/boomerangScope/src/main/java/boomerang/scene/SootDataFlowScope.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootDataFlowScopeUtil.java similarity index 90% rename from boomerangScope/src/main/java/boomerang/scene/SootDataFlowScope.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootDataFlowScopeUtil.java index 9005f73b..5ebb516c 100644 --- a/boomerangScope/src/main/java/boomerang/scene/SootDataFlowScope.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootDataFlowScopeUtil.java @@ -1,7 +1,10 @@ -package boomerang.scene; +package boomerang.framework.soot; -import boomerang.scene.jimple.JimpleDeclaredMethod; -import boomerang.scene.jimple.JimpleMethod; +import boomerang.framework.soot.jimple.JimpleDeclaredMethod; +import boomerang.framework.soot.jimple.JimpleMethod; +import boomerang.scene.DataFlowScope; +import boomerang.scene.DeclaredMethod; +import boomerang.scene.Method; import com.google.common.base.Predicate; import com.google.common.collect.Sets; import java.util.List; @@ -14,8 +17,8 @@ import soot.SootMethod; import soot.util.queue.QueueReader; -public class SootDataFlowScope { - private static final Logger LOGGER = LoggerFactory.getLogger(SootDataFlowScope.class); +public class SootDataFlowScopeUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(SootDataFlowScopeUtil.class); private static final String HASH_CODE_SUB_SIG = "int hashCode()"; private static final String TO_STRING_SUB_SIG = "java.lang.String toString()"; private static final String EQUALS_SUB_SIG = "boolean equals(java.lang.Object)"; @@ -49,7 +52,7 @@ public boolean isExcluded(Method method) { * Excludes hashCode, toString, equals methods and the implementors of java.util.Collection, * java.util.Maps and com.google.common.collect.Multimap */ - public static DataFlowScope excludeComplex(Scene scene) { + public static DataFlowScope excludeComplex() { reset(); return new DataFlowScope() { @Override @@ -88,7 +91,7 @@ public boolean isExcluded(Method method) { private static class MapFilter implements Predicate { private static final String MAP = "java.util.Map"; private static final String GUAVA_MAP = "com.google.common.collect.Multimap"; - private Set excludes = Sets.newHashSet(); + private final Set excludes = Sets.newHashSet(); public MapFilter() { List mapSubClasses = @@ -117,7 +120,7 @@ public boolean apply(SootClass c) { private static class IterableFilter implements Predicate { private static final String ITERABLE = "java.lang.Iterable"; - private Set excludes = Sets.newHashSet(); + private final Set excludes = Sets.newHashSet(); public IterableFilter() { List iterableSubClasses = @@ -138,7 +141,7 @@ public boolean apply(SootClass c) { } private static class SubSignatureFilter implements Predicate { - private Set excludes = Sets.newHashSet(); + private final Set excludes = Sets.newHashSet(); public SubSignatureFilter(String subSig) { QueueReader l = Scene.v().getReachableMethods().listener(); diff --git a/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootFrameworkScope.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootFrameworkScope.java new file mode 100644 index 00000000..6118d722 --- /dev/null +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootFrameworkScope.java @@ -0,0 +1,70 @@ +package boomerang.framework.soot; + +import boomerang.framework.soot.jimple.*; +import boomerang.scene.*; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import soot.*; +import soot.jimple.IntConstant; + +public class SootFrameworkScope implements FrameworkScope { + + @Nonnull private final SootCallGraph sootCallGraph; + + public SootFrameworkScope() { + sootCallGraph = new SootCallGraph(); + getEntrypoints().forEach(sootCallGraph::addEntryPoint); + } + + @Override + public List getEntrypoints() { + return Scene.v().getEntryPoints().stream().map(JimpleMethod::of).collect(Collectors.toList()); + } + + @Override + public Val getTrueValue(Method m) { + return new JimpleVal(IntConstant.v(1), m); + } + + @Override + public Val getFalseValue(Method m) { + return new JimpleVal(IntConstant.v(0), m); + } + + @Override + public Stream handleStaticFieldInitializers(Val fact) { + JimpleStaticFieldVal val = ((JimpleStaticFieldVal) fact); + return ((JimpleField) val.field()) + .getSootField().getDeclaringClass().getMethods().stream() + .filter(SootMethod::hasActiveBody) + .map(JimpleMethod::of); + } + + @Override + public StaticFieldVal newStaticFieldVal(Field field, Method m) { + return new JimpleStaticFieldVal((JimpleField) field, m); + } + + @Nonnull + @Override + public Method getMethod(String signatureStr) { + return JimpleMethod.of(Scene.v().getMethod(signatureStr)); + } + + @Override + public CallGraph getCallGraph() { + return sootCallGraph; + } + + @Override + public DataFlowScope getDataFlowScope() { + return SootDataFlowScopeUtil.make(Scene.v()); + } + + @Override + public DataFlowScope createDataFlowScopeWithoutComplex() { + return SootDataFlowScopeUtil.excludeComplex(); + } +} diff --git a/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootTestFactory.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootTestFactory.java new file mode 100644 index 00000000..362c55b0 --- /dev/null +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/SootTestFactory.java @@ -0,0 +1,77 @@ +package boomerang.framework.soot; + +import soot.SootMethod; + +public class SootTestFactory { + + protected SootMethod sootTestMethod; + + /* FIXME + protected abstract SceneTransformer createAnalysisTransformer(); + + // implementation from: IDEALTestingFacory + protected SceneTransformer createAnalysisTransformer(SootMethod sootTestMethod) throws ImprecisionException { + return new SceneTransformer() { + protected void internalTransform( + String phaseName, @SuppressWarnings("rawtypes") Map options) { + BoomerangPretransformer.v().reset(); + BoomerangPretransformer.v().apply(); + callGraph = new SootCallGraph(); + dataFlowScope = SootDataFlowScope.make(Scene.v()); + analyze(JimpleMethod.of(sootTestMethod)); + } + }; + } + + + // TODO: (from AbstractTestFactory) + protected String getSootClassPath() { + String userdir = System.getProperty("user.dir"); + String javaHome = System.getProperty("java.home"); + if (javaHome == null || javaHome.equals("")) + throw new RuntimeException("Could not get property java.home!"); + + String sootCp = userdir + "/target/test-classes"; + if (getJavaVersion() < 9) { + sootCp += File.pathSeparator + javaHome + "/lib/rt.jar"; + sootCp += File.pathSeparator + javaHome + "/lib/jce.jar"; + } + return sootCp; + } + + private String getTargetClass() { + SootClass sootClass = new SootClass("dummyClass"); + Type paramType = ArrayType.v(RefType.v("java.lang.String"), 1); + SootMethod mainMethod = + new SootMethod( + "main", + Collections.singletonList(paramType), + VoidType.v(), + Modifier.PUBLIC | Modifier.STATIC); + sootClass.addMethod(mainMethod); + JimpleBody body = Jimple.v().newBody(mainMethod); + mainMethod.setActiveBody(body); + RefType testCaseType = RefType.v(getTestCaseClassName()); + Local loc = Jimple.v().newLocal("l0", paramType); + body.getLocals().add(loc); + body.getUnits().add(Jimple.v().newIdentityStmt(loc, Jimple.v().newParameterRef(paramType, 0))); + Local allocatedTestObj = Jimple.v().newLocal("dummyObj", testCaseType); + body.getLocals().add(allocatedTestObj); + body.getUnits() + .add(Jimple.v().newAssignStmt(allocatedTestObj, Jimple.v().newNewExpr(testCaseType))); + body.getUnits() + .add( + Jimple.v() + .newInvokeStmt( + Jimple.v().newVirtualInvokeExpr(allocatedTestObj, sootTestMethod.makeRef()))); + body.getUnits().add(Jimple.v().newReturnVoidStmt()); + + Scene.v().addClass(sootClass); + body.validate(); + return sootClass.toString(); + } + + + */ + +} diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/BoomerangPretransformer.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/BoomerangPretransformer.java similarity index 98% rename from boomerangScope/src/main/java/boomerang/scene/jimple/BoomerangPretransformer.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/BoomerangPretransformer.java index ccbea231..fdbb1829 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/BoomerangPretransformer.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/BoomerangPretransformer.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import com.google.common.collect.Sets; import java.util.AbstractMap; @@ -231,8 +231,8 @@ private Set getStmtsWithConstants(Body methodBody) { } } if (u instanceof ReturnStmt) { - ReturnStmt assignStmt = (ReturnStmt) u; - if (assignStmt.getOp() instanceof Constant) { + ReturnStmt returnStmt = (ReturnStmt) u; + if (returnStmt.getOp() instanceof Constant) { retMap.add(u); } } diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/ExplicitNullifyFields.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/ExplicitNullifyFields.java similarity index 97% rename from boomerangScope/src/main/java/boomerang/scene/jimple/ExplicitNullifyFields.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/ExplicitNullifyFields.java index c485375b..29864efa 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/ExplicitNullifyFields.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/ExplicitNullifyFields.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import com.google.common.collect.Sets; import java.util.Set; diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleControlFlowGraph.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleControlFlowGraph.java similarity index 98% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleControlFlowGraph.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleControlFlowGraph.java index 180729e7..62b26dd1 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleControlFlowGraph.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleControlFlowGraph.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.ControlFlowGraph; import boomerang.scene.Statement; diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDeclaredMethod.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDeclaredMethod.java similarity index 89% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDeclaredMethod.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDeclaredMethod.java index f8e280e8..1697b56c 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDeclaredMethod.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDeclaredMethod.java @@ -1,7 +1,8 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.DeclaredMethod; import boomerang.scene.InvokeExpr; +import boomerang.scene.Method; import boomerang.scene.Type; import boomerang.scene.WrappedClass; import java.util.ArrayList; @@ -57,9 +58,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleDeclaredMethod other = (JimpleDeclaredMethod) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override @@ -72,6 +72,11 @@ public String getSignature() { return delegate.getSignature(); } + @Override + public Method getCalledMethod() { + return JimpleMethod.of(delegate); + } + @Override public WrappedClass getDeclaringClass() { return new JimpleWrappedClass(delegate.getDeclaringClass()); diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDoubleVal.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDoubleVal.java similarity index 85% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDoubleVal.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDoubleVal.java index dc7a8388..3d76a854 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleDoubleVal.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleDoubleVal.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.Method; import boomerang.scene.Val; @@ -37,8 +37,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleDoubleVal other = (JimpleDoubleVal) obj; if (falseVariable == null) { - if (other.falseVariable != null) return false; - } else if (!falseVariable.equals(other.falseVariable)) return false; - return true; + return other.falseVariable == null; + } else return falseVariable.equals(other.falseVariable); } } diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleField.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleField.java similarity index 87% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleField.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleField.java index 83cc0bda..1b953f17 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleField.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleField.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.Field; import soot.SootField; @@ -24,7 +24,7 @@ public JimpleField(SootField delegate) { @Override public String toString() { - return delegate.getName().toString(); + return delegate.getName(); } public SootField getSootField() { @@ -46,9 +46,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleField other = (JimpleField) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleIfStatement.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleIfStatement.java similarity index 94% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleIfStatement.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleIfStatement.java index e5a6e3aa..7219dd34 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleIfStatement.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleIfStatement.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.IfStatement; import boomerang.scene.Method; @@ -14,8 +14,8 @@ public class JimpleIfStatement implements IfStatement { - private IfStmt delegate; - private Method method; + private final IfStmt delegate; + private final Method method; public JimpleIfStatement(IfStmt delegate, Method method) { this.delegate = delegate; @@ -24,7 +24,7 @@ public JimpleIfStatement(IfStmt delegate, Method method) { @Override public Statement getTarget() { - return JimpleStatement.create(delegate.getTarget(), (JimpleMethod) method); + return JimpleStatement.create(delegate.getTarget(), method); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInstanceFieldRef.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInstanceFieldRef.java similarity index 78% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInstanceFieldRef.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInstanceFieldRef.java index cf69f182..e3beee86 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInstanceFieldRef.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInstanceFieldRef.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.Field; import boomerang.scene.InstanceFieldRef; @@ -6,8 +6,8 @@ public class JimpleInstanceFieldRef implements InstanceFieldRef { - private soot.jimple.InstanceFieldRef delegate; - private JimpleMethod m; + private final soot.jimple.InstanceFieldRef delegate; + private final JimpleMethod m; public JimpleInstanceFieldRef(soot.jimple.InstanceFieldRef ifr, JimpleMethod m) { this.delegate = ifr; diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInvokeExpr.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInvokeExpr.java similarity index 92% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInvokeExpr.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInvokeExpr.java index 92102b17..4a6514cb 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleInvokeExpr.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleInvokeExpr.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.DeclaredMethod; import boomerang.scene.InvokeExpr; @@ -13,8 +13,8 @@ public class JimpleInvokeExpr implements InvokeExpr { - private soot.jimple.InvokeExpr delegate; - private Method m; + private final soot.jimple.InvokeExpr delegate; + private final Method m; private ArrayList cache; public JimpleInvokeExpr(soot.jimple.InvokeExpr ive, Method m) { diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleMethod.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleMethod.java similarity index 93% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleMethod.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleMethod.java index a7391f42..0817e0e2 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleMethod.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleMethod.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.ControlFlowGraph; import boomerang.scene.Method; @@ -18,7 +18,8 @@ import soot.util.Chain; public class JimpleMethod extends Method { - private SootMethod delegate; + + private final SootMethod delegate; protected static Interner INTERNAL_POOL = Interners.newWeakInterner(); protected ControlFlowGraph cfg; @@ -28,7 +29,8 @@ public class JimpleMethod extends Method { protected JimpleMethod(SootMethod m) { this.delegate = m; if (!m.hasActiveBody()) { - throw new RuntimeException("Building a Jimple method without active body present"); + throw new RuntimeException( + "Building a Jimple method for " + m + " without active body present"); } } @@ -51,9 +53,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleMethod other = (JimpleMethod) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override @@ -75,6 +76,7 @@ public boolean isParameterLocal(Val val) { return parameterLocals.contains(val); } + @Override public List getParameterTypes() { List types = new ArrayList<>(); @@ -84,6 +86,7 @@ public List getParameterTypes() { return types; } + @Override public Type getParameterType(int index) { return new JimpleType(delegate.getParameterType(index)); } diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStatement.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStatement.java similarity index 99% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStatement.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStatement.java index dd0bbf3b..2eebd504 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStatement.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStatement.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.Field; import boomerang.scene.IfStatement; diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStaticFieldVal.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStaticFieldVal.java similarity index 96% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStaticFieldVal.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStaticFieldVal.java index 397161b9..1b9bae71 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleStaticFieldVal.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleStaticFieldVal.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Field; @@ -175,9 +175,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleStaticFieldVal other = (JimpleStaticFieldVal) obj; if (field == null) { - if (other.field != null) return false; - } else if (!field.equals(other.field)) return false; - return true; + return other.field == null; + } else return field.equals(other.field); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleType.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleType.java similarity index 97% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleType.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleType.java index 4acece63..1640968b 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleType.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleType.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.AllocVal; import boomerang.scene.Type; @@ -141,9 +141,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleType other = (JimpleType) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleVal.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleVal.java similarity index 95% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleVal.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleVal.java index 4cf50cf5..00e8bcb1 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleVal.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleVal.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Method; @@ -76,7 +76,7 @@ public boolean isNewExpr() { } public Type getNewExprType() { - return new JimpleType(((NewExpr) v).getType()); + return new JimpleType(v.getType()); } public Val asUnbalanced(Edge stmt) { @@ -91,10 +91,7 @@ public boolean isArrayAllocationVal() { // TODO Split this into single array and multi array allocation if (v instanceof NewArrayExpr) { return true; - } else if (v instanceof NewMultiArrayExpr) { - return true; - } - return false; + } else return v instanceof NewMultiArrayExpr; } public Val getArrayAllocationSize() { @@ -241,9 +238,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleVal other = (JimpleVal) obj; if (v == null) { - if (other.v != null) return false; - } else if (!v.equals(other.v)) return false; - return true; + return other.v == null; + } else return v.equals(other.v); } public Value getDelegate() { diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleWrappedClass.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleWrappedClass.java similarity index 90% rename from boomerangScope/src/main/java/boomerang/scene/jimple/JimpleWrappedClass.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleWrappedClass.java index df39bdac..c6b17f6b 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/JimpleWrappedClass.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/JimpleWrappedClass.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.Method; import boomerang.scene.Type; @@ -11,7 +11,7 @@ public class JimpleWrappedClass implements WrappedClass { - private SootClass delegate; + private final SootClass delegate; private Set methods; public JimpleWrappedClass(SootClass delegate) { @@ -65,9 +65,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; JimpleWrappedClass other = (JimpleWrappedClass) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/jimple/SootCallGraph.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/SootCallGraph.java similarity index 87% rename from boomerangScope/src/main/java/boomerang/scene/jimple/SootCallGraph.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/SootCallGraph.java index 91606cc3..734066e6 100644 --- a/boomerangScope/src/main/java/boomerang/scene/jimple/SootCallGraph.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/jimple/SootCallGraph.java @@ -1,4 +1,4 @@ -package boomerang.scene.jimple; +package boomerang.framework.soot.jimple; import boomerang.scene.CallGraph; import boomerang.scene.Statement; @@ -11,6 +11,7 @@ public class SootCallGraph extends CallGraph { Logger LOGGER = LoggerFactory.getLogger(SootCallGraph.class); public SootCallGraph() { + soot.jimple.toolkits.callgraph.CallGraph callGraph = Scene.v().getCallGraph(); for (soot.jimple.toolkits.callgraph.Edge e : callGraph) { if (e.src().hasActiveBody() && e.tgt().hasActiveBody() && e.srcStmt() != null) { @@ -24,5 +25,9 @@ public SootCallGraph() { for (SootMethod m : Scene.v().getEntryPoints()) { if (m.hasActiveBody()) this.addEntryPoint(JimpleMethod.of(m)); } + + if (getEdges().isEmpty()) { + throw new IllegalStateException("CallGraph is empty!"); + } } } diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/SootAdapter.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SootAdapter.java similarity index 90% rename from boomerangScope/src/main/java/boomerang/scene/sparse/SootAdapter.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SootAdapter.java index 88f56cf8..0cdb0f69 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/SootAdapter.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SootAdapter.java @@ -1,11 +1,11 @@ -package boomerang.scene.sparse; +package boomerang.framework.soot.sparse; +import boomerang.framework.soot.jimple.*; +import boomerang.framework.soot.sparse.aliasaware.MStaticFieldRef; import boomerang.scene.Field; import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.jimple.*; -import boomerang.scene.sparse.aliasaware.MStaticFieldRef; import soot.*; import soot.jimple.StaticFieldRef; import soot.jimple.Stmt; diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGBuilder.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SparseCFGBuilder.java similarity index 78% rename from boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGBuilder.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SparseCFGBuilder.java index 546509d0..1467d32b 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGBuilder.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/SparseCFGBuilder.java @@ -1,4 +1,4 @@ -package boomerang.scene.sparse; +package boomerang.framework.soot.sparse; import com.google.common.graph.GraphBuilder; import com.google.common.graph.MutableGraph; @@ -17,7 +17,7 @@ public class SparseCFGBuilder { protected Map unitToNumber = new HashMap<>(); - protected MutableGraph numberStmtsAndConvertToMutableGraph(DirectedGraph rawGraph) { + public MutableGraph numberStmtsAndConvertToMutableGraph(DirectedGraph rawGraph) { MutableGraph mGraph = GraphBuilder.directed().build(); List heads = rawGraph.getHeads(); for (Unit head : heads) { @@ -26,7 +26,7 @@ protected MutableGraph numberStmtsAndConvertToMutableGraph(DirectedGraph graph, Unit curr, MutableGraph mutableGraph, int depth) { Integer num = unitToNumber.get(curr); if (num == null || num < depth) { @@ -48,7 +48,7 @@ protected void convertToMutableGraph( * @param graph * @return */ - protected Unit getHead(DirectedGraph graph) { + public Unit getHead(DirectedGraph graph) { List heads = graph.getHeads(); List res = new ArrayList<>(); for (Unit head : heads) { @@ -63,19 +63,19 @@ protected Unit getHead(DirectedGraph graph) { return res.get(0); } - protected Iterator getBFSIterator(MutableGraph graph, Unit head) { + public Iterator getBFSIterator(MutableGraph graph, Unit head) { Traverser traverser = Traverser.forGraph(graph); return traverser.breadthFirst(head).iterator(); } - protected void logCFG(Logger logger, MutableGraph graph) { + public void logCFG(Logger logger, MutableGraph graph) { logger.info( graph.nodes().stream() .map(Objects::toString) .collect(Collectors.joining(System.lineSeparator()))); } - protected boolean isControlStmt(Unit stmt) { + public boolean isControlStmt(Unit stmt) { if (stmt instanceof JIfStmt || stmt instanceof JNopStmt || stmt instanceof JGotoStmt @@ -83,16 +83,13 @@ protected boolean isControlStmt(Unit stmt) { || stmt instanceof JReturnVoidStmt) { return true; } - if (stmt instanceof JIdentityStmt) { - // JIdentityStmt id = (JIdentityStmt) stmt; - // if (id.getRightOp() instanceof JCaughtExceptionRef) { - return true; - // } - } - return false; + // JIdentityStmt id = (JIdentityStmt) stmt; + // if (id.getRightOp() instanceof JCaughtExceptionRef) { + // } + return stmt instanceof JIdentityStmt; } - protected void removeStmt(MutableGraph mCFG, Unit unit) { + public void removeStmt(MutableGraph mCFG, Unit unit) { Set preds = mCFG.predecessors(unit); List tmpPreds = new ArrayList<>(); preds.forEach(e -> tmpPreds.add(e)); diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGBuilder.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGBuilder.java similarity index 93% rename from boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGBuilder.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGBuilder.java index 4d23850f..7006c06f 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGBuilder.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGBuilder.java @@ -1,11 +1,9 @@ -package boomerang.scene.sparse.aliasaware; +package boomerang.framework.soot.sparse.aliasaware; +import boomerang.framework.soot.sparse.SootAdapter; +import boomerang.framework.soot.sparse.SparseCFGBuilder; import boomerang.scene.Pair; import boomerang.scene.Val; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGBuilder; -import boomerang.scene.sparse.eval.SparseCFGQueryLog; import com.google.common.graph.MutableGraph; import java.util.*; import java.util.logging.Logger; @@ -17,6 +15,8 @@ import soot.jimple.internal.*; import soot.toolkits.graph.BriefUnitGraph; import soot.toolkits.graph.DirectedGraph; +import sparse.SparseAliasingCFG; +import sparse.eval.SparseCFGQueryLog; /** Value is the type of DFF */ public class AliasAwareSparseCFGBuilder extends SparseCFGBuilder { @@ -34,8 +34,8 @@ public class AliasAwareSparseCFGBuilder extends SparseCFGBuilder { private static final Logger LOGGER = Logger.getLogger(AliasAwareSparseCFGBuilder.class.getName()); - private boolean enableExceptions; - private boolean ignoreAfterQuery; + private final boolean enableExceptions; + private final boolean ignoreAfterQuery; public AliasAwareSparseCFGBuilder(boolean enableExceptions, boolean ignoreAfterQuery) { this.enableExceptions = enableExceptions; @@ -216,9 +216,7 @@ private void forwardPass(MutableGraph mCFG, Unit queryStmt) { } private boolean isDebugTarget() { - return false - && currentMethod.getName().equals("main") - && queryStmt.toString().startsWith("b_q1"); + return false; } private void logStackOp(Value val, String op) { @@ -461,10 +459,7 @@ private boolean keepContainingStmtsForward(Unit unit, Value queryVar) { return true; } } - if (keepInvokeForValue(unit, queryVar)) { - return true; - } - return false; + return keepInvokeForValue(unit, queryVar); } /** @@ -478,9 +473,7 @@ private boolean keepContainingStmtsForward(Unit unit, Value queryVar) { private boolean equalsQueryBase(Value rightOp, Value queryVar) { if (queryVar instanceof JInstanceFieldRef) { Value queryBase = ((JInstanceFieldRef) queryVar).getBase(); - if (queryBase.equals(rightOp)) { - return true; - } + return queryBase.equals(rightOp); } return false; } @@ -489,9 +482,7 @@ private boolean equalsInitialFieldType(Value op, Value queryVar) { if (op instanceof JInstanceFieldRef) { Value base = ((JInstanceFieldRef) op).getBase(); Type fieldType = ((JInstanceFieldRef) op).getField().getType(); - if (base.equals(queryVar) && fieldType.equals(queryVarType)) { - return true; - } + return base.equals(queryVar) && fieldType.equals(queryVarType); } return false; } @@ -508,9 +499,7 @@ private boolean equalsFieldType(Value op, Value queryVar) { if (op instanceof JInstanceFieldRef) { Value base = ((JInstanceFieldRef) op).getBase(); Type fieldType = ((JInstanceFieldRef) op).getField().getType(); - if (base.equals(queryVar) && fieldType.equals(queryVar.getType())) { - return true; - } + return base.equals(queryVar) && fieldType.equals(queryVar.getType()); } return false; } @@ -588,14 +577,10 @@ private boolean keepInvokeForValue(Unit unit, Value d) { private boolean isInvokeBase(Value d, InvokeExpr invokeExpr) { if (invokeExpr instanceof JVirtualInvokeExpr) { Value base = ((JVirtualInvokeExpr) invokeExpr).getBase(); - if (d.equals(base)) { - return true; - } + return d.equals(base); } else if (invokeExpr instanceof JSpecialInvokeExpr) { Value base = ((JSpecialInvokeExpr) invokeExpr).getBase(); - if (d.equals(base)) { - return true; - } + return d.equals(base); } return false; } @@ -605,17 +590,13 @@ private boolean isAllocOrMethodAssignment(JAssignStmt stmt, Value d) { if (rightOp instanceof JNewExpr) { JNewExpr newExpr = (JNewExpr) rightOp; Type type = newExpr.getType(); - if (type.equals(d.getType())) { - return true; - } - } else if (rightOp instanceof JSpecialInvokeExpr - || rightOp instanceof JStaticInvokeExpr - || rightOp instanceof JVirtualInvokeExpr - || rightOp instanceof JInterfaceInvokeExpr - || rightOp instanceof JDynamicInvokeExpr) { - return true; - } - return false; + return type.equals(d.getType()); + } else + return rightOp instanceof JSpecialInvokeExpr + || rightOp instanceof JStaticInvokeExpr + || rightOp instanceof JVirtualInvokeExpr + || rightOp instanceof JInterfaceInvokeExpr + || rightOp instanceof JDynamicInvokeExpr; } /** diff --git a/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGCache.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGCache.java new file mode 100644 index 00000000..6ab5679f --- /dev/null +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/AliasAwareSparseCFGCache.java @@ -0,0 +1,213 @@ +package boomerang.framework.soot.sparse.aliasaware; + +import boomerang.framework.soot.jimple.JimpleMethod; +import boomerang.framework.soot.jimple.JimpleStatement; +import boomerang.framework.soot.sparse.SootAdapter; +import boomerang.scene.Statement; +import boomerang.scene.Val; +import java.util.*; +import soot.SootMethod; +import soot.jimple.Stmt; +import sparse.SparseAliasingCFG; +import sparse.SparseCFGCache; +import sparse.eval.SparseCFGQueryLog; + +public class AliasAwareSparseCFGCache implements SparseCFGCache { + + List logList = new ArrayList<>(); + + Map cache; + AliasAwareSparseCFGBuilder sparseCFGBuilder; + + private static AliasAwareSparseCFGCache INSTANCE; + private static boolean ignore; + + private AliasAwareSparseCFGCache() {} + + public static AliasAwareSparseCFGCache getInstance(boolean ignoreAfterQuery) { + if (INSTANCE == null || ignore != ignoreAfterQuery) { + ignore = ignoreAfterQuery; + INSTANCE = + new AliasAwareSparseCFGCache(new AliasAwareSparseCFGBuilder(true, ignoreAfterQuery)); + } + return INSTANCE; + } + + private AliasAwareSparseCFGCache(AliasAwareSparseCFGBuilder sparseCFGBuilder) { + this.cache = new HashMap<>(); + this.sparseCFGBuilder = sparseCFGBuilder; + } + + // TODO: unify in super + @Override + public SparseAliasingCFG getSparseCFGForForwardPropagation( + JimpleMethod m, JimpleStatement stmt, Val val) { + // TODO: [ms] check that loop - seems expensive + for (CacheKey s : cache.keySet()) { + // TODO: [ms] check refactoring! possibly: getName() is different than getName() + if (s.getSignature().equals(m.getName())) { + SparseAliasingCFG sparseAliasingCFG = cache.get(s); + if (sparseAliasingCFG.getGraph().nodes().contains(stmt)) { + SparseCFGQueryLog queryLog = + new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.FWD); + logList.add(queryLog); + return sparseAliasingCFG; + } + } + } + SparseCFGQueryLog queryLog = new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.FWD); + logList.add(queryLog); + // throw new RuntimeException("CFG not found for:" + m + " s:" + stmt); + return null; + } + + @Override + public synchronized SparseAliasingCFG getSparseCFGForBackwardPropagation( + Val initialQueryVal, + JimpleStatement initialQueryStmt, + JimpleMethod currentMethod, + Val currentVal, + JimpleStatement currentStmt) { + + // Value sootInitialQueryVal = SootAdapter.asValue(initialQueryVal); + // Value sootCurrentQueryVal = SootAdapter.asValue(currentVal); + + // TODO: [ms] necessary? + SootMethod sootCurrentMethod = SootAdapter.asSootMethod(currentMethod); + Stmt sootInitialQueryStmt = SootAdapter.asStmt(initialQueryStmt); + Stmt sootCurrentStmt = SootAdapter.asStmt(currentStmt); + + CacheKey key = new CacheKeyImpl(currentMethod, initialQueryVal, initialQueryStmt); + SparseAliasingCFG sparseAliasingCFG = cache.get(key); + if (sparseAliasingCFG != null) { + if (sparseAliasingCFG.getGraph().nodes().contains(sootCurrentStmt)) { + SparseCFGQueryLog queryLog = + new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.BWD); + logList.add(queryLog); + return sparseAliasingCFG; + } else { + SparseCFGQueryLog queryLog = + new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.BWD); + queryLog.logStart(); + SparseAliasingCFG cfg = + sparseCFGBuilder.buildSparseCFG( + initialQueryVal, sootCurrentMethod, currentVal, sootCurrentStmt, queryLog); + queryLog.logEnd(); + cache.put(new ChainedCacheKeyImpl(key, currentStmt), cfg); + logList.add(queryLog); + return cfg; + } + } + + key = new ChainedCacheKeyImpl(key, currentStmt); + sparseAliasingCFG = cache.get(key); + if (sparseAliasingCFG != null) { + SparseCFGQueryLog queryLog = + new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.BWD); + logList.add(queryLog); + return sparseAliasingCFG; + } + + SparseCFGQueryLog queryLog = new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.BWD); + queryLog.logStart(); + SparseAliasingCFG cfg = + sparseCFGBuilder.buildSparseCFG( + initialQueryVal, sootCurrentMethod, currentVal, sootCurrentStmt, queryLog); + queryLog.logEnd(); + cache.put(key, cfg); + logList.add(queryLog); + return cfg; + } + + @Override + public List getQueryLogs() { + return logList; + } + + private interface CacheKey { + Statement getQueryStmt(); + + JimpleMethod getSignature(); + + Val getInitialQueryVal(); + } + + private static class ChainedCacheKeyImpl implements CacheKey { + private final CacheKey previousKey; + private final Statement queryStmt; + + private ChainedCacheKeyImpl(CacheKey previousKey, Statement queryStmt) { + this.previousKey = previousKey; + this.queryStmt = queryStmt; + } + + public Statement getQueryStmt() { + return queryStmt; + } + + public JimpleMethod getSignature() { + return previousKey.getSignature(); + } + + public Val getInitialQueryVal() { + return previousKey.getInitialQueryVal(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CacheKey)) { + return false; + } + CacheKey obj1 = (CacheKey) obj; + return getSignature().equals(obj1.getSignature()) + && getQueryStmt().equals(obj1.getQueryStmt()) + && getInitialQueryVal().equals(obj1.getInitialQueryVal()); + } + + @Override + public int hashCode() { + return previousKey.getSignature().hashCode(); + } + } + + private static class CacheKeyImpl implements CacheKey { + private final JimpleMethod signature; + private final Val initialQueryVal; + private final Statement queryStmt; + + public CacheKeyImpl( + JimpleMethod signature, Val initialQueryVal, Statement sootInitialQueryStmt) { + this.signature = signature; + this.initialQueryVal = initialQueryVal; + this.queryStmt = sootInitialQueryStmt; + } + + public JimpleMethod getSignature() { + return signature; + } + + public Val getInitialQueryVal() { + return initialQueryVal; + } + + public Statement getQueryStmt() { + return queryStmt; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof CacheKey)) { + return false; + } + CacheKey other = (CacheKey) obj; + return getSignature().equals(other.getSignature()) + && getQueryStmt().equals(other.getQueryStmt()) + && getInitialQueryVal().equals(other.getInitialQueryVal()); + } + + @Override + public int hashCode() { + return signature.hashCode(); + } + } +} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/DefinedOutside.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/DefinedOutside.java similarity index 90% rename from boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/DefinedOutside.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/DefinedOutside.java index a2853925..1855245f 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/DefinedOutside.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/DefinedOutside.java @@ -1,4 +1,4 @@ -package boomerang.scene.sparse.aliasaware; +package boomerang.framework.soot.sparse.aliasaware; import soot.AbstractUnit; import soot.UnitPrinter; diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/MStaticFieldRef.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/MStaticFieldRef.java similarity index 78% rename from boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/MStaticFieldRef.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/MStaticFieldRef.java index e0f82e74..4dcb48ba 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/MStaticFieldRef.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/aliasaware/MStaticFieldRef.java @@ -1,4 +1,4 @@ -package boomerang.scene.sparse.aliasaware; +package boomerang.framework.soot.sparse.aliasaware; import soot.SootFieldRef; import soot.jimple.StaticFieldRef; diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGBuilder.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGBuilder.java similarity index 93% rename from boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGBuilder.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGBuilder.java index a0c38b8a..b14a0a3d 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGBuilder.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGBuilder.java @@ -1,11 +1,9 @@ -package boomerang.scene.sparse.typebased; +package boomerang.framework.soot.sparse.typebased; +import boomerang.framework.soot.sparse.SootAdapter; +import boomerang.framework.soot.sparse.SparseCFGBuilder; +import boomerang.framework.soot.sparse.aliasaware.AliasAwareSparseCFGBuilder; import boomerang.scene.Val; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGBuilder; -import boomerang.scene.sparse.aliasaware.AliasAwareSparseCFGBuilder; -import boomerang.scene.sparse.eval.SparseCFGQueryLog; import com.google.common.graph.MutableGraph; import java.util.*; import java.util.logging.Logger; @@ -15,11 +13,13 @@ import soot.jimple.internal.*; import soot.toolkits.graph.BriefUnitGraph; import soot.toolkits.graph.DirectedGraph; +import sparse.SparseAliasingCFG; +import sparse.eval.SparseCFGQueryLog; public class TypeBasedSparseCFGBuilder extends SparseCFGBuilder { private static final Logger LOGGER = Logger.getLogger(AliasAwareSparseCFGBuilder.class.getName()); - private boolean enableExceptions; + private final boolean enableExceptions; private Deque typeWorklist; private Set containerTypes; @@ -213,14 +213,10 @@ private boolean isFieldTypeRelevant(Type queryVarType, Value value) { private boolean isInvokeBase(Type queryVarType, InvokeExpr invokeExpr) { if (invokeExpr instanceof JVirtualInvokeExpr) { Value base = ((JVirtualInvokeExpr) invokeExpr).getBase(); - if (isAssignableType(base.getType(), queryVarType)) { - return true; - } + return isAssignableType(base.getType(), queryVarType); } else if (invokeExpr instanceof JSpecialInvokeExpr) { Value base = ((JSpecialInvokeExpr) invokeExpr).getBase(); - if (isAssignableType(base.getType(), queryVarType)) { - return true; - } + return isAssignableType(base.getType(), queryVarType); } return false; } diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGCache.java b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGCache.java similarity index 84% rename from boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGCache.java rename to boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGCache.java index dafb6c88..8388df0c 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/typebased/TypeBasedSparseCFGCache.java +++ b/boomerangScope-Soot/src/main/java/boomerang/framework/soot/sparse/typebased/TypeBasedSparseCFGCache.java @@ -1,20 +1,21 @@ -package boomerang.scene.sparse.typebased; +package boomerang.framework.soot.sparse.typebased; +import boomerang.framework.soot.jimple.JimpleMethod; +import boomerang.framework.soot.sparse.SootAdapter; import boomerang.scene.Method; import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGCache; -import boomerang.scene.sparse.eval.SparseCFGQueryLog; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import soot.SootMethod; import soot.jimple.Stmt; +import sparse.SparseAliasingCFG; +import sparse.SparseCFGCache; +import sparse.eval.SparseCFGQueryLog; -public class TypeBasedSparseCFGCache implements SparseCFGCache { +public class TypeBasedSparseCFGCache implements SparseCFGCache { List logList = new ArrayList<>(); @@ -37,9 +38,11 @@ private TypeBasedSparseCFGCache(TypeBasedSparseCFGBuilder sparseCFGBuilder) { this.sparseCFGBuilder = sparseCFGBuilder; } - public SparseAliasingCFG getSparseCFGForForwardPropagation(SootMethod m, Stmt stmt, Val val) { + @Override + public SparseAliasingCFG getSparseCFGForForwardPropagation(Method m, Statement stmt, Val val) { for (String s : cache.keySet()) { - if (s.startsWith(m.getSignature())) { + // TODO: [ms] rework casting + if (s.startsWith(((JimpleMethod) m).getDelegate().getSignature())) { SparseAliasingCFG sparseAliasingCFG = cache.get(s); if (sparseAliasingCFG.getGraph().nodes().contains(stmt)) { SparseCFGQueryLog queryLog = @@ -55,6 +58,7 @@ public SparseAliasingCFG getSparseCFGForForwardPropagation(SootMethod m, Stmt st return null; } + @Override public synchronized SparseAliasingCFG getSparseCFGForBackwardPropagation( Val initialQueryVal, Statement initialQueryStmt, @@ -68,13 +72,7 @@ public synchronized SparseAliasingCFG getSparseCFGForBackwardPropagation( // Value sootInitialQueryVal = SootAdapter.asValue(initialQueryVal); // Value sootCurrentQueryVal = SootAdapter.asValue(currentVal); - String key = - new StringBuilder(sootSurrentMethod.getSignature()) - .append("-") - .append(initialQueryVal) - .append("-") - .append(sootInitialQueryStmt) - .toString(); + String key = sootSurrentMethod.getSignature() + "-" + initialQueryVal + "-" + initialQueryStmt; // currentStmt must be part of the sparseCFG that was built for the initialQueryStmt // if not we'll built another sparseCFG for the currentStmt diff --git a/boomerangScope-SootUp/pom.xml b/boomerangScope-SootUp/pom.xml new file mode 100644 index 00000000..b3108a81 --- /dev/null +++ b/boomerangScope-SootUp/pom.xml @@ -0,0 +1,117 @@ + + + 4.0.0 + + de.fraunhofer.iem + SPDS + 3.2.3 + ../pom.xml + + + boomerangScope-SootUp + + + 11 + 11 + UTF-8 + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.1.2 + + true + + + + + + + + de.fraunhofer.iem + boomerangScope + + + + + + com.github.soot-oss.SootUp + sootup.core + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.java.core + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.java.bytecode.frontend + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.callgraph + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.analysis.intraprocedural + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.analysis.interprocedural + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.interceptors + develop-SNAPSHOT + + + com.github.soot-oss.SootUp + sootup.jimple.frontend + develop-SNAPSHOT + + + + + + jitpack.io + https://jitpack.io + + + \ No newline at end of file diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/BoomerangPreInterceptor.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/BoomerangPreInterceptor.java new file mode 100644 index 00000000..d06a154e --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/BoomerangPreInterceptor.java @@ -0,0 +1,233 @@ +package boomerang.framework.sootup; + +import java.util.*; +import java.util.stream.Collectors; +import javax.annotation.Nonnull; +import sootup.core.graph.MutableStmtGraph; +import sootup.core.jimple.Jimple; +import sootup.core.jimple.basic.*; +import sootup.core.jimple.common.constant.ClassConstant; +import sootup.core.jimple.common.constant.Constant; +import sootup.core.jimple.common.expr.AbstractInstanceInvokeExpr; +import sootup.core.jimple.common.expr.AbstractInvokeExpr; +import sootup.core.jimple.common.expr.JStaticInvokeExpr; +import sootup.core.jimple.common.ref.JArrayRef; +import sootup.core.jimple.common.ref.JInstanceFieldRef; +import sootup.core.jimple.common.ref.JStaticFieldRef; +import sootup.core.jimple.common.stmt.*; +import sootup.core.model.Body; +import sootup.core.transform.BodyInterceptor; +import sootup.core.views.View; + +public class BoomerangPreInterceptor implements BodyInterceptor { + + private final boolean TRANSFORM_CONSTANTS_SETTINGS; + + private static final String LABEL = "varReplacer"; + private int replaceCounter = 0; + + public BoomerangPreInterceptor() { + this(true); + } + + public BoomerangPreInterceptor(boolean transformConstantsSettings) { + TRANSFORM_CONSTANTS_SETTINGS = transformConstantsSettings; + } + + @Override + public void interceptBody(@Nonnull Body.BodyBuilder bodyBuilder, @Nonnull View view) { + addNopStatementsToMethod(bodyBuilder); + + if (TRANSFORM_CONSTANTS_SETTINGS) { + transformConstantsAtFieldWrites(bodyBuilder); + } + } + + private void addNopStatementsToMethod(Body.BodyBuilder body) { + // Initial nop statement + JNopStmt initialNop = Jimple.newNopStmt(StmtPositionInfo.getNoStmtPositionInfo()); + MutableStmtGraph stmtGraph = body.getStmtGraph(); + stmtGraph.insertBefore(stmtGraph.getStartingStmt(), initialNop); + + // Collect if-statements + Collection ifStatements = + stmtGraph.getNodes().stream() + .filter(stmt -> stmt instanceof JIfStmt) + .map(stmt -> (JIfStmt) stmt) + .collect(Collectors.toSet()); + + // Add nop statement before each if-statement branch + for (JIfStmt ifStmt : ifStatements) { + // Branch under if-Statement: Insert after if-statement + List successors = stmtGraph.successors(ifStmt); + if (!successors.isEmpty()) { + Stmt fallsThroughSuccessor = successors.get(JIfStmt.FALSE_BRANCH_IDX); + + JNopStmt nopAfterIfStmt = Jimple.newNopStmt(ifStmt.getPositionInfo()); + stmtGraph.insertBefore(fallsThroughSuccessor, nopAfterIfStmt); + } + + // Branch for target: For if-statements, there is always exactly one target + Stmt target = successors.get(JIfStmt.TRUE_BRANCH_IDX); + JNopStmt nopBeforeTarget = Jimple.newNopStmt(target.getPositionInfo()); + stmtGraph.insertBefore(target, nopBeforeTarget); + } + } + + private void transformConstantsAtFieldWrites(Body.BodyBuilder body) { + Collection stmtsWithConstants = getStatementsWithConstants(body); + for (Stmt stmt : stmtsWithConstants) { + if (stmt instanceof JAssignStmt) { + /* Transform simple assignments to two assignment steps: + * - value = 10; + * becomes + * - varReplacer = 10; + * - value = varReplacer; + */ + JAssignStmt assignStmt = (JAssignStmt) stmt; + + LValue leftOp = assignStmt.getLeftOp(); + Value rightOp = assignStmt.getRightOp(); + + if (isFieldRef(leftOp) + && rightOp instanceof Constant + && !(rightOp instanceof ClassConstant)) { + String label = LABEL + replaceCounter++; + Local local = Jimple.newLocal(label, rightOp.getType()); + JAssignStmt newAssignStmt = Jimple.newAssignStmt(local, rightOp, stmt.getPositionInfo()); + + body.addLocal(local); + body.getStmtGraph().insertBefore(stmt, newAssignStmt); + + JAssignStmt updatedAssignStmt = + Jimple.newAssignStmt(leftOp, local, stmt.getPositionInfo()); + body.getStmtGraph().replaceNode(stmt, updatedAssignStmt); + } + } + + if (stmt.isInvokableStmt()) { + /* Extract constant arguments to new assignments + * - method(10) + * becomes + * - varReplacer = 10 + * - method(varReplacer) + */ + + InvokableStmt invStmt = stmt.asInvokableStmt(); + Optional InvokeExprOpt = invStmt.getInvokeExpr(); + + if (InvokeExprOpt.isPresent()) { + // TODO: ms: dont use in production?! + if (!stmt.toString().contains("test.assertions.Assertions:") + && !stmt.toString().contains("intQueryFor")) { + + List newArgs = new ArrayList<>(); + AbstractInvokeExpr invokeExpr = InvokeExprOpt.get(); + for (int i = 0; i < invokeExpr.getArgCount(); i++) { + Immediate arg = invokeExpr.getArg(i); + + if (arg instanceof Constant && !(arg instanceof ClassConstant)) { + String label = LABEL + replaceCounter++; + Local paramLocal = Jimple.newLocal(label, arg.getType()); + JAssignStmt newAssignStmt = + Jimple.newAssignStmt(paramLocal, arg, stmt.getPositionInfo()); + + body.addLocal(paramLocal); + body.getStmtGraph().insertBefore(stmt, newAssignStmt); + newArgs.add(paramLocal); + } else { + newArgs.add(arg); + } + } + + // Update the invoke expression with new arguments + AbstractInvokeExpr newInvokeExpr; + if (invokeExpr instanceof JStaticInvokeExpr) { + newInvokeExpr = ((JStaticInvokeExpr) invokeExpr).withArgs(newArgs); + } else if (invokeExpr instanceof AbstractInstanceInvokeExpr) { + newInvokeExpr = ((AbstractInstanceInvokeExpr) invokeExpr).withArgs(newArgs); + } else { + throw new IllegalStateException("unknown InvokeExpr."); + } + + if (stmt instanceof JInvokeStmt) { + JInvokeStmt newStmt = ((JInvokeStmt) stmt).withInvokeExpr(newInvokeExpr); + body.getStmtGraph().replaceNode(stmt, newStmt); + } else if (stmt instanceof JAssignStmt) { + JAssignStmt newStmt = ((JAssignStmt) stmt).withRValue(newInvokeExpr); + body.getStmtGraph().replaceNode(stmt, newStmt); + } + } + } + } + + if (stmt instanceof JReturnStmt) { + /* Transform return stmtsWithConstants into two stmtsWithConstants + * - return 10 + * becomes + * - varReplacer = 10 + * - return varReplacer + */ + JReturnStmt returnStmt = (JReturnStmt) stmt; + + String label = LABEL + replaceCounter++; + Local local = Jimple.newLocal(label, returnStmt.getOp().getType()); + JAssignStmt assignStmt = + Jimple.newAssignStmt(local, returnStmt.getOp(), returnStmt.getPositionInfo()); + + body.addLocal(local); + body.getStmtGraph().insertBefore(stmt, assignStmt); + + JReturnStmt newReturnStmt = Jimple.newReturnStmt(local, returnStmt.getPositionInfo()); + body.getStmtGraph().replaceNode(stmt, newReturnStmt); + } + } + } + + private Collection getStatementsWithConstants(Body.BodyBuilder body) { + Collection result = new HashSet<>(); + + // Assign statements: If the right side is a constant + // Consider arguments of invoke expressions + // Check for constant return values + body.getStmts() + .forEach( + stmt -> { + if (stmt instanceof JAssignStmt) { + JAssignStmt assignStmt = (JAssignStmt) stmt; + + if (isFieldRef(assignStmt.getLeftOp()) + && assignStmt.getRightOp() instanceof Constant) { + result.add(stmt); + } + } + if (stmt.isInvokableStmt()) { + InvokableStmt invokableStmt = stmt.asInvokableStmt(); + if (invokableStmt.containsInvokeExpr()) { + Optional invokeExpr = invokableStmt.getInvokeExpr(); + if (invokeExpr.isPresent()) { + for (Value arg : invokeExpr.get().getArgs()) { + if (arg instanceof Constant) { + result.add(stmt); + } + } + } + } + } + if (stmt instanceof JReturnStmt) { + JReturnStmt returnStmt = (JReturnStmt) stmt; + if (returnStmt.getOp() instanceof Constant) { + result.add(stmt); + } + } + }); + + return result; + } + + private boolean isFieldRef(Value value) { + return value instanceof JInstanceFieldRef + || value instanceof JStaticFieldRef + || value instanceof JArrayRef; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpControlFlowGraph.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpControlFlowGraph.java new file mode 100644 index 00000000..4283b87f --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpControlFlowGraph.java @@ -0,0 +1,101 @@ +package boomerang.framework.sootup; + +import boomerang.scene.ControlFlowGraph; +import boomerang.scene.Statement; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.google.common.collect.Sets; +import java.util.Collection; +import java.util.List; +import sootup.core.graph.StmtGraph; +import sootup.core.jimple.common.stmt.JIdentityStmt; +import sootup.core.jimple.common.stmt.Stmt; + +public class JimpleUpControlFlowGraph implements ControlFlowGraph { + + private final JimpleUpMethod method; + private final StmtGraph graph; + + private boolean cacheBuilt = false; + private final List statements = Lists.newArrayList(); + private final Collection startPointCache = Sets.newHashSet(); + private final Collection endPointCache = Sets.newHashSet(); + private final Multimap predecessorsOfCache = HashMultimap.create(); + private final Multimap successorsOfCache = HashMultimap.create(); + + public JimpleUpControlFlowGraph(JimpleUpMethod method) { + this.method = method; + this.graph = method.getDelegate().getBody().getStmtGraph(); + } + + @Override + public Collection getStartPoints() { + buildCache(); + return startPointCache; + } + + @Override + public Collection getEndPoints() { + buildCache(); + return endPointCache; + } + + @Override + public Collection getSuccsOf(Statement curr) { + buildCache(); + return successorsOfCache.get(curr); + } + + @Override + public Collection getPredsOf(Statement curr) { + buildCache(); + return predecessorsOfCache.get(curr); + } + + @Override + public List getStatements() { + buildCache(); + return statements; + } + + public void buildCache() { + if (cacheBuilt) { + return; + } + + Collection heads = graph.getEntrypoints(); + for (Stmt head : heads) { + if (head instanceof JIdentityStmt) { + continue; + } + + Statement statement = JimpleUpStatement.create(head, method); + startPointCache.add(statement); + } + + Collection tails = graph.getTails(); + for (Stmt tail : tails) { + Statement statement = JimpleUpStatement.create(tail, method); + endPointCache.add(statement); + } + + List units = method.getDelegate().getBody().getStmts(); + for (Stmt unit : units) { + Statement first = JimpleUpStatement.create(unit, method); + statements.add(first); + + for (Stmt predecessor : graph.predecessors(unit)) { + Statement predStatement = JimpleUpStatement.create(predecessor, method); + predecessorsOfCache.put(first, predStatement); + } + + for (Stmt successor : graph.successors(unit)) { + Statement succStatement = JimpleUpStatement.create(successor, method); + successorsOfCache.put(first, succStatement); + } + } + + cacheBuilt = true; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDeclaredMethod.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDeclaredMethod.java new file mode 100644 index 00000000..049552d3 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDeclaredMethod.java @@ -0,0 +1,109 @@ +package boomerang.framework.sootup; + +import boomerang.scene.DeclaredMethod; +import boomerang.scene.Method; +import boomerang.scene.Type; +import boomerang.scene.WrappedClass; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import sootup.java.core.JavaSootClass; +import sootup.java.core.JavaSootMethod; +import sootup.java.core.types.JavaClassType; + +public class JimpleUpDeclaredMethod extends DeclaredMethod { + + private final JavaSootMethod delegate; + + public JimpleUpDeclaredMethod(JimpleUpInvokeExpr invokeExpr, JavaSootMethod delegate) { + super(invokeExpr); + + this.delegate = delegate; + } + + public JavaSootMethod getDelegate() { + return delegate; + } + + @Override + public boolean isNative() { + return delegate.isNative(); + } + + @Override + public String getSubSignature() { + return delegate.getSignature().getSubSignature().toString(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public boolean isStatic() { + return delegate.isStatic(); + } + + @Override + public boolean isConstructor() { + return SootUpFrameworkScope.isConstructor(delegate); + } + + @Override + public String getSignature() { + return delegate.getSignature().toString(); + } + + @Override + public Method getCalledMethod() { + return JimpleUpMethod.of(delegate); + } + + @Override + public WrappedClass getDeclaringClass() { + JavaSootClass sootClass = + SootUpFrameworkScope.getInstance() + .getSootClass((JavaClassType) delegate.getDeclaringClassType()); + return new JimpleUpWrappedClass(sootClass); + } + + @Override + public List getParameterTypes() { + return delegate.getParameterTypes().stream() + .map(JimpleUpType::new) + .collect(Collectors.toList()); + } + + @Override + public Type getParameterType(int index) { + return getParameterTypes().get(index); + } + + @Override + public Type getReturnType() { + return new JimpleUpType(delegate.getReturnType()); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpDeclaredMethod other = (JimpleUpDeclaredMethod) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDoubleVal.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDoubleVal.java new file mode 100644 index 00000000..e10c16b6 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDoubleVal.java @@ -0,0 +1,45 @@ +package boomerang.framework.sootup; + +import boomerang.scene.Method; +import boomerang.scene.Val; +import boomerang.scene.ValWithFalseVariable; +import java.util.Arrays; +import sootup.core.jimple.basic.Value; + +public class JimpleUpDoubleVal extends JimpleUpVal implements ValWithFalseVariable { + + private final Val falseVal; + + public JimpleUpDoubleVal(Value value, Method method, Val falseVal) { + super(value, method); + + this.falseVal = falseVal; + } + + @Override + public Val getFalseVariable() { + return falseVal; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {super.hashCode(), falseVal}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpDoubleVal other = (JimpleUpDoubleVal) obj; + if (falseVal == null) { + return other.falseVal == null; + } else return falseVal.equals(other.falseVal); + } + + @Override + public String toString() { + return "InstanceOf " + falseVal + " " + super.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpField.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpField.java new file mode 100644 index 00000000..c14ff441 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpField.java @@ -0,0 +1,45 @@ +package boomerang.framework.sootup; + +import boomerang.scene.Field; +import java.util.Arrays; +import sootup.java.core.JavaSootField; + +public class JimpleUpField extends Field { + + private final JavaSootField delegate; + + public JimpleUpField(JavaSootField delegate) { + this.delegate = delegate; + } + + public JavaSootField getDelegate() { + return delegate; + } + + @Override + public boolean isInnerClassField() { + return delegate.getName().contains("$"); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpField other = (JimpleUpField) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.getName(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpIfStatement.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpIfStatement.java new file mode 100644 index 00000000..157a003d --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpIfStatement.java @@ -0,0 +1,117 @@ +package boomerang.framework.sootup; + +import boomerang.scene.IfStatement; +import boomerang.scene.Statement; +import boomerang.scene.Val; +import java.util.Arrays; +import sootup.core.jimple.basic.Value; +import sootup.core.jimple.common.constant.IntConstant; +import sootup.core.jimple.common.constant.NullConstant; +import sootup.core.jimple.common.expr.AbstractConditionExpr; +import sootup.core.jimple.common.expr.JEqExpr; +import sootup.core.jimple.common.expr.JNeExpr; +import sootup.core.jimple.common.stmt.JIfStmt; + +public class JimpleUpIfStatement implements IfStatement { + + private final JIfStmt delegate; + private final JimpleUpMethod method; + + public JimpleUpIfStatement(JIfStmt delegate, JimpleUpMethod method) { + this.delegate = delegate; + this.method = method; + } + + @Override + public Statement getTarget() { + return JimpleUpStatement.create( + delegate.getTargetStmts(method.getDelegate().getBody()).get(0), method); + } + + @Override + public Evaluation evaluate(Val val) { + if (delegate.getCondition() instanceof JEqExpr) { + JEqExpr eqExpr = (JEqExpr) delegate.getCondition(); + + Value op1 = eqExpr.getOp1(); + Value op2 = eqExpr.getOp2(); + + if ((val.equals(new JimpleUpVal(op1, method)) && op2.equals(NullConstant.getInstance())) + || (val.equals(new JimpleUpVal(op2, method)) && op2.equals(NullConstant.getInstance()))) { + return Evaluation.TRUE; + } + + if ((val.equals(new JimpleUpVal(IntConstant.getInstance(0), method)) + && op2.equals(IntConstant.getInstance(0)) + || (val.equals(new JimpleUpVal(IntConstant.getInstance(1), method)) + && op2.equals(IntConstant.getInstance(1))))) { + return Evaluation.TRUE; + } + + if ((val.equals(new JimpleUpVal(IntConstant.getInstance(1), method)) + && op2.equals(IntConstant.getInstance(0)) + || (val.equals(new JimpleUpVal(IntConstant.getInstance(0), method)) + && op2.equals(IntConstant.getInstance(1))))) { + return Evaluation.FALSE; + } + } + + if (delegate.getCondition() instanceof JNeExpr) { + JNeExpr neExpr = (JNeExpr) delegate.getCondition(); + + Value op1 = neExpr.getOp1(); + Value op2 = neExpr.getOp2(); + + if ((val.equals(new JimpleUpVal(op1, method)) && op2.equals(NullConstant.getInstance()) + || (val.equals(new JimpleUpVal(op2, method)) + && op2.equals(NullConstant.getInstance())))) { + return Evaluation.FALSE; + } + if ((val.equals(new JimpleUpVal(IntConstant.getInstance(0), method)) + && op2.equals(IntConstant.getInstance(0)) + || (val.equals(new JimpleUpVal(IntConstant.getInstance(1), method)) + && op2.equals(IntConstant.getInstance(1))))) { + return Evaluation.FALSE; + } + if ((val.equals(new JimpleUpVal(IntConstant.getInstance(1), method)) + && op2.equals(IntConstant.getInstance(0)) + || (val.equals(new JimpleUpVal(IntConstant.getInstance(0), method)) + && op2.equals(IntConstant.getInstance(1))))) { + return Evaluation.TRUE; + } + } + + return Evaluation.UNKOWN; + } + + @Override + public boolean uses(Val val) { + AbstractConditionExpr conditionExpr = delegate.getCondition(); + Value op1 = conditionExpr.getOp1(); + Value op2 = conditionExpr.getOp2(); + + return val.equals(new JimpleUpVal(op1, method)) || val.equals(new JimpleUpVal(op2, method)); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpIfStatement other = (JimpleUpIfStatement) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInstanceFieldRef.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInstanceFieldRef.java new file mode 100644 index 00000000..2d65028e --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInstanceFieldRef.java @@ -0,0 +1,53 @@ +package boomerang.framework.sootup; + +import boomerang.scene.Field; +import boomerang.scene.InstanceFieldRef; +import boomerang.scene.Val; +import java.util.Arrays; +import sootup.core.jimple.common.ref.JInstanceFieldRef; +import sootup.java.core.JavaSootField; + +public class JimpleUpInstanceFieldRef implements InstanceFieldRef { + + private final JInstanceFieldRef delegate; + private final JimpleUpMethod method; + + public JimpleUpInstanceFieldRef(JInstanceFieldRef delegate, JimpleUpMethod method) { + this.delegate = delegate; + this.method = method; + } + + @Override + public Val getBase() { + return new JimpleUpVal(delegate.getBase(), method); + } + + @Override + public Field getField() { + JavaSootField field = + SootUpFrameworkScope.getInstance().getSootField(delegate.getFieldSignature()); + return new JimpleUpField(field); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpInstanceFieldRef other = (JimpleUpInstanceFieldRef) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInvokeExpr.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInvokeExpr.java new file mode 100644 index 00000000..15b0aa03 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInvokeExpr.java @@ -0,0 +1,103 @@ +package boomerang.framework.sootup; + +import boomerang.scene.DeclaredMethod; +import boomerang.scene.InvokeExpr; +import boomerang.scene.Val; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import sootup.core.jimple.common.expr.AbstractInstanceInvokeExpr; +import sootup.core.jimple.common.expr.AbstractInvokeExpr; +import sootup.core.jimple.common.expr.JSpecialInvokeExpr; +import sootup.core.jimple.common.expr.JStaticInvokeExpr; +import sootup.java.core.JavaSootMethod; + +public class JimpleUpInvokeExpr implements InvokeExpr { + + private final AbstractInvokeExpr delegate; + private final JimpleUpMethod method; + + private List argsCache; + + public JimpleUpInvokeExpr(AbstractInvokeExpr delegate, JimpleUpMethod method) { + this.delegate = delegate; + this.method = method; + } + + @Override + public Val getArg(int index) { + if (delegate.getArg(index) == null) { + return Val.zero(); + } + return new JimpleUpVal(delegate.getArg(index), method); + } + + @Override + public List getArgs() { + if (argsCache == null) { + argsCache = new ArrayList<>(); + + for (int i = 0; i < delegate.getArgCount(); i++) { + argsCache.add(getArg(i)); + } + } + return argsCache; + } + + @Override + public boolean isInstanceInvokeExpr() { + return delegate instanceof AbstractInstanceInvokeExpr; + } + + @Override + public Val getBase() { + assert isInstanceInvokeExpr(); + AbstractInstanceInvokeExpr iie = (AbstractInstanceInvokeExpr) delegate; + + return new JimpleUpVal(iie.getBase(), method); + } + + @Override + public DeclaredMethod getMethod() { + JavaSootMethod sootMethod = + SootUpFrameworkScope.getInstance() + .getSootMethod(delegate.getMethodSignature()) + .orElseThrow( + () -> + new IllegalStateException( + "Can't find Method Declaration! " + delegate.getMethodSignature())); + return new JimpleUpDeclaredMethod(this, sootMethod); + } + + @Override + public boolean isSpecialInvokeExpr() { + return delegate instanceof JSpecialInvokeExpr; + } + + @Override + public boolean isStaticInvokeExpr() { + return delegate instanceof JStaticInvokeExpr; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpInvokeExpr other = (JimpleUpInvokeExpr) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpMethod.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpMethod.java new file mode 100644 index 00000000..0402c9d7 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpMethod.java @@ -0,0 +1,184 @@ +package boomerang.framework.sootup; + +import boomerang.scene.*; +import com.google.common.collect.Interner; +import com.google.common.collect.Interners; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import sootup.core.jimple.basic.Local; +import sootup.java.core.JavaSootClass; +import sootup.java.core.JavaSootMethod; +import sootup.java.core.types.JavaClassType; + +public class JimpleUpMethod extends Method { + + protected static Interner INTERNAL_POOL = Interners.newWeakInterner(); + private final JavaSootMethod delegate; + private final JimpleUpControlFlowGraph cfg; + + private Set localCache; + private List parameterLocalCache; + + protected JimpleUpMethod(JavaSootMethod delegate) { + this.delegate = delegate; + + if (!delegate.hasBody()) { + throw new RuntimeException("Trying to build a Jimple method without body present"); + } + + cfg = new JimpleUpControlFlowGraph(this); + } + + public static JimpleUpMethod of(JavaSootMethod method) { + return INTERNAL_POOL.intern(new JimpleUpMethod(method)); + } + + public JavaSootMethod getDelegate() { + return delegate; + } + + @Override + public boolean isStaticInitializer() { + return SootUpFrameworkScope.isStaticInitializer(delegate); + } + + @Override + public boolean isParameterLocal(Val val) { + if (val.isStatic()) return false; + + List parameterLocals = getParameterLocals(); + return parameterLocals.contains(val); + } + + @Override + public List getParameterTypes() { + List result = new ArrayList<>(); + + for (sootup.core.types.Type type : delegate.getParameterTypes()) { + result.add(new JimpleUpType(type)); + } + + return result; + } + + @Override + public Type getParameterType(int index) { + return new JimpleUpType(delegate.getParameterType(index)); + } + + @Override + public Type getReturnType() { + return new JimpleUpType(delegate.getReturnType()); + } + + @Override + public boolean isThisLocal(Val val) { + if (val.isStatic()) return false; + if (delegate.isStatic()) return false; + + Val thisLocal = getThisLocal(); + return thisLocal.equals(val); + } + + @Override + public Set getLocals() { + if (localCache == null) { + localCache = new HashSet<>(); + + for (Local local : delegate.getBody().getLocals()) { + localCache.add(new JimpleUpVal(local, this)); + } + } + return localCache; + } + + @Override + public Val getThisLocal() { + return new JimpleUpVal(delegate.getBody().getThisLocal(), this); + } + + @Override + public List getParameterLocals() { + if (parameterLocalCache == null) { + parameterLocalCache = new ArrayList<>(); + + for (Local local : delegate.getBody().getParameterLocals()) { + parameterLocalCache.add(new JimpleUpVal(local, this)); + } + } + return parameterLocalCache; + } + + @Override + public boolean isStatic() { + return delegate.isStatic(); + } + + @Override + public boolean isNative() { + return delegate.isNative(); + } + + @Override + public List getStatements() { + return getControlFlowGraph().getStatements(); + } + + @Override + public WrappedClass getDeclaringClass() { + JavaSootClass sootClass = + SootUpFrameworkScope.getInstance() + .getSootClass((JavaClassType) delegate.getDeclaringClassType()); + return new JimpleUpWrappedClass(sootClass); + } + + @Override + public ControlFlowGraph getControlFlowGraph() { + return cfg; + } + + @Override + public String getSubSignature() { + return delegate.getSignature().getSubSignature().toString(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public boolean isConstructor() { + return SootUpFrameworkScope.isConstructor(delegate); + } + + @Override + public boolean isPublic() { + return delegate.isPublic(); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpMethod other = (JimpleUpMethod) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStatement.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStatement.java new file mode 100644 index 00000000..8043d3ca --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStatement.java @@ -0,0 +1,417 @@ +package boomerang.framework.sootup; + +import boomerang.scene.Field; +import boomerang.scene.IfStatement; +import boomerang.scene.InvokeExpr; +import boomerang.scene.Pair; +import boomerang.scene.Statement; +import boomerang.scene.StaticFieldVal; +import boomerang.scene.Val; +import com.google.common.base.Joiner; +import java.util.Arrays; +import java.util.Collection; +import sootup.core.jimple.common.constant.StringConstant; +import sootup.core.jimple.common.expr.*; +import sootup.core.jimple.common.ref.JArrayRef; +import sootup.core.jimple.common.ref.JCaughtExceptionRef; +import sootup.core.jimple.common.ref.JInstanceFieldRef; +import sootup.core.jimple.common.ref.JStaticFieldRef; +import sootup.core.jimple.common.stmt.JAssignStmt; +import sootup.core.jimple.common.stmt.JIdentityStmt; +import sootup.core.jimple.common.stmt.JIfStmt; +import sootup.core.jimple.common.stmt.JReturnStmt; +import sootup.core.jimple.common.stmt.JThrowStmt; +import sootup.core.jimple.common.stmt.Stmt; +import sootup.java.core.JavaSootField; + +public class JimpleUpStatement extends Statement { + + private final Stmt delegate; + private final JimpleUpMethod method; + + private JimpleUpStatement(Stmt delegate, JimpleUpMethod method) { + super(method); + + if (delegate == null) { + throw new RuntimeException("Statement must not be null"); + } + + this.delegate = delegate; + this.method = method; + } + + public static Statement create(Stmt delegate, JimpleUpMethod method) { + return new JimpleUpStatement(delegate, method); + } + + @Override + public boolean containsStaticFieldAccess() { + if (delegate instanceof JAssignStmt) { + JAssignStmt assignStmt = (JAssignStmt) delegate; + + return assignStmt.getLeftOp() instanceof JStaticFieldRef + || assignStmt.getRightOp() instanceof JStaticFieldRef; + } + return false; + } + + @Override + public boolean containsInvokeExpr() { + return delegate.isInvokableStmt() && delegate.asInvokableStmt().containsInvokeExpr(); + } + + @Override + public Field getWrittenField() { + assert isAssign(); + + JAssignStmt assignStmt = (JAssignStmt) delegate; + SootUpFrameworkScope scopeInstance = SootUpFrameworkScope.getInstance(); + if (assignStmt.getLeftOp() instanceof JStaticFieldRef) { + JStaticFieldRef staticFieldRef = (JStaticFieldRef) assignStmt.getLeftOp(); + JavaSootField sootField = scopeInstance.getSootField(staticFieldRef.getFieldSignature()); + return new JimpleUpField(sootField); + } + + if (assignStmt.getLeftOp() instanceof JArrayRef) { + return Field.array(getArrayBase().getY()); + } + + JInstanceFieldRef ifr = (JInstanceFieldRef) assignStmt.getLeftOp(); + JavaSootField sootField = scopeInstance.getSootField(ifr.getFieldSignature()); + return new JimpleUpField(sootField); + } + + @Override + public boolean isFieldWriteWithBase(Val base) { + if (isAssign() && isFieldStore()) { + Pair instanceFieldRef = getFieldStore(); + return instanceFieldRef.getX().equals(base); + } + + if (isAssign() && isArrayStore()) { + Pair arrayBase = getArrayBase(); + return arrayBase.getX().equals(base); + } + + return false; + } + + @Override + public Field getLoadedField() { + JAssignStmt as = (JAssignStmt) delegate; + JInstanceFieldRef ifr = (JInstanceFieldRef) as.getRightOp(); + + JavaSootField sootField = + SootUpFrameworkScope.getInstance().getSootField(ifr.getFieldSignature()); + return new JimpleUpField(sootField); + } + + @Override + public boolean isFieldLoadWithBase(Val base) { + if (isAssign() && isFieldLoad()) { + return getFieldLoad().getX().equals(base); + } + return false; + } + + @Override + public boolean isAssign() { + return delegate instanceof JAssignStmt; + } + + @Override + public Val getLeftOp() { + assert isAssign(); + + JAssignStmt assignStmt = (JAssignStmt) delegate; + return new JimpleUpVal(assignStmt.getLeftOp(), method); + } + + @Override + public Val getRightOp() { + assert isAssign(); + + JAssignStmt assignStmt = (JAssignStmt) delegate; + return new JimpleUpVal(assignStmt.getRightOp(), method); + } + + @Override + public boolean isInstanceOfStatement(Val fact) { + if (isAssign()) { + if (getRightOp().isInstanceOfExpr()) { + Val instanceOfOp = getRightOp().getInstanceOfOp(); + return instanceOfOp.equals(fact); + } + } + return false; + } + + @Override + public boolean isCast() { + if (delegate instanceof JAssignStmt) { + JAssignStmt assignStmt = (JAssignStmt) delegate; + + return assignStmt.getRightOp() instanceof JCastExpr; + } + return false; + } + + @Override + public boolean isPhiStatement() { + return false; + } + + @Override + public InvokeExpr getInvokeExpr() { + assert containsInvokeExpr(); + assert delegate.isInvokableStmt(); + assert delegate.asInvokableStmt().getInvokeExpr().isPresent(); + return new JimpleUpInvokeExpr(delegate.asInvokableStmt().getInvokeExpr().get(), method); + } + + @Override + public boolean isReturnStmt() { + return delegate instanceof JReturnStmt; + } + + @Override + public boolean isThrowStmt() { + return delegate instanceof JThrowStmt; + } + + @Override + public boolean isIfStmt() { + return delegate instanceof JIfStmt; + } + + @Override + public IfStatement getIfStmt() { + assert isIfStmt(); + + JIfStmt ifStmt = (JIfStmt) delegate; + return new JimpleUpIfStatement(ifStmt, method); + } + + @Override + public Val getReturnOp() { + assert isReturnStmt(); + + JReturnStmt returnStmt = (JReturnStmt) delegate; + return new JimpleUpVal(returnStmt.getOp(), method); + } + + @Override + public boolean isMultiArrayAllocation() { + return (delegate instanceof JAssignStmt) + && ((JAssignStmt) delegate).getRightOp() instanceof JNewMultiArrayExpr; + } + + @Override + public boolean isStringAllocation() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getRightOp() instanceof StringConstant; + } + + @Override + public boolean isFieldStore() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getLeftOp() instanceof JInstanceFieldRef; + } + + @Override + public boolean isArrayStore() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getLeftOp() instanceof JArrayRef; + } + + @Override + public boolean isArrayLoad() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getRightOp() instanceof JArrayRef; + } + + @Override + public boolean isFieldLoad() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getRightOp() instanceof JInstanceFieldRef; + } + + @Override + public boolean isIdentityStmt() { + return delegate instanceof JIdentityStmt; + } + + @Override + public Pair getFieldStore() { + JAssignStmt assignStmt = (JAssignStmt) delegate; + JInstanceFieldRef val = (JInstanceFieldRef) assignStmt.getLeftOp(); + return new Pair<>( + new JimpleUpVal(val.getBase(), method), + new JimpleUpField( + SootUpFrameworkScope.getInstance().getSootField(val.getFieldSignature()))); + } + + @Override + public Pair getFieldLoad() { + JAssignStmt assignStmt = (JAssignStmt) delegate; + JInstanceFieldRef val = (JInstanceFieldRef) assignStmt.getRightOp(); + return new Pair<>( + new JimpleUpVal(val.getBase(), method), + new JimpleUpField( + SootUpFrameworkScope.getInstance().getSootField(val.getFieldSignature()))); + } + + @Override + public boolean isStaticFieldLoad() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getRightOp() instanceof JStaticFieldRef; + } + + @Override + public boolean isStaticFieldStore() { + return delegate instanceof JAssignStmt + && ((JAssignStmt) delegate).getLeftOp() instanceof JStaticFieldRef; + } + + @Override + public StaticFieldVal getStaticField() { + JStaticFieldRef v; + if (isStaticFieldLoad()) { + v = (JStaticFieldRef) ((JAssignStmt) delegate).getRightOp(); + } else if (isStaticFieldStore()) { + v = (JStaticFieldRef) ((JAssignStmt) delegate).getLeftOp(); + } else { + throw new RuntimeException("Statement does not have a static field"); + } + return new JimpleUpStaticFieldVal( + new JimpleUpField(SootUpFrameworkScope.getInstance().getSootField(v.getFieldSignature())), + method); + } + + @Override + public boolean killAtIfStmt(Val fact, Statement successor) { + return false; + } + + @Override + public Collection getPhiVals() { + throw new RuntimeException("Not supported!"); + } + + @Override + public Pair getArrayBase() { + if (isArrayLoad()) { + Val rightOp = getRightOp(); + return rightOp.getArrayBase(); + } + + if (isArrayStore()) { + Val rightOp = getLeftOp(); + return rightOp.getArrayBase(); + } + + throw new RuntimeException("Statement does not deal with an array base"); + } + + @Override + public int getStartLineNumber() { + return delegate.getPositionInfo().getStmtPosition().getFirstLine(); + } + + @Override + public int getStartColumnNumber() { + return delegate.getPositionInfo().getStmtPosition().getFirstCol(); + } + + @Override + public int getEndLineNumber() { + return delegate.getPositionInfo().getStmtPosition().getLastLine(); + } + + @Override + public int getEndColumnNumber() { + return delegate.getPositionInfo().getStmtPosition().getLastCol(); + } + + @Override + public boolean isCatchStmt() { + return delegate instanceof JIdentityStmt + && ((JIdentityStmt) delegate).getRightOp() instanceof JCaughtExceptionRef; + } + + public Stmt getDelegate() { + return delegate; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpStatement other = (JimpleUpStatement) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return shortName(delegate); + } + + private String shortName(Stmt s) { + if (s.isInvokableStmt() && s.asInvokableStmt().containsInvokeExpr()) { + String base = ""; + AbstractInvokeExpr abstractInvokeExpr = s.asInvokableStmt().getInvokeExpr().get(); + if (abstractInvokeExpr instanceof AbstractInstanceInvokeExpr) { + AbstractInstanceInvokeExpr iie = (AbstractInstanceInvokeExpr) abstractInvokeExpr; + base = iie.getBase() + "."; + } + String assign = ""; + if (s instanceof JAssignStmt) { + assign = ((JAssignStmt) s).getLeftOp() + " = "; + } + return assign + + base + + abstractInvokeExpr.getMethodSignature().getName() + + "(" + + Joiner.on(",").join(abstractInvokeExpr.getArgs()) + + ")"; + } + if (s instanceof JIdentityStmt) { + return s.toString(); + } + if (s instanceof JAssignStmt) { + JAssignStmt assignStmt = (JAssignStmt) s; + if (assignStmt.getLeftOp() instanceof JInstanceFieldRef) { + JInstanceFieldRef ifr = (JInstanceFieldRef) assignStmt.getLeftOp(); + return ifr.getBase() + + "." + + ifr.getFieldSignature().getName() + + " = " + + assignStmt.getRightOp(); + } + if (assignStmt.getRightOp() instanceof JInstanceFieldRef) { + JInstanceFieldRef ifr = (JInstanceFieldRef) assignStmt.getRightOp(); + return assignStmt.getLeftOp() + + " = " + + ifr.getBase() + + "." + + ifr.getFieldSignature().getName(); + } + if (assignStmt.getRightOp() instanceof JNewExpr) { + JNewExpr newExpr = (JNewExpr) assignStmt.getRightOp(); + return assignStmt.getLeftOp() + + " = new " + + newExpr.getType().getClassName(); // getSootClass().getShortName(); + } + } + return s.toString(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStaticFieldVal.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStaticFieldVal.java new file mode 100644 index 00000000..9c9f2c16 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStaticFieldVal.java @@ -0,0 +1,198 @@ +package boomerang.framework.sootup; + +import boomerang.scene.ControlFlowGraph; +import boomerang.scene.Field; +import boomerang.scene.Method; +import boomerang.scene.Pair; +import boomerang.scene.StaticFieldVal; +import boomerang.scene.Type; +import boomerang.scene.Val; +import java.util.Arrays; + +public class JimpleUpStaticFieldVal extends StaticFieldVal { + + private final JimpleUpField field; + + public JimpleUpStaticFieldVal(JimpleUpField field, Method method) { + this(field, method, null); + } + + private JimpleUpStaticFieldVal( + JimpleUpField field, Method method, ControlFlowGraph.Edge unbalanced) { + super(method, unbalanced); + + this.field = field; + } + + @Override + public Field field() { + return field; + } + + @Override + public Type getType() { + return new JimpleUpType(field.getDelegate().getType()); + } + + @Override + public boolean isStatic() { + return true; + } + + @Override + public boolean isNewExpr() { + return false; + } + + @Override + public Type getNewExprType() { + throw new RuntimeException("Static field val is not a new expression"); + } + + @Override + public Val asUnbalanced(ControlFlowGraph.Edge stmt) { + return new JimpleUpStaticFieldVal(field, m, stmt); + } + + @Override + public boolean isLocal() { + return false; + } + + @Override + public boolean isArrayAllocationVal() { + return false; + } + + @Override + public Val getArrayAllocationSize() { + throw new RuntimeException("Static Val is not an array allocation val"); + } + + @Override + public boolean isNull() { + return false; + } + + @Override + public boolean isStringConstant() { + return false; + } + + @Override + public String getStringValue() { + throw new RuntimeException("Static field val is not a string constant"); + } + + @Override + public boolean isStringBufferOrBuilder() { + return false; + } + + @Override + public boolean isThrowableAllocationType() { + return false; + } + + @Override + public boolean isCast() { + return false; + } + + @Override + public Val getCastOp() { + throw new RuntimeException("Static field val is not a cast operation"); + } + + @Override + public boolean isArrayRef() { + return false; + } + + @Override + public boolean isInstanceOfExpr() { + return false; + } + + @Override + public Val getInstanceOfOp() { + throw new RuntimeException("Static field val is not an instance of operation"); + } + + @Override + public boolean isLengthExpr() { + return false; + } + + @Override + public Val getLengthOp() { + throw new RuntimeException("Static field val is not a length operation"); + } + + @Override + public boolean isIntConstant() { + return false; + } + + @Override + public boolean isClassConstant() { + return false; + } + + @Override + public Type getClassConstantType() { + throw new RuntimeException("Static field val is not a class constant"); + } + + @Override + public Val withNewMethod(Method callee) { + return new JimpleUpStaticFieldVal(field, callee); + } + + @Override + public boolean isLongConstant() { + return false; + } + + @Override + public int getIntValue() { + return -1; + } + + @Override + public long getLongValue() { + return -1; + } + + @Override + public Pair getArrayBase() { + throw new RuntimeException("Static field val has not an array base"); + } + + @Override + public String getVariableName() { + return field.toString(); + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {super.hashCode(), field}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpStaticFieldVal other = (JimpleUpStaticFieldVal) obj; + if (field == null) { + return other.field == null; + } else return field.equals(other.field); + } + + @Override + public String toString() { + return "StaticField: " + field; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpType.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpType.java new file mode 100644 index 00000000..1295a3e9 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpType.java @@ -0,0 +1,152 @@ +package boomerang.framework.sootup; + +import boomerang.scene.AllocVal; +import boomerang.scene.Type; +import boomerang.scene.Val; +import boomerang.scene.WrappedClass; +import sootup.core.typehierarchy.TypeHierarchy; +import sootup.core.types.ArrayType; +import sootup.core.types.NullType; +import sootup.core.types.PrimitiveType; +import sootup.core.types.ReferenceType; +import sootup.java.core.JavaSootClass; +import sootup.java.core.types.JavaClassType; +import sootup.java.core.views.JavaView; + +public class JimpleUpType implements Type { + + private final sootup.core.types.Type delegate; + + public JimpleUpType(sootup.core.types.Type delegate) { + this.delegate = delegate; + } + + @Override + public boolean isNullType() { + return delegate instanceof NullType; + } + + @Override + public boolean isRefType() { + return delegate instanceof ReferenceType; + } + + @Override + public boolean isArrayType() { + return delegate instanceof ArrayType; + } + + @Override + public Type getArrayBaseType() { + return new JimpleUpType(delegate).getArrayBaseType(); + } + + @Override + public WrappedClass getWrappedClass() { + JavaClassType classType = (JavaClassType) delegate; + JavaSootClass sootClass = SootUpFrameworkScope.getInstance().getSootClass(classType); + return new JimpleUpWrappedClass(sootClass); + } + + @Override + public boolean doesCastFail(Type targetVal, Val target) { + JavaClassType targetType = (JavaClassType) ((JimpleUpType) targetVal).getDelegate(); + if (this.getDelegate() instanceof NullType) { + return true; + } + + JavaClassType sourceType = (JavaClassType) this.getDelegate(); + JavaSootClass targetClass = SootUpFrameworkScope.getInstance().getSootClass(targetType); + JavaSootClass sourceClass = SootUpFrameworkScope.getInstance().getSootClass(sourceType); + + if (targetClass instanceof SootUpFrameworkScope.PhantomClass + || sourceClass instanceof SootUpFrameworkScope.PhantomClass) { + return false; + } + + if (target instanceof AllocVal && ((AllocVal) target).getAllocVal().isNewExpr()) { + boolean castFails = + SootUpFrameworkScope.getInstance() + .getView() + .getTypeHierarchy() + .isSubtype(targetType, sourceType); + return !castFails; + } + // TODO this line is necessary as canStoreType does not properly work for + // interfaces, see Java doc. + if (targetClass.isInterface()) { + return false; + } + boolean castFails = + SootUpFrameworkScope.getInstance() + .getView() + .getTypeHierarchy() + .isSubtype(targetType, sourceType) + || SootUpFrameworkScope.getInstance() + .getView() + .getTypeHierarchy() + .isSubtype(sourceType, targetType); + return !castFails; + } + + @Override + public boolean isSubtypeOf(String type) { + if (delegate.toString().equals(type)) return true; + if (!(delegate instanceof ReferenceType)) { + if (delegate instanceof PrimitiveType) { + return type.equals(delegate.toString()); + } + return false; + } + + SootUpFrameworkScope scopeInstance = SootUpFrameworkScope.getInstance(); + JavaClassType superType = scopeInstance.getIdentifierFactory().getClassType(type); + JavaSootClass superClass = scopeInstance.getSootClass(superType); + + JavaClassType allocatedType = (JavaClassType) delegate; + JavaSootClass sootClass = scopeInstance.getSootClass(allocatedType); + TypeHierarchy typeHierarchy = scopeInstance.getView().getTypeHierarchy(); + if (!superClass.isInterface()) { + return typeHierarchy.isSubtype(sootClass.getType(), superClass.getType()); + } + // TODO: [ms] check if seperation of interface/class is necessary + if (typeHierarchy.subclassesOf(superClass.getType()).anyMatch(t -> t == allocatedType)) { + return true; + } + return typeHierarchy.implementersOf(superClass.getType()).anyMatch(t -> t == allocatedType); + } + + @Override + public boolean isSupertypeOf(String subTypeStr) { + if (!(delegate instanceof ReferenceType)) { + if (delegate instanceof PrimitiveType) { + return subTypeStr.equals(delegate.toString()); + } + return false; + } + + JavaView view = SootUpFrameworkScope.getInstance().getView(); + TypeHierarchy typeHierarchy = view.getTypeHierarchy(); + + JavaClassType subType = view.getIdentifierFactory().getClassType(subTypeStr); + if (!typeHierarchy.contains(subType)) { + return false; + } + + JavaClassType thisType = view.getIdentifierFactory().getClassType(delegate.toString()); + if (!typeHierarchy.contains(thisType)) { + return false; + } + + return typeHierarchy.isSubtype(subType, thisType); + } + + @Override + public boolean isBooleanType() { + return false; + } + + public sootup.core.types.Type getDelegate() { + return delegate; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpVal.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpVal.java new file mode 100644 index 00000000..12d30f57 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpVal.java @@ -0,0 +1,270 @@ +package boomerang.framework.sootup; + +import boomerang.scene.ControlFlowGraph; +import boomerang.scene.Method; +import boomerang.scene.Pair; +import boomerang.scene.Type; +import boomerang.scene.Val; +import java.util.Arrays; +import sootup.core.jimple.basic.Local; +import sootup.core.jimple.basic.Value; +import sootup.core.jimple.common.constant.ClassConstant; +import sootup.core.jimple.common.constant.IntConstant; +import sootup.core.jimple.common.constant.LongConstant; +import sootup.core.jimple.common.constant.NullConstant; +import sootup.core.jimple.common.constant.StringConstant; +import sootup.core.jimple.common.expr.JCastExpr; +import sootup.core.jimple.common.expr.JInstanceOfExpr; +import sootup.core.jimple.common.expr.JLengthExpr; +import sootup.core.jimple.common.expr.JNewArrayExpr; +import sootup.core.jimple.common.expr.JNewExpr; +import sootup.core.jimple.common.expr.JNewMultiArrayExpr; +import sootup.core.jimple.common.ref.JArrayRef; +import sootup.core.types.NullType; + +public class JimpleUpVal extends Val { + + private final Value delegate; + + public JimpleUpVal(Value delegate, Method method) { + this(delegate, method, null); + } + + protected JimpleUpVal(Value delegate, Method method, ControlFlowGraph.Edge unbalanced) { + super(method, unbalanced); + + if (delegate == null) { + throw new RuntimeException("Value must not be null"); + } + this.delegate = delegate; + } + + @Override + public Type getType() { + if (delegate == null) { + return new JimpleUpType(NullType.getInstance()); + } else { + return new JimpleUpType(delegate.getType()); + } + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isNewExpr() { + return delegate instanceof JNewExpr; + } + + @Override + public Type getNewExprType() { + assert isNewExpr(); + return new JimpleUpType(((JNewExpr) delegate).getType()); + } + + @Override + public Val asUnbalanced(ControlFlowGraph.Edge stmt) { + return new JimpleUpVal(delegate, m, stmt); + } + + @Override + public boolean isLocal() { + return delegate instanceof Local; + } + + @Override + public boolean isArrayAllocationVal() { + return delegate instanceof JNewArrayExpr || delegate instanceof JNewMultiArrayExpr; + } + + @Override + public Val getArrayAllocationSize() { + if (delegate instanceof JNewArrayExpr) { + JNewArrayExpr newArrayExpr = (JNewArrayExpr) delegate; + + return new JimpleUpVal(newArrayExpr.getSize(), m); + } + + throw new RuntimeException("Val is not an array allocation val"); + } + + @Override + public boolean isNull() { + return delegate instanceof NullConstant; + } + + @Override + public boolean isStringConstant() { + return delegate instanceof StringConstant; + } + + @Override + public String getStringValue() { + assert isStringConstant(); + return ((StringConstant) delegate).getValue(); + } + + @Override + public boolean isStringBufferOrBuilder() { + Type type = getType(); + return type.toString().equals("java.lang.String") + || type.toString().equals("java.lang.StringBuilder") + || type.toString().equals("java.lang.StringBuffer"); + } + + @Override + public boolean isThrowableAllocationType() { + return SootUpFrameworkScope.getInstance() + .getView() + .getTypeHierarchy() + .isSubtype( + ((JimpleUpType) getType()).getDelegate(), + SootUpFrameworkScope.getInstance() + .getIdentifierFactory() + .getClassType("java.lang.Throwable")); + } + + @Override + public boolean isCast() { + return delegate instanceof JCastExpr; + } + + @Override + public Val getCastOp() { + assert isCast(); + + JCastExpr castExpr = (JCastExpr) delegate; + return new JimpleUpVal(castExpr.getOp(), m); + } + + @Override + public boolean isArrayRef() { + return delegate instanceof JArrayRef; + } + + @Override + public boolean isInstanceOfExpr() { + return delegate instanceof JInstanceOfExpr; + } + + @Override + public Val getInstanceOfOp() { + assert isInstanceOfExpr(); + + JInstanceOfExpr instanceOfExpr = (JInstanceOfExpr) delegate; + return new JimpleUpVal(instanceOfExpr.getOp(), m); + } + + @Override + public boolean isLengthExpr() { + return delegate instanceof JLengthExpr; + } + + @Override + public Val getLengthOp() { + assert isLengthExpr(); + + JLengthExpr lengthExpr = (JLengthExpr) delegate; + return new JimpleUpVal(lengthExpr.getOp(), m); + } + + @Override + public boolean isIntConstant() { + return delegate instanceof IntConstant; + } + + @Override + public boolean isClassConstant() { + return delegate instanceof ClassConstant; + } + + @Override + public Type getClassConstantType() { + assert isClassConstant(); + + ClassConstant constant = (ClassConstant) delegate; + return new JimpleUpType(constant.getType()); + } + + @Override + public Val withNewMethod(Method callee) { + throw new RuntimeException("Only allowed for static fields"); + } + + @Override + public Val withSecondVal(Val leftOp) { + return new JimpleUpDoubleVal(delegate, m, leftOp); + } + + @Override + public boolean isLongConstant() { + return delegate instanceof LongConstant; + } + + @Override + public int getIntValue() { + assert isIntConstant(); + + IntConstant intConstant = (IntConstant) delegate; + return intConstant.getValue(); + } + + @Override + public long getLongValue() { + assert isLongConstant(); + + LongConstant longConstant = (LongConstant) delegate; + return longConstant.getValue(); + } + + @Override + public Pair getArrayBase() { + assert isArrayRef(); + + JArrayRef arrayRef = (JArrayRef) delegate; + return new Pair<>( + new JimpleUpVal(arrayRef.getBase(), m), + arrayRef.getIndex() instanceof IntConstant + ? ((IntConstant) arrayRef.getIndex()).getValue() + : -1); + } + + @Override + public String getVariableName() { + return delegate.toString(); + } + + public Value getDelegate() { + return delegate; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {super.hashCode(), delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!super.equals(obj)) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpVal other = (JimpleUpVal) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.toString() + + " (" + + m.getDeclaringClass() + + "." + + m + + ")" + + (isUnbalanced() ? " unbalanced " + unbalancedStmt : ""); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpWrappedClass.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpWrappedClass.java new file mode 100644 index 00000000..cce1c5b9 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpWrappedClass.java @@ -0,0 +1,99 @@ +package boomerang.framework.sootup; + +import boomerang.scene.Method; +import boomerang.scene.Type; +import boomerang.scene.WrappedClass; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; +import sootup.java.core.JavaSootClass; +import sootup.java.core.JavaSootMethod; +import sootup.java.core.types.JavaClassType; + +public class JimpleUpWrappedClass implements WrappedClass { + + private final JavaSootClass delegate; + private Set methodsCache; + + public JimpleUpWrappedClass(JavaSootClass delegate) { + this.delegate = delegate; + } + + @Override + public Set getMethods() { + if (methodsCache == null) { + methodsCache = new HashSet<>(); + + for (JavaSootMethod method : delegate.getMethods()) { + if (method.hasBody()) { + methodsCache.add(JimpleUpMethod.of(method)); + } + } + } + return methodsCache; + } + + @Override + public boolean hasSuperclass() { + return delegate.hasSuperclass(); + } + + @Override + public WrappedClass getSuperclass() { + Optional superClassType = delegate.getSuperclass(); + if (superClassType.isEmpty()) { + throw new RuntimeException("Super class type of " + superClassType + " is not present"); + } + JavaSootClass superClass = + SootUpFrameworkScope.getInstance().getSootClass(superClassType.get()); + return new JimpleUpWrappedClass(superClass); + } + + @Override + public Type getType() { + return new JimpleUpType(delegate.getType()); + } + + @Override + public boolean isApplicationClass() { + return delegate.isApplicationClass(); + } + + @Override + public String getFullyQualifiedName() { + return delegate.getName(); + } + + @Override + public String getName() { + return delegate.getName(); + } + + @Override + public Object getDelegate() { + return delegate; + } + + @Override + public int hashCode() { + return Arrays.hashCode(new Object[] {delegate}); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + + JimpleUpWrappedClass other = (JimpleUpWrappedClass) obj; + if (delegate == null) { + return other.delegate == null; + } else return delegate.equals(other.delegate); + } + + @Override + public String toString() { + return delegate.getName(); + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpCallGraph.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpCallGraph.java new file mode 100644 index 00000000..696d8a15 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpCallGraph.java @@ -0,0 +1,64 @@ +package boomerang.framework.sootup; + +import boomerang.scene.CallGraph; +import boomerang.scene.Method; +import boomerang.scene.Statement; +import java.util.Collection; +import java.util.Optional; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sootup.core.jimple.common.stmt.InvokableStmt; +import sootup.core.signatures.MethodSignature; +import sootup.java.core.JavaSootMethod; + +public class SootUpCallGraph extends CallGraph { + + private static final Logger LOGGER = LoggerFactory.getLogger(SootUpCallGraph.class); + + public SootUpCallGraph(sootup.callgraph.CallGraph callGraph, Collection entryPoints) { + + assert !entryPoints.isEmpty(); + assert !callGraph.getMethodSignatures().isEmpty(); + + // TODO: add a convenience method for this(edge collecting) to sootup + callGraph.getMethodSignatures().stream() + .flatMap((MethodSignature methodSignature) -> callGraph.callsTo(methodSignature).stream()) + .forEach( + call -> { + Optional sourceOpt = + SootUpFrameworkScope.getInstance().getSootMethod(call.getSourceMethodSignature()); + Optional targetOpt = + SootUpFrameworkScope.getInstance().getSootMethod(call.getTargetMethodSignature()); + + if (sourceOpt.isEmpty() || targetOpt.isEmpty()) { + return; + } + + JavaSootMethod sourceMethod = sourceOpt.get(); + JavaSootMethod targetMethod = targetOpt.get(); + if (!sourceMethod.hasBody() || !targetMethod.hasBody()) { + return; + } + + InvokableStmt invokableStmt = call.getInvokableStmt(); + if (!invokableStmt.containsInvokeExpr()) { + return; + } + + Statement callSite = + JimpleUpStatement.create(invokableStmt, JimpleUpMethod.of(sourceMethod)); + this.addEdge(new Edge(callSite, JimpleUpMethod.of(targetMethod))); + + LOGGER.trace("Added edge {} -> {}", callSite, targetMethod); + }); + + for (Method em : entryPoints) { + this.addEntryPoint(em); + LOGGER.trace("Added entry point: {}", em); + } + + if (getEdges().isEmpty()) { + throw new IllegalStateException("CallGraph is empty!"); + } + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScope.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScope.java new file mode 100644 index 00000000..837fe43f --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScope.java @@ -0,0 +1,32 @@ +package boomerang.framework.sootup; + +import boomerang.scene.DataFlowScope; +import boomerang.scene.DeclaredMethod; +import boomerang.scene.Method; +import boomerang.scene.WrappedClass; + +public class SootUpDataFlowScope { + + /** + * Default DataFlowScope that excludes native methods and methods from third-party libraries + * + * @return the dataflow scope + */ + public static DataFlowScope make() { + return new DataFlowScope() { + + @Override + public boolean isExcluded(DeclaredMethod method) { + WrappedClass declaringClass = method.getDeclaringClass(); + + return method.isNative() || !declaringClass.isApplicationClass(); + } + + public boolean isExcluded(Method method) { + WrappedClass declaringClass = method.getDeclaringClass(); + + return method.isNative() || !declaringClass.isApplicationClass(); + } + }; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScopeUtil.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScopeUtil.java new file mode 100644 index 00000000..4c9daf71 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScopeUtil.java @@ -0,0 +1,191 @@ +package boomerang.framework.sootup; + +import boomerang.scene.*; +import com.google.common.base.Predicate; +import com.google.common.collect.Sets; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sootup.core.types.ClassType; +import sootup.java.core.JavaSootClass; +import sootup.java.core.JavaSootMethod; +import sootup.java.core.types.JavaClassType; +import sootup.java.core.views.JavaView; + +public class SootUpDataFlowScopeUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(SootUpDataFlowScopeUtil.class); + private static final String HASH_CODE_SUB_SIG = "int hashCode()"; + private static final String TO_STRING_SUB_SIG = "java.lang.String toString()"; + private static final String EQUALS_SUB_SIG = "boolean equals(java.lang.Object)"; + private static final String CLONE_SIG = "java.lang.Object clone()"; + public static Predicate[] classFilters; + public static Predicate[] methodFilters; + + /** + * Default data-flow scope that only excludes phantom and native methods. + * + * @return + */ + public static DataFlowScope make(SootUpFrameworkScope scope) { + reset(scope); + return new DataFlowScope() { + @Override + public boolean isExcluded(DeclaredMethod method) { + JimpleUpDeclaredMethod m = (JimpleUpDeclaredMethod) method; + return m.getDeclaringClass().getDelegate() instanceof SootUpFrameworkScope.PhantomClass + || m.isNative(); + } + + public boolean isExcluded(Method method) { + JimpleUpMethod m = (JimpleUpMethod) method; + return m.getDeclaringClass().getDelegate() instanceof SootUpFrameworkScope.PhantomClass + || m.isNative(); + } + }; + } + + /** + * Excludes hashCode, toString, equals methods and the implementors of java.util.Collection, + * java.util.Maps and com.google.common.collect.Multimap + */ + public static DataFlowScope excludeComplex(SootUpFrameworkScope scope) { + reset(scope); + return new DataFlowScope() { + @Override + public boolean isExcluded(DeclaredMethod method) { + JimpleUpDeclaredMethod m = (JimpleUpDeclaredMethod) method; + for (Predicate f : classFilters) { + if (f.apply((JavaSootClass) m.getDeclaringClass().getDelegate())) { + return true; + } + } + for (Predicate f : methodFilters) { + if (f.apply(m.getDelegate())) { + return true; + } + } + return m.getDeclaringClass().getDelegate() instanceof SootUpFrameworkScope.PhantomClass + || m.isNative(); + } + + public boolean isExcluded(Method method) { + JimpleUpMethod m = (JimpleUpMethod) method; + for (Predicate f : classFilters) { + if (f.apply((JavaSootClass) m.getDeclaringClass().getDelegate())) { + return true; + } + } + for (Predicate f : methodFilters) { + if (f.apply(m.getDelegate())) { + return true; + } + } + return m.getDeclaringClass().getDelegate() instanceof SootUpFrameworkScope.PhantomClass + || m.isNative(); + } + }; + } + + private static class MapFilter implements Predicate { + private static final String MAP = "java.util.Map"; + private static final String GUAVA_MAP = "com.google.common.collect.Multimap"; + private final Set excludes = Sets.newHashSet(); + + public MapFilter(JavaView view) { + JavaClassType mapClassType = view.getIdentifierFactory().getClassType(MAP); + List mapSubClasses = + view.getTypeHierarchy().implementersOf(mapClassType).collect(Collectors.toList()); + excludes.add(mapClassType); + excludes.addAll(mapSubClasses); + + JavaClassType guavaMapType = view.getIdentifierFactory().getClassType(GUAVA_MAP); + Optional guavaMapOpt = view.getClass(guavaMapType); + if (guavaMapOpt.isPresent()) { + JavaSootClass c = guavaMapOpt.get(); + if (c.isInterface()) { + view.getTypeHierarchy().implementersOf(guavaMapType).forEach(excludes::add); + } + } + view.getClasses() + .filter( + c -> { + Optional outerClass = c.getOuterClass(); + return outerClass.isPresent() && excludes.contains(outerClass.get()); + }) + .forEach( + c -> { + excludes.add(guavaMapType); + }); + + if (excludes.isEmpty()) { + LOGGER.debug("Excludes empty for {}", MAP); + } + } + + @Override + public boolean apply(JavaSootClass c) { + return excludes.contains(c); + } + } + + private static class IterableFilter implements Predicate { + private static final String ITERABLE = "java.lang.Iterable"; + private final Set excludes = Sets.newHashSet(); + + public IterableFilter(JavaView view) { + JavaClassType iterableClassType = view.getIdentifierFactory().getClassType(ITERABLE); + + view.getTypeHierarchy().implementersOf(iterableClassType).forEach(excludes::add); + + view.getClasses() + .filter(c -> c.hasOuterClass() && excludes.contains(c.getOuterClass().get())) + .forEach( + c -> { + excludes.add(iterableClassType); + }); + + if (excludes.isEmpty()) { + LOGGER.debug("Excludes empty for {}", ITERABLE); + } + } + + @Override + public boolean apply(JavaSootClass c) { + return excludes.contains(c); + } + } + + private static class SubSignatureFilter implements Predicate { + private final Set excludes = Sets.newHashSet(); + + public SubSignatureFilter(SootUpFrameworkScope scope, String subSig) { + scope.getCallGraph().getReachableMethods().stream() + .map(Method::getSubSignature) + .filter(methodSig -> methodSig.equals(subSig)) + .forEach(excludes::add); + if (excludes.isEmpty()) { + LOGGER.debug("Excludes empty for {}", subSig); + } + } + + @Override + public boolean apply(JavaSootMethod m) { + return excludes.contains(m); + } + } + + private static void reset(SootUpFrameworkScope scope) { + classFilters = + new Predicate[] {new MapFilter(scope.getView()), new IterableFilter(scope.getView())}; + methodFilters = + new Predicate[] { + new SubSignatureFilter(scope, HASH_CODE_SUB_SIG), + new SubSignatureFilter(scope, TO_STRING_SUB_SIG), + new SubSignatureFilter(scope, EQUALS_SUB_SIG), + new SubSignatureFilter(scope, CLONE_SIG) + }; + } +} diff --git a/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpFrameworkScope.java b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpFrameworkScope.java new file mode 100644 index 00000000..58deffff --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpFrameworkScope.java @@ -0,0 +1,211 @@ +package boomerang.framework.sootup; + +import static boomerang.framework.sootup.SootUpDataFlowScopeUtil.excludeComplex; + +import boomerang.scene.*; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import sootup.core.inputlocation.EagerInputLocation; +import sootup.core.jimple.basic.NoPositionInformation; +import sootup.core.jimple.common.constant.IntConstant; +import sootup.core.model.ClassModifier; +import sootup.core.model.SourceType; +import sootup.core.signatures.FieldSignature; +import sootup.core.signatures.MethodSignature; +import sootup.core.types.ClassType; +import sootup.java.core.*; +import sootup.java.core.types.JavaClassType; +import sootup.java.core.views.JavaView; + +public class SootUpFrameworkScope implements FrameworkScope { + + @Nonnull protected final JavaView view; + @Nonnull protected final CallGraph cg; + @Nonnull protected final List entrypoints; + @Nonnull protected final DataFlowScope dataflowScope; + + public SootUpFrameworkScope( + @Nonnull JavaView view, + @Nonnull sootup.callgraph.CallGraph cg, + @Nonnull List entrypoints) { + INSTANCE = this; // FIXME! [ms] this hack is disgusting! + this.view = view; + this.entrypoints = + entrypoints.stream() + .map(ep -> view.getMethod(ep).get()) + .map(JimpleUpMethod::of) + .collect(Collectors.toList()); + + this.cg = new SootUpCallGraph(cg, getEntrypoints()); + dataflowScope = SootUpDataFlowScope.make(); + } + + private static SootUpFrameworkScope INSTANCE; + + public static SootUpFrameworkScope getInstance() { + if (INSTANCE == null) { + throw new RuntimeException("Client hasn't been initialized. Call setInstance first"); + } + return INSTANCE; + } + + @Override + public List getEntrypoints() { + return entrypoints; + } + + @Override + @Nonnull + public Val getTrueValue(Method m) { + return new JimpleUpVal(IntConstant.getInstance(1), m); + } + + @Override + @Nonnull + public Val getFalseValue(Method m) { + return new JimpleUpVal(IntConstant.getInstance(0), m); + } + + @Override + @Nonnull + public Stream handleStaticFieldInitializers(Val fact) { + JimpleUpStaticFieldVal val = ((JimpleUpStaticFieldVal) fact); + ClassType declaringClassType = + ((JimpleUpField) val.field()).getDelegate().getDeclaringClassType(); + + return view.getClass(declaringClassType).get().getMethods().stream() + .filter(sootup.core.model.SootMethod::hasBody) + .map(JimpleUpMethod::of); + } + + @Override + @Nonnull + public StaticFieldVal newStaticFieldVal(Field field, Method m) { + return new JimpleUpStaticFieldVal((JimpleUpField) field, m); + } + + @Nonnull + @Override + public Method getMethod(String signatureStr) { + return JimpleUpMethod.of( + view.getMethod(view.getIdentifierFactory().parseMethodSignature(signatureStr)).get()); + } + + @Override + public CallGraph getCallGraph() { + return cg; + } + + @Override + public DataFlowScope getDataFlowScope() { + return dataflowScope; + } + + @Override + public DataFlowScope createDataFlowScopeWithoutComplex() { + return excludeComplex(this); + } + + // --- + + private static final String CONSTRUCTOR_NAME = ""; + private static final String STATIC_INITIALIZER_NAME = ""; + + public JavaView getView() { + return view; + } + + public JavaIdentifierFactory getIdentifierFactory() { + return view.getIdentifierFactory(); + } + + public JavaSootClass getSootClass(JavaClassType classType) { + Optional sootClass = view.getClass(classType); + if (sootClass.isPresent()) { + return sootClass.get(); + } + + OverridingJavaClassSource phantomClassSource = + new OverridingJavaClassSource( + new EagerInputLocation(), + Paths.get("/phantom-class-in-memory"), + classType, + null, + Collections.emptySet(), + null, + Collections.emptySet(), + Collections.emptySet(), + NoPositionInformation.getInstance(), + EnumSet.noneOf(ClassModifier.class), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()); + return new PhantomClass(phantomClassSource, SourceType.Application); + } + + public Optional getSootMethod(MethodSignature methodSignature) { + Optional method = view.getMethod(methodSignature); + if (method.isPresent()) { + return method; + } + + // System.out.println("get" + methodSignature); + + Optional declaredClassOfMethod = + view.getTypeHierarchy() + .superClassesOf(methodSignature.getDeclClassType()) + .filter( + type -> { + // System.out.println("is it in? " + type); + Optional aClass = view.getClass(type); + return aClass + .map( + javaSootClass -> { + return javaSootClass + .getMethod(methodSignature.getSubSignature()) + .isPresent(); + }) + .orElse(false); + }) + .findAny(); + + if (declaredClassOfMethod.isEmpty()) { + return Optional.empty(); + } + ClassType declClassType = declaredClassOfMethod.get(); + + Optional aClass = view.getClass(declClassType); + return aClass.flatMap( + javaSootClass -> javaSootClass.getMethod(methodSignature.getSubSignature())); + // throw new RuntimeException("Method not found: " + methodSignature); + } + + public JavaSootField getSootField(FieldSignature fieldSignature) { + Optional field = view.getField(fieldSignature); + if (field.isPresent()) { + return field.get(); + } + throw new RuntimeException("Field not found: " + fieldSignature); + } + + public static boolean isConstructor(JavaSootMethod sootMethod) { + return sootMethod.getSignature().getName().equals(CONSTRUCTOR_NAME); + } + + public static boolean isStaticInitializer(JavaSootMethod sootMethod) { + return sootMethod.getSignature().getName().equals(STATIC_INITIALIZER_NAME); + } + + /** Dummy Phantom Class representation to mimic what Soot would do */ + public static class PhantomClass extends JavaSootClass { + public PhantomClass(JavaSootClassSource classSource, SourceType sourceType) { + super(classSource, sourceType); + } + } +} diff --git a/boomerangScope-SootUp/src/main/java/sootup/ScopedAnalysisInputLocation.java b/boomerangScope-SootUp/src/main/java/sootup/ScopedAnalysisInputLocation.java new file mode 100644 index 00000000..432d29a0 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/sootup/ScopedAnalysisInputLocation.java @@ -0,0 +1,114 @@ +package sootup; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import sootup.core.frontend.SootClassSource; +import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.model.SourceType; +import sootup.core.transform.BodyInterceptor; +import sootup.core.types.ClassType; +import sootup.core.views.View; + +/** + * Base class for filtering ClassSources returned from the underlying AnalysisInputLocation you need + * to override the filter function - e.g. override it in an anonymous class (TODO: remov + * ScopedAnalysisInputLocation as it is already in an upstream PR - innerclasses need to be kept) + */ +public abstract class ScopedAnalysisInputLocation implements AnalysisInputLocation { + + @Nonnull private final AnalysisInputLocation inputLocation; + + public ScopedAnalysisInputLocation(@Nonnull AnalysisInputLocation inputLocation) { + this.inputLocation = inputLocation; + } + + /** Override this method. */ + protected abstract boolean filter(@Nonnull ClassType type); + + @Nonnull + @Override + public Optional getClassSource( + @Nonnull ClassType type, @Nonnull View view) { + if (!filter(type)) { + return Optional.empty(); + } + return inputLocation.getClassSource(type, view); + } + + @Nonnull + @Override + public Stream getClassSources(@Nonnull View view) { + return inputLocation.getClassSources(view).filter(type -> filter(type.getClassType())); + } + + @Nonnull + @Override + public SourceType getSourceType() { + return inputLocation.getSourceType(); + } + + @Nonnull + @Override + public List getBodyInterceptors() { + return inputLocation.getBodyInterceptors(); + } + + public static class AllowlistingScopedAnalysisInputLocation extends ScopedAnalysisInputLocation { + + private final Collection allowlist; + + protected String mapStr(String s) { + + // TODO: adapt from soots: isIncluded() + // if (className.equals(pkg) + // || ((pkg.endsWith(".*") || pkg.endsWith("$*")) && + // className.startsWith(pkg.substring(0, pkg.length() - 1)))) { + if (!s.endsWith(".*")) { + throw new IllegalStateException("filter method is not implemented for a specific class!"); + } + return s.substring(0, s.length() - 2); + } + + public AllowlistingScopedAnalysisInputLocation( + @Nonnull AnalysisInputLocation inputLocation, Collection allowlist) { + super(inputLocation); + this.allowlist = allowlist.stream().map(this::mapStr).collect(Collectors.toList()); + } + + @Override + protected boolean filter(@Nonnull ClassType type) { + return allowlist.contains(type.getPackageName().toString()); + } + } + + public static class DenylistingScopedAnalysisInputLocation extends ScopedAnalysisInputLocation { + + private final Collection denylist; + + protected String mapStr(String s) { + // TODO: adapt from soots: isIncluded() + // if (className.equals(pkg) + // || ((pkg.endsWith(".*") || pkg.endsWith("$*")) && + // className.startsWith(pkg.substring(0, pkg.length() - 1)))) { + if (!s.endsWith(".*")) { + throw new IllegalStateException("filter method is not implemented for a specific class!"); + } + return s.substring(0, s.length() - 2); + } + + public DenylistingScopedAnalysisInputLocation( + @Nonnull AnalysisInputLocation inputLocation, Collection denylist) { + super(inputLocation); + this.denylist = denylist.stream().map(this::mapStr).collect(Collectors.toList()); + } + + @Override + protected boolean filter(@Nonnull ClassType type) { + return !denylist.contains(type.getPackageName().toString()); + } + } +} diff --git a/boomerangScope-SootUp/src/main/java/sootup/SourceTypeSplittingAnalysisInputLocation.java b/boomerangScope-SootUp/src/main/java/sootup/SourceTypeSplittingAnalysisInputLocation.java new file mode 100644 index 00000000..ceacd615 --- /dev/null +++ b/boomerangScope-SootUp/src/main/java/sootup/SourceTypeSplittingAnalysisInputLocation.java @@ -0,0 +1,126 @@ +package sootup; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import javax.annotation.Nonnull; +import sootup.core.frontend.SootClassSource; +import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.model.SourceType; +import sootup.core.transform.BodyInterceptor; +import sootup.core.types.ClassType; +import sootup.core.views.View; + +/** Mimics Soots includePackage / excludePackage behaviour */ +public abstract class SourceTypeSplittingAnalysisInputLocation implements AnalysisInputLocation { + + @Nonnull + protected abstract AnalysisInputLocation getInputLocation(); + + @Nonnull + @Override + public abstract SourceType getSourceType(); + + protected abstract boolean filter(@Nonnull ClassType type); + + private static boolean filterConditionCheck(String pkg, String className) { + if (className.equals(pkg)) { + return true; + } + if (pkg.endsWith(".*") || pkg.endsWith("$*")) { + return className.startsWith(pkg.substring(0, pkg.length() - 1)); + } + return false; + } + + @Nonnull + @Override + public Optional getClassSource( + @Nonnull ClassType type, @Nonnull View view) { + if (filter(type)) { + return getInputLocation().getClassSource(type, view); + } + return Optional.empty(); + } + + @Nonnull + @Override + public Stream getClassSources(@Nonnull View view) { + return getInputLocation().getClassSources(view).filter(type -> filter(type.getClassType())); + } + + @Nonnull + @Override + public List getBodyInterceptors() { + return getInputLocation().getBodyInterceptors(); + } + + public static class LibraryAnalysisInputLocation + extends SourceTypeSplittingAnalysisInputLocation { + + @Nonnull private final SourceTypeSplittingAnalysisInputLocation inputLocation; + private final Collection excludes; + + public LibraryAnalysisInputLocation( + @Nonnull SourceTypeSplittingAnalysisInputLocation inputLocation, + Collection excludes) { + this.inputLocation = inputLocation; + this.excludes = excludes; + } + + @Override + protected AnalysisInputLocation getInputLocation() { + return inputLocation; + } + + protected boolean filter(@Nonnull ClassType type) { + String className = type.getFullyQualifiedName(); + for (String pkg : excludes) { + if (filterConditionCheck(pkg, className)) { + return !inputLocation.filter(type); + } + } + return false; + } + + @Nonnull + @Override + public SourceType getSourceType() { + return SourceType.Library; + } + } + + public static class ApplicationAnalysisInputLocation + extends SourceTypeSplittingAnalysisInputLocation { + private final Collection includes; + @Nonnull private final AnalysisInputLocation inputLocation; + + @Override + protected AnalysisInputLocation getInputLocation() { + return inputLocation; + } + + public ApplicationAnalysisInputLocation( + @Nonnull AnalysisInputLocation inputLocation, Collection includes) { + this.inputLocation = inputLocation; + this.includes = includes; + } + + protected boolean filter(@Nonnull ClassType type) { + String className = type.getFullyQualifiedName(); + for (String pkg : includes) { + if (filterConditionCheck(pkg, className)) { + return true; + } + } + return false; + } + + @Nonnull + @Override + public SourceType getSourceType() { + return SourceType.Application; + } + } +} diff --git a/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..531e9dbe --- /dev/null +++ b/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,31 @@ +boomerang/framework/sootup/JimpleUpIfStatement.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil$MapFilter.class +boomerang/framework/sootup/JimpleUpDeclaredMethod.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil$IterableFilter.class +boomerang/framework/sootup/JimpleUpInvokeExpr.class +boomerang/framework/sootup/SootUpFrameworkScope$PhantomClass.class +sootup/ScopedAnalysisInputLocation.class +boomerang/framework/sootup/SootUpCallGraph.class +boomerang/framework/sootup/SootUpFrameworkScope.class +boomerang/framework/sootup/JimpleUpVal.class +boomerang/framework/sootup/JimpleUpMethod.class +boomerang/framework/sootup/JimpleUpType.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil$2.class +sootup/SourceTypeSplittingAnalysisInputLocation$ApplicationAnalysisInputLocation.class +boomerang/framework/sootup/JimpleUpControlFlowGraph.class +boomerang/framework/sootup/JimpleUpStaticFieldVal.class +boomerang/framework/sootup/JimpleUpWrappedClass.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil.class +boomerang/framework/sootup/SootUpDataFlowScope.class +sootup/ScopedAnalysisInputLocation$AllowlistingScopedAnalysisInputLocation.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil$SubSignatureFilter.class +boomerang/framework/sootup/JimpleUpField.class +sootup/ScopedAnalysisInputLocation$DenylistingScopedAnalysisInputLocation.class +boomerang/framework/sootup/SootUpDataFlowScope$1.class +boomerang/framework/sootup/BoomerangPreInterceptor.class +sootup/SourceTypeSplittingAnalysisInputLocation.class +boomerang/framework/sootup/JimpleUpInstanceFieldRef.class +boomerang/framework/sootup/SootUpDataFlowScopeUtil$1.class +boomerang/framework/sootup/JimpleUpDoubleVal.class +boomerang/framework/sootup/JimpleUpStatement.class +sootup/SourceTypeSplittingAnalysisInputLocation$LibraryAnalysisInputLocation.class diff --git a/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..7799009e --- /dev/null +++ b/boomerangScope-SootUp/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,20 @@ +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/BoomerangPreInterceptor.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpControlFlowGraph.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDeclaredMethod.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpDoubleVal.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpField.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpIfStatement.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInstanceFieldRef.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpInvokeExpr.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpMethod.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStatement.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStaticFieldVal.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpType.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpVal.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpWrappedClass.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpCallGraph.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScope.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpDataFlowScopeUtil.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/SootUpFrameworkScope.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/sootup/ScopedAnalysisInputLocation.java +/home/smarkus/workspace/Java/SparseBoomerang/boomerangScope-SootUp/src/main/java/sootup/SourceTypeSplittingAnalysisInputLocation.java diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALACallGraph.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALACallGraph.java similarity index 95% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALACallGraph.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALACallGraph.java index 3df7e6cc..b80a1d94 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALACallGraph.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALACallGraph.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.CallGraph; import com.google.common.base.Stopwatch; @@ -30,8 +30,8 @@ public class WALACallGraph extends CallGraph { - private Map iMethodToWALAMethod = new HashMap<>(); - private IClassHierarchy cha; + private final Map iMethodToWALAMethod = new HashMap<>(); + private final IClassHierarchy cha; public WALACallGraph(com.ibm.wala.ipa.callgraph.CallGraph cg, IClassHierarchy cha) { this.cha = cha; diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAClass.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAClass.java similarity index 94% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAClass.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAClass.java index 276c0f84..acfac5d7 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAClass.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAClass.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.Method; import boomerang.scene.Type; @@ -71,9 +71,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALAClass other = (WALAClass) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAControlFlowGraph.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAControlFlowGraph.java similarity index 95% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAControlFlowGraph.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAControlFlowGraph.java index 261716ca..0190f80f 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAControlFlowGraph.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAControlFlowGraph.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.ControlFlowGraph; import boomerang.scene.Method; @@ -40,10 +40,10 @@ public class WALAControlFlowGraph implements ControlFlowGraph { - private Method method; - private SSACFG cfg; - private IClassHierarchy cha; - private Map basicBlockToFirstStmt = Maps.newHashMap(); + private final Method method; + private final SSACFG cfg; + private final IClassHierarchy cha; + private final Map basicBlockToFirstStmt = Maps.newHashMap(); public WALAControlFlowGraph(WALAMethod method, IClassHierarchy cha) { this.method = method; @@ -53,11 +53,11 @@ public WALAControlFlowGraph(WALAMethod method, IClassHierarchy cha) { } private boolean cacheBuild = false; - private List startPointCache = Lists.newArrayList(); - private List endPointCache = Lists.newArrayList(); - private Multimap succsOfCache = HashMultimap.create(); - private Multimap predsOfCache = HashMultimap.create(); - private List statements = Lists.newArrayList(); + private final List startPointCache = Lists.newArrayList(); + private final List endPointCache = Lists.newArrayList(); + private final Multimap succsOfCache = HashMultimap.create(); + private final Multimap predsOfCache = HashMultimap.create(); + private final List statements = Lists.newArrayList(); public Collection getStartPoints() { buildCache(); diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADataFlowScope.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADataFlowScope.java similarity index 97% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADataFlowScope.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADataFlowScope.java index ba0b3106..03eeed5e 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADataFlowScope.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADataFlowScope.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.DataFlowScope; import boomerang.scene.DeclaredMethod; diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADeclaredMethod.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADeclaredMethod.java similarity index 90% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADeclaredMethod.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADeclaredMethod.java index eadea317..d683d4ea 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADeclaredMethod.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADeclaredMethod.java @@ -9,10 +9,11 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.DeclaredMethod; import boomerang.scene.InvokeExpr; +import boomerang.scene.Method; import boomerang.scene.Type; import boomerang.scene.WrappedClass; import com.ibm.wala.types.MethodReference; @@ -59,6 +60,11 @@ public String getSignature() { return delegate.getSignature(); } + @Override + public Method getCalledMethod() { + throw new RuntimeException("Not implemented"); + } + @Override public WrappedClass getDeclaringClass() { return new WALAClass(delegate.getDeclaringClass()); @@ -94,9 +100,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALADeclaredMethod other = (WALADeclaredMethod) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyNullStatement.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyNullStatement.java similarity index 96% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyNullStatement.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyNullStatement.java index 9002e5d9..c0b36297 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyNullStatement.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyNullStatement.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.Field; import boomerang.scene.IfStatement; @@ -25,8 +25,8 @@ public class WALADummyNullStatement extends WALAStatement { - private Val leftOp; - private WALAVal rightOp; + private final Val leftOp; + private final WALAVal rightOp; public WALADummyNullStatement(Val a, Method method) { super(a + " = null", method); @@ -245,9 +245,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALADummyNullStatement other = (WALADummyNullStatement) obj; if (leftOp == null) { - if (other.leftOp != null) return false; - } else if (!leftOp.equals(other.leftOp)) return false; - return true; + return other.leftOp == null; + } else return leftOp.equals(other.leftOp); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyVal.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyVal.java similarity index 97% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyVal.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyVal.java index 260ff5c1..15f60ccd 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALADummyVal.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALADummyVal.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.Type; import com.ibm.wala.analysis.typeInference.TypeAbstraction; diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAField.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAField.java similarity index 87% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAField.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAField.java index 46a3ecc9..e502eaec 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAField.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAField.java @@ -9,14 +9,14 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.Field; import com.ibm.wala.types.FieldReference; public class WALAField extends Field { - private FieldReference fieldRef; + private final FieldReference fieldRef; public WALAField(FieldReference fieldRef) { this.fieldRef = fieldRef; @@ -37,9 +37,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALAField other = (WALAField) obj; if (fieldRef == null) { - if (other.fieldRef != null) return false; - } else if (!fieldRef.equals(other.fieldRef)) return false; - return true; + return other.fieldRef == null; + } else return fieldRef.equals(other.fieldRef); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAIfStatement.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAIfStatement.java similarity index 92% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAIfStatement.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAIfStatement.java index 9065e15b..03c2d623 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAIfStatement.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAIfStatement.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.IfStatement; import boomerang.scene.Statement; @@ -19,9 +19,9 @@ public class WALAIfStatement implements IfStatement { - private SSAConditionalBranchInstruction delegate; - private WALAMethod method; - private Statement target; + private final SSAConditionalBranchInstruction delegate; + private final WALAMethod method; + private final Statement target; public WALAIfStatement(SSAConditionalBranchInstruction delegate, WALAMethod method) { this.delegate = delegate; diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAInvokeExpr.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAInvokeExpr.java similarity index 94% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAInvokeExpr.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAInvokeExpr.java index 178dd06b..7088239c 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAInvokeExpr.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAInvokeExpr.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.DeclaredMethod; import boomerang.scene.InvokeExpr; @@ -20,8 +20,8 @@ public class WALAInvokeExpr implements InvokeExpr { - private SSAAbstractInvokeInstruction inv; - private WALAMethod m; + private final SSAAbstractInvokeInstruction inv; + private final WALAMethod m; private List argsCache; public WALAInvokeExpr(SSAAbstractInvokeInstruction inv, WALAMethod m) { diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAMethod.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAMethod.java similarity index 89% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAMethod.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAMethod.java index e0d4566c..26170dcc 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAMethod.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAMethod.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.ControlFlowGraph; import boomerang.scene.Method; @@ -25,18 +25,19 @@ import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.ipa.cha.IClassHierarchy; import com.ibm.wala.ssa.IR; +import java.util.ArrayList; import java.util.List; import java.util.Set; public class WALAMethod extends Method { - private IMethod delegate; - private WALAControlFlowGraph cfg; - private IR ir; + private final IMethod delegate; + private final WALAControlFlowGraph cfg; + private final IR ir; private List paramLocalCache; private Set valueCache; - private TypeInference typeInference; - private IClassHierarchy cha; + private final TypeInference typeInference; + private final IClassHierarchy cha; public WALAMethod(IMethod delegate, IR ir, IClassHierarchy cha) { this.delegate = delegate; @@ -62,12 +63,18 @@ public boolean isParameterLocal(Val val) { @Override public List getParameterTypes() { - throw new UnsupportedOperationException("Not implemented yet"); + List types = new ArrayList<>(); + + for (Val val : getParameterLocals()) { + types.add(val.getType()); + } + + return types; } @Override public Type getParameterType(int index) { - throw new UnsupportedOperationException("Not implemented yet"); + return getParameterLocals().get(index).getType(); } @Override @@ -161,9 +168,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALAMethod other = (WALAMethod) obj; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } IR getIR() { diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStatement.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStatement.java similarity index 92% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStatement.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStatement.java index ced1e431..3fc68e32 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStatement.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStatement.java @@ -9,8 +9,9 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; +import boomerang.framework.wala.WALAVal.OP; import boomerang.scene.Field; import boomerang.scene.IfStatement; import boomerang.scene.InvokeExpr; @@ -19,7 +20,6 @@ import boomerang.scene.Statement; import boomerang.scene.StaticFieldVal; import boomerang.scene.Val; -import boomerang.scene.wala.WALAVal.OP; import com.google.common.collect.Lists; import com.ibm.wala.cast.loader.AstMethod; import com.ibm.wala.classLoader.IBytecodeMethod; @@ -105,9 +105,7 @@ public boolean isFieldLoadWithBase(Val base) { public boolean isReturnOperator(Val val) { if (isReturnStmt()) { SSAReturnInstruction ins = (SSAReturnInstruction) delegate; - return ins.getResult() == -1 - ? false - : new WALAVal(ins.getResult(), (WALAMethod) method).equals(val); + return ins.getResult() != -1 && new WALAVal(ins.getResult(), (WALAMethod) method).equals(val); } return false; } @@ -144,9 +142,7 @@ public boolean isAssign() { private boolean isAssigningCall() { if (containsInvokeExpr()) { - if (((SSAAbstractInvokeInstruction) delegate).getNumberOfReturnValues() > 0) { - return true; - } + return ((SSAAbstractInvokeInstruction) delegate).getNumberOfReturnValues() > 0; } return false; } @@ -158,7 +154,7 @@ private boolean isAllocationStatement() { @Override public Val getLeftOp() { if (isFieldLoad() || isStaticFieldLoad()) { - return new WALAVal(((SSAGetInstruction) delegate).getDef(), (WALAMethod) method); + return new WALAVal(delegate.getDef(), (WALAMethod) method); } if (isFieldStore()) { // The left op of a statement x.f = y must be the complete term x.f @@ -166,25 +162,24 @@ public Val getLeftOp() { } if (isStaticFieldStore()) { return new WALAStaticFieldVal( - new WALAField(((SSAFieldAccessInstruction) delegate).getDeclaredField()), - (WALAMethod) method); + new WALAField(((SSAFieldAccessInstruction) delegate).getDeclaredField()), method); } if (isAllocationStatement()) { - return new WALAVal(((SSANewInstruction) delegate).getDef(), (WALAMethod) method); + return new WALAVal(delegate.getDef(), (WALAMethod) method); } if (isPhiStatement()) { - return new WALAVal(((SSAPhiInstruction) delegate).getDef(), (WALAMethod) method); + return new WALAVal(delegate.getDef(), (WALAMethod) method); } if (isAssigningCall()) { return new WALAVal( ((SSAAbstractInvokeInstruction) delegate).getReturnValue(0), (WALAMethod) method); } if (isCast()) { - return new WALAVal(((SSACheckCastInstruction) delegate).getDef(), (WALAMethod) method); + return new WALAVal(delegate.getDef(), (WALAMethod) method); } if (isArrayLoad()) { - return new WALAVal(((SSAArrayLoadInstruction) delegate).getDef(), (WALAMethod) method); + return new WALAVal(delegate.getDef(), (WALAMethod) method); } if (isArrayStore()) { @@ -220,8 +215,7 @@ public Val getRightOp() { } if (isStaticFieldLoad()) { return new WALAStaticFieldVal( - new WALAField(((SSAFieldAccessInstruction) delegate).getDeclaredField()), - (WALAMethod) method); + new WALAField(((SSAFieldAccessInstruction) delegate).getDeclaredField()), method); } return null; } @@ -357,7 +351,7 @@ public int hashCode() { final int prime = 31; int result = super.hashCode(); if (delegate instanceof SSAPhiInstruction) { - result = prime * result + ((SSAPhiInstruction) delegate).getDef(); + result = prime * result + delegate.getDef(); } result = prime * result + ((delegate == null) ? 0 : delegate.hashCode()); result = prime * result + ((rep == null) ? 0 : rep.hashCode()); @@ -380,9 +374,7 @@ public boolean equals(Object obj) { if (other.rep != null) return false; } else if (!rep.equals(other.rep)) return false; if (delegate instanceof SSAPhiInstruction && other.delegate instanceof SSAPhiInstruction) { - if (!phiEquals((SSAPhiInstruction) delegate, (SSAPhiInstruction) other.delegate)) { - return false; - } + return phiEquals((SSAPhiInstruction) delegate, (SSAPhiInstruction) other.delegate); } return true; } diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStaticFieldVal.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStaticFieldVal.java similarity index 95% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStaticFieldVal.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStaticFieldVal.java index 39557978..32d7cf7b 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAStaticFieldVal.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAStaticFieldVal.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Field; @@ -21,7 +21,7 @@ public class WALAStaticFieldVal extends StaticFieldVal { - private Field declaredField; + private final Field declaredField; public WALAStaticFieldVal(Field declaredField, Method method) { this(declaredField, method, null); @@ -172,9 +172,8 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; WALAStaticFieldVal other = (WALAStaticFieldVal) obj; if (declaredField == null) { - if (other.declaredField != null) return false; - } else if (!declaredField.equals(other.declaredField)) return false; - return true; + return other.declaredField == null; + } else return declaredField.equals(other.declaredField); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAType.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAType.java similarity index 97% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAType.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAType.java index 9c1e2e81..d99a76a8 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAType.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAType.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.AllocVal; import boomerang.scene.Type; @@ -110,8 +110,7 @@ public boolean isSubtypeOf(String type) { return true; } } - if (typeAbstraction.equals(TypeAbstraction.TOP)) return true; - return false; + return typeAbstraction.equals(TypeAbstraction.TOP); } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAUnitializedFieldStatement.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAUnitializedFieldStatement.java similarity index 95% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAUnitializedFieldStatement.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAUnitializedFieldStatement.java index a5e8841c..5b794940 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAUnitializedFieldStatement.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAUnitializedFieldStatement.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.Field; import boomerang.scene.IfStatement; @@ -22,10 +22,10 @@ public class WALAUnitializedFieldStatement extends WALAStatement { - private WALAField field; - private WALAMethod method; - private Val thisLocal; - private Val rightOp; + private final WALAField field; + private final WALAMethod method; + private final Val thisLocal; + private final Val rightOp; public WALAUnitializedFieldStatement( WALAField field, WALAMethod method, Val thisLocal, Val rightOp) { diff --git a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAVal.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAVal.java similarity index 98% rename from boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAVal.java rename to boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAVal.java index 359935be..b02ed11b 100644 --- a/boomerangScope-WALA/src/main/java/boomerang/scene/wala/WALAVal.java +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WALAVal.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package boomerang.scene.wala; +package boomerang.framework.wala; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.Method; @@ -34,7 +34,7 @@ public class WALAVal extends Val { private final SSAInstruction ssaInstruction; private final OP op; - public static enum OP { + public enum OP { LEFT, RIGHT } @@ -284,8 +284,7 @@ public boolean equals(Object obj) { if (ssaInstruction == null) { if (other.ssaInstruction != null) return false; } else if (!ssaInstruction.equals(other.ssaInstruction)) return false; - if (programCounter != other.programCounter) return false; - return true; + return programCounter == other.programCounter; } @Override diff --git a/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WalaFrameworkScope.java b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WalaFrameworkScope.java new file mode 100644 index 00000000..0ade0dd3 --- /dev/null +++ b/boomerangScope-WALA/src/main/java/boomerang/framework/wala/WalaFrameworkScope.java @@ -0,0 +1,55 @@ +package boomerang.framework.wala; + +import boomerang.scene.*; +import java.util.List; +import java.util.stream.Stream; +import javax.annotation.Nonnull; + +public class WalaFrameworkScope implements FrameworkScope { + + @Override + public Val getTrueValue(Method m) { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public Val getFalseValue(Method m) { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public Stream handleStaticFieldInitializers(Val fact) { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public StaticFieldVal newStaticFieldVal(Field field, Method m) { + throw new UnsupportedOperationException("implement me!"); + } + + @Nonnull + @Override + public Method getMethod(String signatureStr) { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public CallGraph getCallGraph() { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public DataFlowScope getDataFlowScope() { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public DataFlowScope createDataFlowScopeWithoutComplex() { + throw new UnsupportedOperationException("implement me!"); + } + + @Override + public List getEntrypoints() { + throw new UnsupportedOperationException("implement me!"); + } +} diff --git a/boomerangScope-WALA/src/test/java/example/ExampleMain1.java b/boomerangScope-WALA/src/test/java/example/ExampleMain1.java index 28f08a0b..b046aa77 100644 --- a/boomerangScope-WALA/src/test/java/example/ExampleMain1.java +++ b/boomerangScope-WALA/src/test/java/example/ExampleMain1.java @@ -15,14 +15,11 @@ import boomerang.Boomerang; import boomerang.DefaultBoomerangOptions; import boomerang.Query; +import boomerang.framework.wala.WALACallGraph; +import boomerang.framework.wala.WalaFrameworkScope; import boomerang.results.BackwardBoomerangResults; -import boomerang.scene.AnalysisScope; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.wala.WALACallGraph; import com.google.common.collect.Lists; import com.ibm.wala.classLoader.IMethod; import com.ibm.wala.core.util.config.AnalysisScopeReader; @@ -106,7 +103,9 @@ protected Collection generate(Edge edge) { } }; // 1. Create a Boomerang solver. - Boomerang solver = new Boomerang(cg, DataFlowScope.INCLUDE_ALL, new DefaultBoomerangOptions()); + Boomerang solver = + new Boomerang( + cg, DataFlowScope.INCLUDE_ALL, new DefaultBoomerangOptions(), new WalaFrameworkScope()); // 2. Submit a query to the solver. Collection seeds = scope.computeSeeds(); diff --git a/boomerangScope/pom.xml b/boomerangScope/pom.xml index 275a488c..558cd60c 100644 --- a/boomerangScope/pom.xml +++ b/boomerangScope/pom.xml @@ -7,19 +7,18 @@ 4.0.0 boomerangScope - - junit - junit - - - org.soot-oss - soot + de.fraunhofer.iem + PDS - de.fraunhofer.iem - synchronizedPDS + com.google.guava + guava + + org.slf4j + slf4j-api + \ No newline at end of file diff --git a/boomerangScope/src/main/java/boomerang/scene/AllocVal.java b/boomerangScope/src/main/java/boomerang/scene/AllocVal.java index cba420a4..0dca12ae 100644 --- a/boomerangScope/src/main/java/boomerang/scene/AllocVal.java +++ b/boomerangScope/src/main/java/boomerang/scene/AllocVal.java @@ -4,9 +4,9 @@ public class AllocVal extends Val { - private Val delegate; - private Val allocationVal; - private Statement allocStatement; + private final Val delegate; + private final Val allocationVal; + private final Statement allocStatement; public AllocVal(Val delegate, Statement allocStatement, Val allocationVal) { super(); @@ -159,9 +159,8 @@ public boolean equals(Object obj) { if (other.allocationVal != null) return false; } else if (!allocationVal.equals(other.allocationVal)) return false; if (delegate == null) { - if (other.delegate != null) return false; - } else if (!delegate.equals(other.delegate)) return false; - return true; + return other.delegate == null; + } else return delegate.equals(other.delegate); } public Val getAllocVal() { diff --git a/boomerangScope/src/main/java/boomerang/scene/CallGraph.java b/boomerangScope/src/main/java/boomerang/scene/CallGraph.java index 17d43d50..2f7b68da 100644 --- a/boomerangScope/src/main/java/boomerang/scene/CallGraph.java +++ b/boomerangScope/src/main/java/boomerang/scene/CallGraph.java @@ -8,12 +8,12 @@ public class CallGraph { - private Set edges = Sets.newHashSet(); - private Multimap edgesOutOf = HashMultimap.create(); - private Multimap edgesInto = HashMultimap.create(); - private Set entryPoints = Sets.newHashSet(); - private Multimap fieldLoadStatements = HashMultimap.create(); - private Multimap fieldStoreStatements = HashMultimap.create(); + private final Set edges = Sets.newHashSet(); + private final Multimap edgesOutOf = HashMultimap.create(); + private final Multimap edgesInto = HashMultimap.create(); + private final Set entryPoints = Sets.newHashSet(); + private final Multimap fieldLoadStatements = HashMultimap.create(); + private final Multimap fieldStoreStatements = HashMultimap.create(); public Collection edgesOutOf(Statement stmt) { return edgesOutOf.get(stmt); @@ -57,9 +57,8 @@ public boolean equals(Object obj) { if (other.callSite != null) return false; } else if (!callSite.equals(other.callSite)) return false; if (callee == null) { - if (other.callee != null) return false; - } else if (!callee.equals(other.callee)) return false; - return true; + return other.callee == null; + } else return callee.equals(other.callee); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/ControlFlowGraph.java b/boomerangScope/src/main/java/boomerang/scene/ControlFlowGraph.java index 89b81347..7a90fa8d 100644 --- a/boomerangScope/src/main/java/boomerang/scene/ControlFlowGraph.java +++ b/boomerangScope/src/main/java/boomerang/scene/ControlFlowGraph.java @@ -1,8 +1,8 @@ package boomerang.scene; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.List; -import wpds.interfaces.Location; public interface ControlFlowGraph { diff --git a/boomerangScope/src/main/java/boomerang/scene/DataFlowScope.java b/boomerangScope/src/main/java/boomerang/scene/DataFlowScope.java index 58abf60c..84bfe5f0 100644 --- a/boomerangScope/src/main/java/boomerang/scene/DataFlowScope.java +++ b/boomerangScope/src/main/java/boomerang/scene/DataFlowScope.java @@ -15,7 +15,7 @@ public boolean isExcluded(Method method) { } }; - public boolean isExcluded(DeclaredMethod method); + boolean isExcluded(DeclaredMethod method); - public boolean isExcluded(Method method); + boolean isExcluded(Method method); } diff --git a/boomerangScope/src/main/java/boomerang/scene/DeclaredMethod.java b/boomerangScope/src/main/java/boomerang/scene/DeclaredMethod.java index 14abe0eb..fe00e6c4 100644 --- a/boomerangScope/src/main/java/boomerang/scene/DeclaredMethod.java +++ b/boomerangScope/src/main/java/boomerang/scene/DeclaredMethod.java @@ -22,6 +22,8 @@ public DeclaredMethod(InvokeExpr inv) { public abstract String getSignature(); + public abstract Method getCalledMethod(); + public abstract WrappedClass getDeclaringClass(); public abstract List getParameterTypes(); diff --git a/boomerangScope/src/main/java/boomerang/scene/Field.java b/boomerangScope/src/main/java/boomerang/scene/Field.java index 66ebb882..7ceec607 100644 --- a/boomerangScope/src/main/java/boomerang/scene/Field.java +++ b/boomerangScope/src/main/java/boomerang/scene/Field.java @@ -12,10 +12,10 @@ package boomerang.scene; import com.google.common.base.Objects; -import wpds.interfaces.Empty; -import wpds.interfaces.Location; -import wpds.wildcard.ExclusionWildcard; -import wpds.wildcard.Wildcard; +import de.fraunhofer.iem.Empty; +import de.fraunhofer.iem.Location; +import de.fraunhofer.iem.wildcard.ExclusionWildcard; +import de.fraunhofer.iem.wildcard.Wildcard; public class Field implements Location { private final String rep; @@ -49,13 +49,8 @@ public boolean equals(Object obj) { } Field other = (Field) obj; if (rep == null) { - if (other.rep != null) { - return false; - } - } else if (!rep.equals(other.rep)) { - return false; - } - return true; + return other.rep == null; + } else return rep.equals(other.rep); } @Override @@ -135,13 +130,8 @@ public boolean equals(Object obj) { } ExclusionWildcardField other = (ExclusionWildcardField) obj; if (excludes == null) { - if (other.excludes != null) { - return false; - } - } else if (!excludes.equals(other.excludes)) { - return false; - } - return true; + return other.excludes == null; + } else return excludes.equals(other.excludes); } } diff --git a/boomerangScope/src/main/java/boomerang/scene/FrameworkScope.java b/boomerangScope/src/main/java/boomerang/scene/FrameworkScope.java new file mode 100644 index 00000000..78b5ffd6 --- /dev/null +++ b/boomerangScope/src/main/java/boomerang/scene/FrameworkScope.java @@ -0,0 +1,31 @@ +package boomerang.scene; + +import java.util.List; +import java.util.stream.Stream; +import javax.annotation.Nonnull; + +public interface FrameworkScope { + + List getEntrypoints(); + + Val getTrueValue(Method m); + + Val getFalseValue(Method m); + + Stream handleStaticFieldInitializers(Val fact); + + StaticFieldVal newStaticFieldVal(Field field, Method m); + + // TODO: [ms] maybe refactor it - currently its only used in testcases + @Nonnull + Method getMethod(String signatureStr); + + // TODO: [ms] maybe refactor it - currently its only used in testcases + CallGraph getCallGraph(); + + // TODO: [ms] maybe refactor it - currently its only used in testcases + DataFlowScope getDataFlowScope(); + + // TODO: [ms] maybe refactor it - currently its only used in testcases + DataFlowScope createDataFlowScopeWithoutComplex(); +} diff --git a/boomerangScope/src/main/java/boomerang/scene/IfStatement.java b/boomerangScope/src/main/java/boomerang/scene/IfStatement.java index 24fd1c85..b3d5cb89 100644 --- a/boomerangScope/src/main/java/boomerang/scene/IfStatement.java +++ b/boomerangScope/src/main/java/boomerang/scene/IfStatement.java @@ -5,7 +5,7 @@ enum Evaluation { TRUE, FALSE, UNKOWN - }; + } Statement getTarget(); diff --git a/boomerangScope/src/main/java/boomerang/scene/InstanceFieldRef.java b/boomerangScope/src/main/java/boomerang/scene/InstanceFieldRef.java index 12c80434..ccfe25ad 100644 --- a/boomerangScope/src/main/java/boomerang/scene/InstanceFieldRef.java +++ b/boomerangScope/src/main/java/boomerang/scene/InstanceFieldRef.java @@ -2,7 +2,7 @@ public interface InstanceFieldRef { - public Val getBase(); + Val getBase(); - public Field getField(); + Field getField(); } diff --git a/boomerangScope/src/main/java/boomerang/scene/InvokeExpr.java b/boomerangScope/src/main/java/boomerang/scene/InvokeExpr.java index b7a7aa9b..7c729786 100644 --- a/boomerangScope/src/main/java/boomerang/scene/InvokeExpr.java +++ b/boomerangScope/src/main/java/boomerang/scene/InvokeExpr.java @@ -4,17 +4,17 @@ public interface InvokeExpr { - public Val getArg(int index); + Val getArg(int index); - public List getArgs(); + List getArgs(); - public boolean isInstanceInvokeExpr(); + boolean isInstanceInvokeExpr(); - public Val getBase(); + Val getBase(); - public DeclaredMethod getMethod(); + DeclaredMethod getMethod(); - public boolean isSpecialInvokeExpr(); + boolean isSpecialInvokeExpr(); - public boolean isStaticInvokeExpr(); + boolean isStaticInvokeExpr(); } diff --git a/boomerangScope/src/main/java/boomerang/scene/Method.java b/boomerangScope/src/main/java/boomerang/scene/Method.java index 9c5847ac..e9d359dd 100644 --- a/boomerangScope/src/main/java/boomerang/scene/Method.java +++ b/boomerangScope/src/main/java/boomerang/scene/Method.java @@ -2,10 +2,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import de.fraunhofer.iem.Location; import java.util.Collection; import java.util.List; import java.util.Set; -import wpds.interfaces.Location; public abstract class Method implements Location { private static Method epsilon; @@ -119,6 +119,7 @@ public boolean isPublic() { return epsilon; } + // TODO: [ms] looks as if this toString() should go into epsilon.. @Override public String toString() { return "METHOD EPS"; diff --git a/boomerangScope/src/main/java/boomerang/scene/Pair.java b/boomerangScope/src/main/java/boomerang/scene/Pair.java index c6244247..a3277007 100644 --- a/boomerangScope/src/main/java/boomerang/scene/Pair.java +++ b/boomerangScope/src/main/java/boomerang/scene/Pair.java @@ -36,9 +36,8 @@ public boolean equals(Object obj) { if (other.x != null) return false; } else if (!x.equals(other.x)) return false; if (y == null) { - if (other.y != null) return false; - } else if (!y.equals(other.y)) return false; - return true; + return other.y == null; + } else return y.equals(other.y); } @Override diff --git a/boomerangScope/src/main/java/boomerang/scene/Statement.java b/boomerangScope/src/main/java/boomerang/scene/Statement.java index 09e92cd2..9ff4702c 100644 --- a/boomerangScope/src/main/java/boomerang/scene/Statement.java +++ b/boomerangScope/src/main/java/boomerang/scene/Statement.java @@ -11,9 +11,9 @@ */ package boomerang.scene; +import de.fraunhofer.iem.Empty; +import de.fraunhofer.iem.Location; import java.util.Collection; -import wpds.interfaces.Empty; -import wpds.interfaces.Location; public abstract class Statement implements Location { // Wrapper for stmt so we know the method @@ -379,15 +379,12 @@ public boolean uses(Val value) { if (getFieldStore().getX().equals(value)) return true; } if (isReturnOperator(value)) return true; - if (isParameter(value)) { - return true; - } - return false; + return isParameter(value); } public boolean assignsValue(Val value) { if (isAssign()) { - if (getLeftOp().equals(value)) return true; + return getLeftOp().equals(value); } return false; } @@ -474,9 +471,8 @@ public boolean equals(Object obj) { if (other.method != null) return false; } else if (!method.equals(other.method)) return false; if (rep == null) { - if (other.rep != null) return false; - } else if (!rep.equals(other.rep)) return false; - return true; + return other.rep == null; + } else return rep.equals(other.rep); } public abstract int getStartLineNumber(); diff --git a/boomerangScope/src/main/java/boomerang/scene/Val.java b/boomerangScope/src/main/java/boomerang/scene/Val.java index 0ceffa3d..b17d18da 100644 --- a/boomerangScope/src/main/java/boomerang/scene/Val.java +++ b/boomerangScope/src/main/java/boomerang/scene/Val.java @@ -277,9 +277,8 @@ public boolean equals(Object obj) { if (other.rep != null) return false; } else if (!rep.equals(other.rep)) return false; if (unbalancedStmt == null) { - if (other.unbalancedStmt != null) return false; - } else if (!unbalancedStmt.equals(other.unbalancedStmt)) return false; - return true; + return other.unbalancedStmt == null; + } else return unbalancedStmt.equals(other.unbalancedStmt); } public abstract Val withNewMethod(Method callee); @@ -301,7 +300,7 @@ public boolean isConstant() { public abstract Pair getArrayBase(); public boolean isThisLocal() { - return m().isStatic() ? false : m().getThisLocal().equals(this); + return !m().isStatic() && m().getThisLocal().equals(this); } public boolean isReturnLocal() { diff --git a/boomerangScope/src/main/java/boomerang/scene/ValWithFalseVariable.java b/boomerangScope/src/main/java/boomerang/scene/ValWithFalseVariable.java index f309858b..7991deec 100644 --- a/boomerangScope/src/main/java/boomerang/scene/ValWithFalseVariable.java +++ b/boomerangScope/src/main/java/boomerang/scene/ValWithFalseVariable.java @@ -1,5 +1,5 @@ package boomerang.scene; public interface ValWithFalseVariable { - public abstract Val getFalseVariable(); + Val getFalseVariable(); } diff --git a/boomerangScope/src/main/java/boomerang/scene/WrappedClass.java b/boomerangScope/src/main/java/boomerang/scene/WrappedClass.java index 644cf370..f73b3d3d 100644 --- a/boomerangScope/src/main/java/boomerang/scene/WrappedClass.java +++ b/boomerangScope/src/main/java/boomerang/scene/WrappedClass.java @@ -4,19 +4,19 @@ public interface WrappedClass { - public Set getMethods(); + Set getMethods(); - public boolean hasSuperclass(); + boolean hasSuperclass(); - public WrappedClass getSuperclass(); + WrappedClass getSuperclass(); - public Type getType(); + Type getType(); - public boolean isApplicationClass(); + boolean isApplicationClass(); - public String getFullyQualifiedName(); + String getFullyQualifiedName(); - public String getName(); + String getName(); - public Object getDelegate(); + Object getDelegate(); } diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseAliasingCFG.java b/boomerangScope/src/main/java/boomerang/scene/sparse/SparseAliasingCFG.java deleted file mode 100644 index aedc3df7..00000000 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseAliasingCFG.java +++ /dev/null @@ -1,57 +0,0 @@ -package boomerang.scene.sparse; - -import boomerang.scene.Val; -import com.google.common.graph.MutableGraph; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import soot.Unit; -import soot.Value; - -public class SparseAliasingCFG { - - private static Logger log = LoggerFactory.getLogger(SparseAliasingCFG.class); - - private MutableGraph graph; - private Val d; // which dff this SCFG belongs to - private Unit queryStmt; // in contrast to sparseCFG queryStmt affects the graph - private Set fallbackAliases; - private Map unitToNumber; - - public SparseAliasingCFG( - Val d, - MutableGraph graph, - Unit queryStmt, - Set fallbackAliases, - Map unitToNumber) { - this.d = d; - this.queryStmt = queryStmt; - this.graph = graph; - this.fallbackAliases = fallbackAliases; - this.unitToNumber = unitToNumber; - } - - public Set getFallBackAliases() { - return fallbackAliases; - } - - public synchronized boolean addEdge(Unit node, Unit succ) { - return graph.putEdge(node, succ); - } - - public Set getSuccessors(Unit node) { - return graph.successors(node); - } - - public List getNextUses(Unit node) { - Set successors = getSuccessors(node); - return new ArrayList<>(successors); - } - - public MutableGraph getGraph() { - return this.graph; - } -} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGCache.java b/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGCache.java deleted file mode 100644 index b0cb91b6..00000000 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/aliasaware/AliasAwareSparseCFGCache.java +++ /dev/null @@ -1,124 +0,0 @@ -package boomerang.scene.sparse.aliasaware; - -import boomerang.scene.Method; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.sparse.SootAdapter; -import boomerang.scene.sparse.SparseAliasingCFG; -import boomerang.scene.sparse.SparseCFGCache; -import boomerang.scene.sparse.eval.SparseCFGQueryLog; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import soot.SootMethod; -import soot.jimple.Stmt; - -public class AliasAwareSparseCFGCache implements SparseCFGCache { - - List logList = new ArrayList<>(); - - Map cache; - AliasAwareSparseCFGBuilder sparseCFGBuilder; - - private static AliasAwareSparseCFGCache INSTANCE; - private static boolean ignore; - - private AliasAwareSparseCFGCache() {} - - public static AliasAwareSparseCFGCache getInstance(boolean ignoreAfterQuery) { - if (INSTANCE == null || ignore != ignoreAfterQuery) { - ignore = ignoreAfterQuery; - INSTANCE = - new AliasAwareSparseCFGCache(new AliasAwareSparseCFGBuilder(true, ignoreAfterQuery)); - } - return INSTANCE; - } - - private AliasAwareSparseCFGCache(AliasAwareSparseCFGBuilder sparseCFGBuilder) { - this.cache = new HashMap<>(); - this.sparseCFGBuilder = sparseCFGBuilder; - } - - // TODO: unify in super - public SparseAliasingCFG getSparseCFGForForwardPropagation(SootMethod m, Stmt stmt, Val val) { - for (String s : cache.keySet()) { - if (s.startsWith(m.getSignature())) { - SparseAliasingCFG sparseAliasingCFG = cache.get(s); - if (sparseAliasingCFG.getGraph().nodes().contains(stmt)) { - SparseCFGQueryLog queryLog = - new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.FWD); - logList.add(queryLog); - return sparseAliasingCFG; - } - } - } - SparseCFGQueryLog queryLog = new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.FWD); - logList.add(queryLog); - // throw new RuntimeException("CFG not found for:" + m + " s:" + stmt); - return null; - } - - public synchronized SparseAliasingCFG getSparseCFGForBackwardPropagation( - Val initialQueryVal, - Statement initialQueryStmt, - Method currentMethod, - Val currentVal, - Statement currentStmt) { - - SootMethod sootSurrentMethod = SootAdapter.asSootMethod(currentMethod); - Stmt sootInitialQueryStmt = SootAdapter.asStmt(initialQueryStmt); - Stmt sootCurrentStmt = SootAdapter.asStmt(currentStmt); - // Value sootInitialQueryVal = SootAdapter.asValue(initialQueryVal); - // Value sootCurrentQueryVal = SootAdapter.asValue(currentVal); - - String key = - new StringBuilder(sootSurrentMethod.getSignature()) - .append("-") - .append(initialQueryVal) - .append("-") - .append(sootInitialQueryStmt) - .toString(); - - if (cache.containsKey(key)) { - if (cache.get(key).getGraph().nodes().contains(sootCurrentStmt)) { - SparseCFGQueryLog queryLog = - new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.BWD); - logList.add(queryLog); - return cache.get(key); - } else { - SparseCFGQueryLog queryLog = - new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.BWD); - queryLog.logStart(); - SparseAliasingCFG cfg = - sparseCFGBuilder.buildSparseCFG( - initialQueryVal, sootSurrentMethod, currentVal, sootCurrentStmt, queryLog); - queryLog.logEnd(); - cache.put(key + currentStmt, cfg); - logList.add(queryLog); - return cfg; - } - } else if (cache.containsKey(key + currentStmt)) { - SparseCFGQueryLog queryLog = - new SparseCFGQueryLog(true, SparseCFGQueryLog.QueryDirection.BWD); - logList.add(queryLog); - return cache.get(key + currentStmt); - } else { - SparseCFGQueryLog queryLog = - new SparseCFGQueryLog(false, SparseCFGQueryLog.QueryDirection.BWD); - queryLog.logStart(); - SparseAliasingCFG cfg = - sparseCFGBuilder.buildSparseCFG( - initialQueryVal, sootSurrentMethod, currentVal, sootCurrentStmt, queryLog); - queryLog.logEnd(); - cache.put(key, cfg); - logList.add(queryLog); - return cfg; - } - } - - @Override - public List getQueryLogs() { - return logList; - } -} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/PropagationCounter.java b/boomerangScope/src/main/java/boomerang/scene/sparse/eval/PropagationCounter.java deleted file mode 100644 index 4137b600..00000000 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/PropagationCounter.java +++ /dev/null @@ -1,59 +0,0 @@ -package boomerang.scene.sparse.eval; - -import boomerang.scene.sparse.SparseCFGCache; - -public class PropagationCounter { - private SparseCFGCache.SparsificationStrategy strategy; - private long forwardPropagation = 0; - private long backwardPropagation = 0; - - private static PropagationCounter NONE_INSTANCE; - private static PropagationCounter TYPE_BASED_INSTANCE; - private static PropagationCounter ALIAS_AWARE_INSTANCE; - - public static PropagationCounter getInstance(SparseCFGCache.SparsificationStrategy strategy) { - switch (strategy) { - case NONE: - if (NONE_INSTANCE == null) { - NONE_INSTANCE = new PropagationCounter(strategy); - } - return NONE_INSTANCE; - case TYPE_BASED: - if (TYPE_BASED_INSTANCE == null) { - TYPE_BASED_INSTANCE = new PropagationCounter(strategy); - } - return TYPE_BASED_INSTANCE; - case ALIAS_AWARE: - if (ALIAS_AWARE_INSTANCE == null) { - ALIAS_AWARE_INSTANCE = new PropagationCounter(strategy); - } - return ALIAS_AWARE_INSTANCE; - default: - throw new RuntimeException("No such strategy"); - } - } - - private PropagationCounter(SparseCFGCache.SparsificationStrategy strategy) { - this.strategy = strategy; - } - - public void countForward() { - forwardPropagation++; - } - - public void countBackward() { - backwardPropagation++; - } - - public long getForwardPropagation() { - return forwardPropagation; - } - - public long getBackwardPropagation() { - return backwardPropagation; - } - - public SparseCFGCache.SparsificationStrategy getStrategy() { - return strategy; - } -} diff --git a/boomerangScope/src/main/java/sparse/SparseAliasingCFG.java b/boomerangScope/src/main/java/sparse/SparseAliasingCFG.java new file mode 100644 index 00000000..a1f2c287 --- /dev/null +++ b/boomerangScope/src/main/java/sparse/SparseAliasingCFG.java @@ -0,0 +1,55 @@ +package sparse; + +import boomerang.scene.Val; +import com.google.common.graph.MutableGraph; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class SparseAliasingCFG { + + private static final Logger log = LoggerFactory.getLogger(SparseAliasingCFG.class); + + private final MutableGraph graph; + private final Val d; // which dff this SCFG belongs to + private final U queryStmt; // in contrast to sparseCFG queryStmt affects the graph + private final Set fallbackAliases; + private final Map unitToNumber; + + public SparseAliasingCFG( + Val d, + MutableGraph graph, + U queryStmt, + Set fallbackAliases, + Map unitToNumber) { + this.d = d; + this.queryStmt = queryStmt; + this.graph = graph; + this.fallbackAliases = fallbackAliases; + this.unitToNumber = unitToNumber; + } + + public Set getFallBackAliases() { + return fallbackAliases; + } + + public synchronized boolean addEdge(U node, U succ) { + return graph.putEdge(node, succ); + } + + public Set getSuccessors(U node) { + return graph.successors(node); + } + + public List getNextUses(U node) { + Set successors = getSuccessors(node); + return new ArrayList<>(successors); + } + + public MutableGraph getGraph() { + return this.graph; + } +} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGCache.java b/boomerangScope/src/main/java/sparse/SparseCFGCache.java similarity index 52% rename from boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGCache.java rename to boomerangScope/src/main/java/sparse/SparseCFGCache.java index e7371ce9..7e9fbace 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/SparseCFGCache.java +++ b/boomerangScope/src/main/java/sparse/SparseCFGCache.java @@ -1,32 +1,23 @@ -package boomerang.scene.sparse; +package sparse; -import boomerang.scene.Method; -import boomerang.scene.Statement; import boomerang.scene.Val; -import boomerang.scene.sparse.aliasaware.AliasAwareSparseCFGCache; -import boomerang.scene.sparse.eval.SparseCFGQueryLog; -import boomerang.scene.sparse.typebased.TypeBasedSparseCFGCache; import java.util.List; -import soot.SootMethod; -import soot.jimple.Stmt; +import sparse.eval.SparseCFGQueryLog; -public interface SparseCFGCache { - - enum SparsificationStrategy { - TYPE_BASED, - ALIAS_AWARE, - NONE; - } +public interface SparseCFGCache { static SparseCFGCache getInstance(SparsificationStrategy strategy, boolean ignoreAfterQuery) { + + // FIXME: [ms] fix/refactor mapping + /* switch (strategy) { case TYPE_BASED: return TypeBasedSparseCFGCache.getInstance(); case ALIAS_AWARE: return AliasAwareSparseCFGCache.getInstance(ignoreAfterQuery); - default: - throw new RuntimeException("SparsificationStrategy not implemented"); } + */ + throw new RuntimeException("SparsificationStrategy not implemented"); } /** @@ -36,7 +27,7 @@ static SparseCFGCache getInstance(SparsificationStrategy strategy, boolean ignor * @param stmt * @return */ - SparseAliasingCFG getSparseCFGForForwardPropagation(SootMethod m, Stmt stmt, Val val); + SparseAliasingCFG getSparseCFGForForwardPropagation(M m, S stmt, Val val); /** * For building the {@link SparseAliasingCFG} for the first time for a backward query. @@ -49,11 +40,7 @@ static SparseCFGCache getInstance(SparsificationStrategy strategy, boolean ignor * @return */ SparseAliasingCFG getSparseCFGForBackwardPropagation( - Val initialQueryVal, - Statement initialQueryStmt, - Method currentMethod, - Val currentVal, - Statement currentStmt); + Val initialQueryVal, S initialQueryStmt, M currentMethod, Val currentVal, S currentStmt); List getQueryLogs(); } diff --git a/boomerangScope/src/main/java/sparse/SparsificationStrategy.java b/boomerangScope/src/main/java/sparse/SparsificationStrategy.java new file mode 100644 index 00000000..77408f0c --- /dev/null +++ b/boomerangScope/src/main/java/sparse/SparsificationStrategy.java @@ -0,0 +1,27 @@ +package sparse; + +import boomerang.scene.Method; +import boomerang.scene.Statement; +import sparse.eval.PropagationCounter; + +public interface SparsificationStrategy { + + SparseCFGCache getInstance(boolean ignoreAfterQuery); + + PropagationCounter getCounter(); + + SparsificationStrategy NONE = new NoSparsificationStrategy(); + + class NoSparsificationStrategy implements SparsificationStrategy { + @Override + public SparseCFGCache getInstance(boolean ignoreAfterQuery) { + // TODO [ms]: not used in code (when commented code is re-enabled) + throw new UnsupportedOperationException("not implemented yet."); + } + + @Override + public PropagationCounter getCounter() { + return new PropagationCounter(); + } + } +} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/EvalPrinter.java b/boomerangScope/src/main/java/sparse/eval/EvalPrinter.java similarity index 62% rename from boomerangScope/src/main/java/boomerang/scene/sparse/eval/EvalPrinter.java rename to boomerangScope/src/main/java/sparse/eval/EvalPrinter.java index 88b91634..c5763798 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/EvalPrinter.java +++ b/boomerangScope/src/main/java/sparse/eval/EvalPrinter.java @@ -1,14 +1,13 @@ -package boomerang.scene.sparse.eval; +package sparse.eval; -import boomerang.scene.sparse.SparseCFGCache; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; import java.util.List; +import sparse.SparseCFGCache; public class EvalPrinter { - private String evalName; + private final String evalName; public EvalPrinter(String evalName) { this.evalName = evalName; @@ -25,26 +24,28 @@ public void printCachePerformance(SparseCFGCache cache) { long count = 0; for (SparseCFGQueryLog queryLog : queryLogs) { count++; - StringBuilder str = new StringBuilder(Long.toString(count)); - str.append(","); - str.append(queryLog.isRetrievedFromCache()); - str.append(","); - str.append(queryLog.getDirection()); - str.append(","); - str.append(queryLog.getDuration().toMillis()); - str.append(System.lineSeparator()); - writer.write(str.toString()); + String str = + Long.toString(count) + + "," + + queryLog.isRetrievedFromCache() + + "," + + queryLog.getDirection() + + "," + + queryLog.getDuration().toMillis() + + System.lineSeparator(); + writer.write(str); } } catch (IOException e) { e.printStackTrace(); } } + /* TODO: [ms] was unused - strategy enum does not exist anymore - sparsification currently only soot specific.. public void printPropagationCount() { List counters = new ArrayList<>(); - counters.add(PropagationCounter.getInstance(SparseCFGCache.SparsificationStrategy.NONE)); - counters.add(PropagationCounter.getInstance(SparseCFGCache.SparsificationStrategy.TYPE_BASED)); - counters.add(PropagationCounter.getInstance(SparseCFGCache.SparsificationStrategy.ALIAS_AWARE)); + counters.add(PropagationCounter.getInstance(SparsificationStrategy.NONE)); + counters.add(PropagationCounter.getInstance(SparsificationStrategy.TYPE_BASED)); + counters.add(PropagationCounter.getInstance(SparsificationStrategy.ALIAS_AWARE)); try (FileWriter writer = new FileWriter(evalName + "-" + "propCount.csv")) { StringBuilder str = new StringBuilder(); for (PropagationCounter counter : counters) { @@ -60,4 +61,5 @@ public void printPropagationCount() { e.printStackTrace(); } } + */ } diff --git a/boomerangScope/src/main/java/sparse/eval/PropagationCounter.java b/boomerangScope/src/main/java/sparse/eval/PropagationCounter.java new file mode 100644 index 00000000..70f5a57c --- /dev/null +++ b/boomerangScope/src/main/java/sparse/eval/PropagationCounter.java @@ -0,0 +1,24 @@ +package sparse.eval; + +public class PropagationCounter { + private long forwardPropagation = 0; + private long backwardPropagation = 0; + + public PropagationCounter() {} + + public void countForwardPropagation() { + forwardPropagation++; + } + + public void countBackwardProgragation() { + backwardPropagation++; + } + + public long getForwardPropagation() { + return forwardPropagation; + } + + public long getBackwardPropagation() { + return backwardPropagation; + } +} diff --git a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/SparseCFGQueryLog.java b/boomerangScope/src/main/java/sparse/eval/SparseCFGQueryLog.java similarity index 92% rename from boomerangScope/src/main/java/boomerang/scene/sparse/eval/SparseCFGQueryLog.java rename to boomerangScope/src/main/java/sparse/eval/SparseCFGQueryLog.java index 32a80a6e..4a75a669 100644 --- a/boomerangScope/src/main/java/boomerang/scene/sparse/eval/SparseCFGQueryLog.java +++ b/boomerangScope/src/main/java/sparse/eval/SparseCFGQueryLog.java @@ -1,4 +1,4 @@ -package boomerang.scene.sparse.eval; +package sparse.eval; import com.google.common.base.Stopwatch; import java.time.Duration; @@ -9,13 +9,13 @@ */ public class SparseCFGQueryLog { - private boolean retrievedFromCache; + private final boolean retrievedFromCache; - private QueryDirection direction; + private final QueryDirection direction; public enum QueryDirection { FWD, - BWD; + BWD } private final Stopwatch watch; @@ -23,7 +23,7 @@ public enum QueryDirection { private final Stopwatch findStmtsWatch; private final Stopwatch sparsifysWatch; - private int containerTypeCount = 0; + private final int containerTypeCount = 0; private int initialStmtCount = 0; private int finalStmtCount = 0; diff --git a/idealPDS/pom.xml b/idealPDS/pom.xml index 0fddd0f5..04a25877 100644 --- a/idealPDS/pom.xml +++ b/idealPDS/pom.xml @@ -46,7 +46,12 @@ org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + ${maven-surefire-plugin.version} + + + integration-test + + -Xmx8G -Xss128m diff --git a/idealPDS/src/main/java/ideal/IDEALAnalysis.java b/idealPDS/src/main/java/ideal/IDEALAnalysis.java index 68f593d8..2a361432 100644 --- a/idealPDS/src/main/java/ideal/IDEALAnalysis.java +++ b/idealPDS/src/main/java/ideal/IDEALAnalysis.java @@ -37,8 +37,8 @@ public class IDEALAnalysis { protected final IDEALAnalysisDefinition analysisDefinition; private final AnalysisScope seedFactory; private int seedCount; - private Map, Stopwatch> analysisTime = new HashMap<>(); - private Set> timedoutSeeds = new HashSet<>(); + private final Map, Stopwatch> analysisTime = new HashMap<>(); + private final Set> timedoutSeeds = new HashSet<>(); public IDEALAnalysis(final IDEALAnalysisDefinition analysisDefinition) { this.analysisDefinition = analysisDefinition; diff --git a/idealPDS/src/main/java/ideal/IDEALAnalysisDefinition.java b/idealPDS/src/main/java/ideal/IDEALAnalysisDefinition.java index 496bd9d4..8d3ffdc1 100644 --- a/idealPDS/src/main/java/ideal/IDEALAnalysisDefinition.java +++ b/idealPDS/src/main/java/ideal/IDEALAnalysisDefinition.java @@ -18,6 +18,7 @@ import boomerang.scene.CallGraph; import boomerang.scene.ControlFlowGraph.Edge; import boomerang.scene.DataFlowScope; +import boomerang.scene.FrameworkScope; import boomerang.scene.Val; import java.util.Collection; import sync.pds.solver.WeightFunctions; @@ -82,4 +83,6 @@ public IDEALResultHandler getResultHandler() { } protected abstract DataFlowScope getDataFlowScope(); + + public abstract FrameworkScope getFrameworkFactory(); } diff --git a/idealPDS/src/main/java/ideal/IDEALSeedSolver.java b/idealPDS/src/main/java/ideal/IDEALSeedSolver.java index 758c2ab1..bd0827bd 100644 --- a/idealPDS/src/main/java/ideal/IDEALSeedSolver.java +++ b/idealPDS/src/main/java/ideal/IDEALSeedSolver.java @@ -52,7 +52,7 @@ public class IDEALSeedSolver { - private static Logger LOGGER = LoggerFactory.getLogger(IDEALSeedSolver.class); + private static final Logger LOGGER = LoggerFactory.getLogger(IDEALSeedSolver.class); private final IDEALAnalysisDefinition analysisDefinition; private final ForwardQuery seed; private final IDEALWeightFunctions idealWeightFunctions; @@ -60,8 +60,8 @@ public class IDEALSeedSolver { private final WeightedBoomerang phase1Solver; private final WeightedBoomerang phase2Solver; private final Stopwatch analysisStopwatch = Stopwatch.createUnstarted(); - private Multimap, Edge> affectedStrongUpdateStmt = HashMultimap.create(); - private Set> weakUpdates = Sets.newHashSet(); + private final Multimap, Edge> affectedStrongUpdateStmt = HashMultimap.create(); + private final Set> weakUpdates = Sets.newHashSet(); private int killedRules; private final class AddIndirectFlowAtCallSite implements WPAUpdateListener, W> { @@ -104,9 +104,8 @@ public boolean equals(Object obj) { if (other.callSite != null) return false; } else if (!callSite.equals(other.callSite)) return false; if (returnedFact == null) { - if (other.returnedFact != null) return false; - } else if (!returnedFact.equals(other.returnedFact)) return false; - return true; + return other.returnedFact == null; + } else return returnedFact.equals(other.returnedFact); } private IDEALSeedSolver getOuterType() { @@ -266,7 +265,7 @@ public void onInTransitionAdded( public enum Phases { ObjectFlow, ValueFlow - }; + } public IDEALSeedSolver(IDEALAnalysisDefinition analysisDefinition, ForwardQuery seed) { this.analysisDefinition = analysisDefinition; @@ -304,7 +303,8 @@ private WeightedBoomerang createSolver(Phases phase) { return new WeightedBoomerang( analysisDefinition.callGraph(), analysisDefinition.getDataFlowScope(), - analysisDefinition.boomerangOptions()) { + analysisDefinition.boomerangOptions(), + analysisDefinition.getFrameworkFactory()) { @Override protected WeightFunctions getForwardCallWeights( @@ -331,9 +331,7 @@ protected WeightFunctions getBackwardCallWeights() { @Override public boolean preventCallRuleAdd(ForwardQuery sourceQuery, Rule, W> rule) { if (phase.equals(Phases.ValueFlow) && sourceQuery.equals(seed)) { - if (preventStrongUpdateFlows(rule)) { - return true; - } + return preventStrongUpdateFlows(rule); } return false; } diff --git a/idealPDS/src/main/java/ideal/IDEALSeedTimeout.java b/idealPDS/src/main/java/ideal/IDEALSeedTimeout.java index b45baf31..694fc263 100644 --- a/idealPDS/src/main/java/ideal/IDEALSeedTimeout.java +++ b/idealPDS/src/main/java/ideal/IDEALSeedTimeout.java @@ -18,8 +18,8 @@ /** Created by johannesspath on 01.12.17. */ public class IDEALSeedTimeout extends RuntimeException { private final IDEALSeedSolver solver; - private WeightedBoomerang timedoutSolver; - private ForwardBoomerangResults lastResults; + private final WeightedBoomerang timedoutSolver; + private final ForwardBoomerangResults lastResults; public IDEALSeedTimeout( IDEALSeedSolver solver, diff --git a/idealPDS/src/main/java/ideal/IDEALWeightFunctions.java b/idealPDS/src/main/java/ideal/IDEALWeightFunctions.java index bfcd15e1..8fa0e20c 100644 --- a/idealPDS/src/main/java/ideal/IDEALWeightFunctions.java +++ b/idealPDS/src/main/java/ideal/IDEALWeightFunctions.java @@ -30,15 +30,15 @@ public class IDEALWeightFunctions implements WeightFunctions { private static final Logger logger = LoggerFactory.getLogger(IDEALWeightFunctions.class); - private WeightFunctions delegate; - private Set listeners = Sets.newHashSet(); - private Set potentialStrongUpdates = Sets.newHashSet(); - private Set weakUpdates = Sets.newHashSet(); - private Set> nonOneFlowNodes = Sets.newHashSet(); + private final WeightFunctions delegate; + private final Set listeners = Sets.newHashSet(); + private final Set potentialStrongUpdates = Sets.newHashSet(); + private final Set weakUpdates = Sets.newHashSet(); + private final Set> nonOneFlowNodes = Sets.newHashSet(); private Phases phase; - private boolean strongUpdates; - private Multimap, Node> indirectAlias = HashMultimap.create(); - private Set> nodesWithStrongUpdate = Sets.newHashSet(); + private final boolean strongUpdates; + private final Multimap, Node> indirectAlias = HashMultimap.create(); + private final Set> nodesWithStrongUpdate = Sets.newHashSet(); public IDEALWeightFunctions(WeightFunctions delegate, boolean strongUpdates) { this.delegate = delegate; diff --git a/idealPDS/src/main/java/inference/InferenceWeight.java b/idealPDS/src/main/java/inference/InferenceWeight.java index d3235593..d8ae5391 100644 --- a/idealPDS/src/main/java/inference/InferenceWeight.java +++ b/idealPDS/src/main/java/inference/InferenceWeight.java @@ -92,8 +92,7 @@ public boolean equals(Object obj) { if (other.rep != null) return false; } else if (!rep.equals(other.rep)) return false; if (invokedMethods == null) { - if (other.invokedMethods != null) return false; - } else if (!invokedMethods.equals(other.invokedMethods)) return false; - return true; + return other.invokedMethods == null; + } else return invokedMethods.equals(other.invokedMethods); } } diff --git a/idealPDS/src/main/java/typestate/TransitionFunction.java b/idealPDS/src/main/java/typestate/TransitionFunction.java index 8b0537f4..238f1f30 100644 --- a/idealPDS/src/main/java/typestate/TransitionFunction.java +++ b/idealPDS/src/main/java/typestate/TransitionFunction.java @@ -32,7 +32,7 @@ public class TransitionFunction extends Weight { private static TransitionFunction zero; - private Set stateChangeStatements; + private final Set stateChangeStatements; public TransitionFunction(Set trans, Set stateChangeStatements) { this.stateChangeStatements = stateChangeStatements; @@ -126,7 +126,7 @@ public static TransitionFunction zero() { public String toString() { if (this.rep != null) return this.rep; - return "Weight: " + value.toString() + ""; + return "Weight: " + value.toString(); } @Override @@ -148,8 +148,7 @@ public boolean equals(Object obj) { if (other.rep != null) return false; } else if (!rep.equals(other.rep)) return false; if (value == null) { - if (other.value != null) return false; - } else if (!value.equals(other.value)) return false; - return true; + return other.value == null; + } else return value.equals(other.value); } } diff --git a/idealPDS/src/main/java/typestate/finiteautomata/ITransition.java b/idealPDS/src/main/java/typestate/finiteautomata/ITransition.java index 61a5ac02..63f82a28 100644 --- a/idealPDS/src/main/java/typestate/finiteautomata/ITransition.java +++ b/idealPDS/src/main/java/typestate/finiteautomata/ITransition.java @@ -12,7 +12,7 @@ package typestate.finiteautomata; public interface ITransition { - public State from(); + State from(); - public State to(); + State to(); } diff --git a/idealPDS/src/main/java/typestate/finiteautomata/MatcherTransition.java b/idealPDS/src/main/java/typestate/finiteautomata/MatcherTransition.java index 558b8e4e..321779d9 100644 --- a/idealPDS/src/main/java/typestate/finiteautomata/MatcherTransition.java +++ b/idealPDS/src/main/java/typestate/finiteautomata/MatcherTransition.java @@ -18,9 +18,9 @@ public class MatcherTransition extends Transition { private static final Logger LOGGER = LoggerFactory.getLogger(MatcherTransition.class); - private Type type; - private Parameter param; - private String methodMatcher; + private final Type type; + private final Parameter param; + private final String methodMatcher; private boolean negate = false; public enum Type { @@ -33,7 +33,7 @@ public enum Type { public enum Parameter { This, Param1, - Param2; + Param2 } public MatcherTransition(State from, String methodMatcher, Parameter param, State to, Type type) { @@ -57,7 +57,7 @@ public boolean matches(DeclaredMethod declaredMethod) { if (matches) LOGGER.debug( "Found matching transition at call site {} for {}", declaredMethod.getInvokeExpr(), this); - return negate ? !matches : matches; + return negate != matches; } public Type getType() { @@ -95,7 +95,6 @@ public boolean equals(Object obj) { } else if (!methodMatcher.equals(other.methodMatcher)) return false; if (negate != other.negate) return false; if (param != other.param) return false; - if (type != other.type) return false; - return true; + return type == other.type; } } diff --git a/idealPDS/src/main/java/typestate/finiteautomata/State.java b/idealPDS/src/main/java/typestate/finiteautomata/State.java index 9c4ec772..115796e0 100644 --- a/idealPDS/src/main/java/typestate/finiteautomata/State.java +++ b/idealPDS/src/main/java/typestate/finiteautomata/State.java @@ -12,9 +12,9 @@ package typestate.finiteautomata; public interface State { - public boolean isErrorState(); + boolean isErrorState(); - public boolean isInitialState(); + boolean isInitialState(); - public boolean isAccepting(); + boolean isAccepting(); } diff --git a/idealPDS/src/main/java/typestate/finiteautomata/Transition.java b/idealPDS/src/main/java/typestate/finiteautomata/Transition.java index 96b7ab88..de46792b 100644 --- a/idealPDS/src/main/java/typestate/finiteautomata/Transition.java +++ b/idealPDS/src/main/java/typestate/finiteautomata/Transition.java @@ -59,14 +59,13 @@ public boolean equals(Object obj) { if (other.rep != null) return false; } else if (!rep.equals(other.rep)) return false; if (to == null) { - if (other.to != null) return false; - } else if (!to.equals(other.to)) return false; - return true; + return other.to == null; + } else return to.equals(other.to); } public String toString() { if (rep != null) return rep; - return "" + from + " -> " + to; + return from + " -> " + to; } private static Transition instance; diff --git a/idealPDS/src/main/java/typestate/finiteautomata/TypeStateMachineWeightFunctions.java b/idealPDS/src/main/java/typestate/finiteautomata/TypeStateMachineWeightFunctions.java index fe734706..4d1ada17 100644 --- a/idealPDS/src/main/java/typestate/finiteautomata/TypeStateMachineWeightFunctions.java +++ b/idealPDS/src/main/java/typestate/finiteautomata/TypeStateMachineWeightFunctions.java @@ -23,13 +23,9 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import soot.Scene; -import soot.SootClass; import sync.pds.solver.WeightFunctions; import sync.pds.solver.nodes.Node; import typestate.TransitionFunction; @@ -129,6 +125,8 @@ private TransitionFunction getMatchingTransitions( return new TransitionFunction(res, Collections.singleton(transitionEdge)); } + /* + // TODO: [ms] re-enable protected List getSubclassesOf(String className) { SootClass sootClass = Scene.v().getSootClass(className); List list = Scene.v().getActiveHierarchy().getSubclassesOfIncluding(sootClass); @@ -138,6 +136,7 @@ protected List getSubclassesOf(String className) { } return res; } + */ protected Collection> getLeftSideOf(Edge edge) { Statement s = edge.getStart(); diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachine.java index 248b4b90..6caf955f 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachine.java @@ -24,7 +24,7 @@ public class FileMustBeClosedStateMachine extends TypeStateMachineWeightFunctions { - public static enum States implements State { + public enum States implements State { INIT, OPENED, CLOSED; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachineCallToReturn.java b/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachineCallToReturn.java index 8dc919f7..0cf9e596 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachineCallToReturn.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/FileMustBeClosedStateMachineCallToReturn.java @@ -24,7 +24,7 @@ public class FileMustBeClosedStateMachineCallToReturn extends TypeStateMachineWeightFunctions { - public static enum States implements State { + public enum States implements State { INIT, OPENED, CLOSED; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/HasNextStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/HasNextStateMachine.java index daf656f0..e15a7eae 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/HasNextStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/HasNextStateMachine.java @@ -26,10 +26,10 @@ public class HasNextStateMachine extends TypeStateMachineWeightFunctions { - private static String NEXT_METHOD = ".* next\\(\\)"; - private static String HAS_NEXT_METHOD = ".* hasNext\\(\\)"; + private static final String NEXT_METHOD = ".* next\\(\\)"; + private static final String HAS_NEXT_METHOD = ".* hasNext\\(\\)"; - public static enum States implements State { + public enum States implements State { NONE, INIT, HASNEXT, diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/InputStreamStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/InputStreamStateMachine.java index 27c3bdf0..ede7c1d7 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/InputStreamStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/InputStreamStateMachine.java @@ -27,7 +27,7 @@ public class InputStreamStateMachine extends TypeStateMachineWeightFunctions { private static final String READ_METHODS = ".* read.*"; private static final String TYPE = "java.io.InputStream"; - public static enum States implements State { + public enum States implements State { CLOSED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/KeyStoreStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/KeyStoreStateMachine.java index 2f05b898..08ec49d7 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/KeyStoreStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/KeyStoreStateMachine.java @@ -17,11 +17,7 @@ import boomerang.scene.DeclaredMethod; import boomerang.scene.Statement; import java.util.Collections; -import java.util.HashSet; -import java.util.List; import java.util.Set; -import soot.SootClass; -import soot.SootMethod; import typestate.TransitionFunction; import typestate.finiteautomata.MatcherTransition; import typestate.finiteautomata.MatcherTransition.Parameter; @@ -31,9 +27,9 @@ public class KeyStoreStateMachine extends TypeStateMachineWeightFunctions { - private static String LOAD_METHOD = ".* load.*"; + private static final String LOAD_METHOD = ".* load.*"; - public static enum States implements State { + public enum States implements State { NONE, INIT, LOADED, @@ -74,6 +70,8 @@ public KeyStoreStateMachine() { States.ERROR, LOAD_METHOD, true, Parameter.This, States.ERROR, Type.OnCallToReturn)); } + /* + // TODO: [ms] re-enable private Set keyStoreConstructor() { List subclasses = getSubclassesOf("java.security.KeyStore"); Set out = new HashSet<>(); @@ -83,6 +81,7 @@ private Set keyStoreConstructor() { } return out; } + */ @Override public Set> generateSeed(Edge edge) { diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/OutputStreamStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/OutputStreamStateMachine.java index ea177075..80bcb904 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/OutputStreamStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/OutputStreamStateMachine.java @@ -27,7 +27,7 @@ public class OutputStreamStateMachine extends TypeStateMachineWeightFunctions { private static final String WRITE_METHODS = ".* write.*"; private static final String TYPE = "java.io.OutputStream"; - public static enum States implements State { + public enum States implements State { NONE, CLOSED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/PipedInputStreamStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/PipedInputStreamStateMachine.java index c50b3e5e..cc575ec4 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/PipedInputStreamStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/PipedInputStreamStateMachine.java @@ -26,7 +26,7 @@ public class PipedInputStreamStateMachine extends TypeStateMachineWeightFunction private static final String CONNECT_METHODS = "connect"; private static final String READ_METHODS = "read"; - public static enum States implements State { + public enum States implements State { INIT, CONNECTED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/PipedOutputStreamStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/PipedOutputStreamStateMachine.java index a6adf7a4..2d6d5ac1 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/PipedOutputStreamStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/PipedOutputStreamStateMachine.java @@ -23,7 +23,7 @@ public class PipedOutputStreamStateMachine extends TypeStateMachineWeightFunctions { - public static enum States implements State { + public enum States implements State { INIT, CONNECTED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/PrintStreamStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/PrintStreamStateMachine.java index f6aa7b83..adbe38de 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/PrintStreamStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/PrintStreamStateMachine.java @@ -23,7 +23,7 @@ public class PrintStreamStateMachine extends TypeStateMachineWeightFunctions { - public static enum States implements State { + public enum States implements State { NONE, CLOSED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/PrintWriterStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/PrintWriterStateMachine.java index 2179c819..9ec3f963 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/PrintWriterStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/PrintWriterStateMachine.java @@ -23,7 +23,7 @@ public class PrintWriterStateMachine extends TypeStateMachineWeightFunctions { - public static enum States implements State { + public enum States implements State { NONE, CLOSED, ERROR; diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/SignatureStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/SignatureStateMachine.java index 6506e5b8..71c9f028 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/SignatureStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/SignatureStateMachine.java @@ -17,11 +17,6 @@ import boomerang.scene.Statement; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import soot.SootClass; -import soot.SootMethod; import typestate.TransitionFunction; import typestate.finiteautomata.MatcherTransition; import typestate.finiteautomata.MatcherTransition.Parameter; @@ -38,7 +33,7 @@ public class SignatureStateMachine extends TypeStateMachineWeightFunctions { private static final String VERIFY = "verify"; private static final String GET_INSTANCE = "getInstance"; - public static enum States implements State { + public enum States implements State { NONE, UNITIALIZED, SIGN_CHECK, @@ -125,6 +120,8 @@ public SignatureStateMachine() { new MatcherTransition(States.ERROR, UPDATE, Parameter.This, States.ERROR, Type.OnCall)); } + /* + // TODO: [ms] re-enable private Set constructor() { List subclasses = getSubclassesOf("java.security.Signature"); Set out = new HashSet<>(); @@ -134,6 +131,7 @@ private Set constructor() { } return out; } + */ @Override public Collection> generateSeed(Edge edge) { diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/SocketStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/SocketStateMachine.java index 76c48f36..c12b9516 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/SocketStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/SocketStateMachine.java @@ -25,7 +25,7 @@ public class SocketStateMachine extends TypeStateMachineWeightFunctions { - private static String CONNECT_METHOD = ".* connect.*"; + private static final String CONNECT_METHOD = ".* connect.*"; public enum States implements State { INIT, diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/URLConnStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/URLConnStateMachine.java index 633ba6bf..098e1b2d 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/URLConnStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/URLConnStateMachine.java @@ -28,7 +28,7 @@ public class URLConnStateMachine extends TypeStateMachineWeightFunctions { private static final String ILLEGAL_OPERTIONS = ".* (setDoInput|setDoOutput|setAllowUserInteraction|setUseCaches|setIfModifiedSince|setRequestProperty|addRequestProperty|getRequestProperty|getRequestProperties).*"; - public static enum States implements State { + public enum States implements State { NONE, INIT, CONNECTED, diff --git a/idealPDS/src/main/java/typestate/impl/statemachines/VectorStateMachine.java b/idealPDS/src/main/java/typestate/impl/statemachines/VectorStateMachine.java index 1b848bff..b4a457aa 100644 --- a/idealPDS/src/main/java/typestate/impl/statemachines/VectorStateMachine.java +++ b/idealPDS/src/main/java/typestate/impl/statemachines/VectorStateMachine.java @@ -25,12 +25,13 @@ public class VectorStateMachine extends TypeStateMachineWeightFunctions { - private static String ADD_ELEMENT_METHODS = + private static final String ADD_ELEMENT_METHODS = "(.* (add|addAll|addElement|insertElementAt|set|setElementAt).*)|(java.util.Collection)>"; - private static String ACCESS_ELEMENT_METHODS = ".* (elementAt|firstElement|lastElement|get).*"; - private static String REMOVE_ALL_METHODS = ".* removeAllElements.*"; + private static final String ACCESS_ELEMENT_METHODS = + ".* (elementAt|firstElement|lastElement|get).*"; + private static final String REMOVE_ALL_METHODS = ".* removeAllElements.*"; - public static enum States implements State { + public enum States implements State { INIT, NOT_EMPTY, ACCESSED_EMPTY; diff --git a/idealPDS/src/main/java/inference/example/InferenceExample.java b/idealPDS/src/test/java/example/InferenceExample.java similarity index 96% rename from idealPDS/src/main/java/inference/example/InferenceExample.java rename to idealPDS/src/test/java/example/InferenceExample.java index c7c60779..e3f3285e 100644 --- a/idealPDS/src/main/java/inference/example/InferenceExample.java +++ b/idealPDS/src/test/java/example/InferenceExample.java @@ -9,7 +9,7 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package inference.example; +package example; public class InferenceExample { public static void main(String... args) { diff --git a/idealPDS/src/main/java/inference/example/Main.java b/idealPDS/src/test/java/example/Main.java similarity index 92% rename from idealPDS/src/main/java/inference/example/Main.java rename to idealPDS/src/test/java/example/Main.java index dde5c6f1..897ad8e3 100644 --- a/idealPDS/src/main/java/inference/example/Main.java +++ b/idealPDS/src/test/java/example/Main.java @@ -9,19 +9,17 @@ *

Contributors: Johannes Spaeth - initial API and implementation * ***************************************************************************** */ -package inference.example; +package example; import boomerang.WeightedForwardQuery; import boomerang.debugger.Debugger; +import boomerang.framework.soot.SootDataFlowScopeUtil; +import boomerang.framework.soot.SootFrameworkScope; +import boomerang.framework.soot.jimple.BoomerangPretransformer; +import boomerang.framework.soot.jimple.SootCallGraph; import boomerang.results.ForwardBoomerangResults; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.ControlFlowGraph.Edge; -import boomerang.scene.DataFlowScope; -import boomerang.scene.SootDataFlowScope; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.jimple.SootCallGraph; import com.google.common.base.Joiner; import com.google.common.collect.Table; import ideal.IDEALAnalysis; @@ -154,7 +152,12 @@ public CallGraph callGraph() { @Override protected DataFlowScope getDataFlowScope() { - return SootDataFlowScope.make(Scene.v()); + return SootDataFlowScopeUtil.make(Scene.v()); + } + + @Override + public FrameworkScope getFrameworkFactory() { + return new SootFrameworkScope(); } }); solver.run(); diff --git a/idealPDS/src/test/java/test/ComparableResult.java b/idealPDS/src/test/java/test/ComparableResult.java index 91fdc8a3..f590fab8 100644 --- a/idealPDS/src/test/java/test/ComparableResult.java +++ b/idealPDS/src/test/java/test/ComparableResult.java @@ -15,9 +15,9 @@ public interface ComparableResult { - public Val getVal(); + Val getVal(); - public Statement getStmt(); + Statement getStmt(); - public void computedResults(State val); + void computedResults(State val); } diff --git a/idealPDS/src/test/java/test/ExpectedResults.java b/idealPDS/src/test/java/test/ExpectedResults.java index a9649199..a4d6e78e 100644 --- a/idealPDS/src/test/java/test/ExpectedResults.java +++ b/idealPDS/src/test/java/test/ExpectedResults.java @@ -23,7 +23,7 @@ public abstract class ExpectedResults enum InternalState { ERROR, - ACCEPTING; + ACCEPTING } ExpectedResults(Statement unit, Val val, InternalState state) { @@ -69,9 +69,8 @@ public boolean equals(Object obj) { } else if (!val.equals(other.val)) return false; if (state != other.state) return false; if (unit == null) { - if (other.unit != null) return false; - } else if (!unit.equals(other.unit)) return false; - return true; + return other.unit == null; + } else return unit.equals(other.unit); } @Override diff --git a/idealPDS/src/test/java/test/IDEALTestingFramework.java b/idealPDS/src/test/java/test/IDEALTestingFramework.java index a0391850..8d4daf24 100644 --- a/idealPDS/src/test/java/test/IDEALTestingFramework.java +++ b/idealPDS/src/test/java/test/IDEALTestingFramework.java @@ -16,34 +16,14 @@ import boomerang.WeightedForwardQuery; import boomerang.debugger.Debugger; import boomerang.results.ForwardBoomerangResults; -import boomerang.scene.CallGraph; +import boomerang.scene.*; import boomerang.scene.CallGraph.Edge; -import boomerang.scene.ControlFlowGraph; -import boomerang.scene.DataFlowScope; -import boomerang.scene.Method; -import boomerang.scene.SootDataFlowScope; -import boomerang.scene.Statement; -import boomerang.scene.Val; -import boomerang.scene.jimple.BoomerangPretransformer; -import boomerang.scene.jimple.JimpleMethod; -import boomerang.scene.jimple.SootCallGraph; import com.google.common.collect.Lists; -import ideal.IDEALAnalysis; -import ideal.IDEALAnalysisDefinition; -import ideal.IDEALResultHandler; -import ideal.IDEALSeedSolver; -import ideal.StoreIDEALResultHandler; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import ideal.*; +import java.util.*; import java.util.Map.Entry; -import java.util.Set; -import soot.Scene; -import soot.SceneTransformer; import sync.pds.solver.WeightFunctions; import test.ExpectedResults.InternalState; -import test.core.selfrunning.AbstractTestingFramework; import test.core.selfrunning.ImprecisionException; import typestate.TransitionFunction; import typestate.finiteautomata.TypeStateMachineWeightFunctions; @@ -52,8 +32,24 @@ public abstract class IDEALTestingFramework extends AbstractTestingFramework { private static final boolean FAIL_ON_IMPRECISE = false; protected StoreIDEALResultHandler resultHandler = new StoreIDEALResultHandler<>(); - protected CallGraph callGraph; - protected DataFlowScope dataFlowScope; + + @Override + protected void initializeWithEntryPoint() { + frameworkScope = + FrameworkScopeFactory.init( + buildClassPath(), + getTestCaseClassName(), + testMethodName.getMethodName(), + getIncludedPackagesList(), + getExludedPackageList()); + } + + @Override + protected void analyze() { + analyze( + frameworkScope.getMethod( + "<" + getTestCaseClassName() + ": void " + testMethodName.getMethodName() + "()>")); + } protected abstract TypeStateMachineWeightFunctions getStateMachine(); @@ -77,7 +73,7 @@ public Collection> generate( @Override public Debugger debugger(IDEALSeedSolver solver) { return - /** + /* * VISUALIZATION ? new IDEVizDebugger<>(new File( * ideVizFile.getAbsolutePath().replace(".json", " " + solver.getSeed() + ".json")), * callGraph) : @@ -110,30 +106,25 @@ public boolean allowMultipleQueries() { }; } + private final CallGraph callGraph = frameworkScope.getCallGraph(); + @Override public CallGraph callGraph() { return callGraph; } + private final DataFlowScope dataFlowScope = frameworkScope.getDataFlowScope(); + @Override protected DataFlowScope getDataFlowScope() { return dataFlowScope; } - }); - } - @Override - protected SceneTransformer createAnalysisTransformer() throws ImprecisionException { - return new SceneTransformer() { - protected void internalTransform( - String phaseName, @SuppressWarnings("rawtypes") Map options) { - BoomerangPretransformer.v().reset(); - BoomerangPretransformer.v().apply(); - callGraph = new SootCallGraph(); - dataFlowScope = SootDataFlowScope.make(Scene.v()); - analyze(JimpleMethod.of(sootTestMethod)); - } - }; + @Override + public FrameworkScope getFrameworkFactory() { + return frameworkScope; + } + }); } protected void analyze(Method m) { @@ -189,7 +180,7 @@ private void parseExpectedQueryResults(Method m, Set queries, Set { - private Multimap stmtToResults = HashMultimap.create(); + private final Multimap stmtToResults = HashMultimap.create(); public TestingResultReporter(Set expectedResults) { for (Assertion e : expectedResults) { diff --git a/idealPDS/src/test/java/typestate/tests/IteratorTest.java b/idealPDS/src/test/java/typestate/tests/IteratorTest.java index d4b0675a..13527723 100644 --- a/idealPDS/src/test/java/typestate/tests/IteratorTest.java +++ b/idealPDS/src/test/java/typestate/tests/IteratorTest.java @@ -100,8 +100,8 @@ public void chartTest() { } private static class AxisCollection { - private ArrayList axesAtTop; - private ArrayList axesAtBottom; + private final ArrayList axesAtTop; + private final ArrayList axesAtBottom; public AxisCollection() { this.axesAtTop = new ArrayList(); diff --git a/idealPDS/src/test/java/typestate/tests/SocketLongTest.java b/idealPDS/src/test/java/typestate/tests/SocketLongTest.java index bc109706..8b8944a2 100644 --- a/idealPDS/src/test/java/typestate/tests/SocketLongTest.java +++ b/idealPDS/src/test/java/typestate/tests/SocketLongTest.java @@ -54,7 +54,7 @@ public void test3() throws IOException { public void test4() throws IOException { Collection sockets = createSockets(); for (Iterator it = sockets.iterator(); it.hasNext(); ) { - Socket s = (Socket) it.next(); + Socket s = it.next(); s.connect(null); talk(s); mustBeInAcceptingState(s); @@ -75,7 +75,7 @@ private Collection createOther() { public void test5() throws IOException { Collection sockets = createSockets(); for (Iterator it = sockets.iterator(); it.hasNext(); ) { - Socket s = (Socket) it.next(); + Socket s = it.next(); talk(s); mayBeInErrorState(s); } diff --git a/idealPDS/src/test/java/typestate/tests/SootSceneSetupTest.java b/idealPDS/src/test/java/typestate/tests/SootSceneSetupTest.java index 72e8fc12..1a9fe1fb 100644 --- a/idealPDS/src/test/java/typestate/tests/SootSceneSetupTest.java +++ b/idealPDS/src/test/java/typestate/tests/SootSceneSetupTest.java @@ -11,7 +11,6 @@ */ package typestate.tests; -import java.util.List; import org.junit.Ignore; import org.junit.Test; import test.IDEALTestingFramework; @@ -44,10 +43,13 @@ protected TypeStateMachineWeightFunctions getStateMachine() { return new FileMustBeClosedStateMachineCallToReturn(); } + /* + // TODO: [ms] re-enable? @Override public List excludedPackages() { List exlcuded = super.excludedPackages(); exlcuded.add("typestate.test.helper.File"); return exlcuded; } + */ } diff --git a/idealPDS/src/test/java/typestate/tests/URLConnTest.java b/idealPDS/src/test/java/typestate/tests/URLConnTest.java index 4e5687ad..9caa1352 100644 --- a/idealPDS/src/test/java/typestate/tests/URLConnTest.java +++ b/idealPDS/src/test/java/typestate/tests/URLConnTest.java @@ -28,7 +28,7 @@ public void test1() throws IOException { @Override public void connect() throws IOException { // TODO Auto-generated method stub - System.out.println(""); + System.out.println(); } @Override @@ -58,7 +58,7 @@ public void test2() throws IOException { @Override public void connect() throws IOException { // TODO Auto-generated method stub - System.out.println(""); + System.out.println(); } @Override diff --git a/misc/eclipse-java-google-style.xml b/misc/eclipse-java-google-style.xml deleted file mode 100644 index 7bb6804e..00000000 --- a/misc/eclipse-java-google-style.xml +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml index 919a94a1..b88ac189 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 de.fraunhofer.iem SPDS @@ -19,7 +20,8 @@ scm:git:git@github.com:secure-software-engineering/SparseBoomerang.git - scm:git:ssh://github.com:secure-software-engineering/SparseBoomerang.git + scm:git:ssh://github.com:secure-software-engineering/SparseBoomerang.git + https://github.com/secure-software-engineering/SparseBoomerang @@ -43,30 +45,35 @@ + PDS WPDS SynchronizedPDS testCore boomerangPDS idealPDS boomerangScope + boomerangScope-Soot + boomerangScope-SootUp boomerangScope-WALA - SparseBoomerangCorrectness + UTF-8 - 4.3.0-SNAPSHOT + 4.3.0-SNAPSHOT 2.13 1.11.2 - 3.6.1 3.5.0 - true + 3.5.2 + 3.5.2 + 3.6.1 + true org.apache.maven.plugins maven-surefire-plugin - 3.5.2 + ${maven-surefire-plugin.version} -Xmx8G -Xss128m @@ -175,11 +182,6 @@ pathexpression 1.0.5 - - org.soot-oss - soot - 4.6.0 - org.apache.commons commons-lang3 @@ -190,6 +192,11 @@ WPDS ${project.version} + + de.fraunhofer.iem + PDS + ${project.version} + de.fraunhofer.iem synchronizedPDS @@ -199,6 +206,7 @@ de.fraunhofer.iem testCore ${project.version} + test de.fraunhofer.iem @@ -210,6 +218,63 @@ boomerangScope ${project.version} + + de.fraunhofer.iem + boomerangScope-Soot + ${project.version} + + + de.fraunhofer.iem + boomerangScope-SootUp + ${project.version} + + + de.fraunhofer.iem + boomerangScope-WALA + ${project.version} + + + org.soot-oss + soot + 4.6.0 + + + + org.soot-oss + sootup.core + 1.3.0 + + + org.soot-oss + sootup.java.core + 1.3.0 + + + org.soot-oss + sootup.java.sourcecode + 1.3.0 + + + org.soot-oss + sootup.java.bytecode + 1.3.0 + + + org.soot-oss + sootup.jimple.parser + 1.3.0 + + + org.soot-oss + sootup.callgraph + 1.3.0 + + + org.soot-oss + sootup.analysis + 1.3.0 + + @@ -273,7 +338,7 @@ - + ci @@ -284,7 +349,7 @@ fmt-maven-plugin - ${skipFormatPlugin} + ${skipFormat} diff --git a/testCore/pom.xml b/testCore/pom.xml index c4470a1f..bf427c97 100644 --- a/testCore/pom.xml +++ b/testCore/pom.xml @@ -1,4 +1,5 @@ - + de.fraunhofer.iem SPDS @@ -7,19 +8,38 @@ 4.0.0 testCore + + + + + org.apache.maven.plugins + maven-deploy-plugin + 3.1.2 + + true + + + + + - org.soot-oss - soot + junit + junit + compile de.fraunhofer.iem - synchronizedPDS + boomerangScope + - junit - junit - compile + de.fraunhofer.iem + boomerangScope-SootUp + + + de.fraunhofer.iem + boomerangScope-Soot \ No newline at end of file diff --git a/testCore/src/main/java/test/AbstractTestingFramework.java b/testCore/src/main/java/test/AbstractTestingFramework.java new file mode 100644 index 00000000..29a78ef8 --- /dev/null +++ b/testCore/src/main/java/test/AbstractTestingFramework.java @@ -0,0 +1,145 @@ +/** + * ***************************************************************************** Copyright (c) 2018 + * Fraunhofer IEM, Paderborn, Germany. This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + *

SPDX-License-Identifier: EPL-2.0 + * + *

Contributors: Johannes Spaeth - initial API and implementation + * ***************************************************************************** + */ +package test; + +import boomerang.scene.FrameworkScope; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TestName; +import test.core.selfrunning.ImprecisionException; + +public abstract class AbstractTestingFramework { + @Rule public TestName testMethodName = new TestName(); + protected File ideVizFile; + protected File dotFile; + protected FrameworkScope frameworkScope; + + protected abstract void initializeWithEntryPoint(); + + protected abstract void analyze(); + + protected String buildClassPath() { + String userdir = System.getProperty("user.dir"); + String javaHome = System.getProperty("java.home"); + if (javaHome == null || javaHome.isEmpty()) { + throw new RuntimeException("Could not get property java.home!"); + } + + String sootCp = userdir + "/target/test-classes"; + if (getJavaVersion() < 9) { + sootCp += File.pathSeparator + javaHome + "/lib/rt.jar"; + sootCp += File.pathSeparator + javaHome + "/lib/jce.jar"; + } + return sootCp; + } + + protected List getIncludedPackagesList() { + List includeList = new ArrayList<>(); + includeList.add("java.lang.*"); + includeList.add("java.util.*"); + includeList.add("java.io.*"); + includeList.add("sun.misc.*"); + includeList.add("java.net.*"); + includeList.add("sun.nio.*"); + includeList.add("javax.servlet.*"); + return includeList; + } + + protected List getExludedPackageList() { + List excludedPackages = new ArrayList<>(); + excludedPackages.add("sun.*"); + excludedPackages.add("javax.*"); + excludedPackages.add("com.sun.*"); + excludedPackages.add("com.ibm.*"); + excludedPackages.add("org.xml.*"); + excludedPackages.add("org.w3c.*"); + excludedPackages.add("apple.awt.*"); + excludedPackages.add("com.apple.*"); + return excludedPackages; + } + + @Before + public void beforeTestCaseExecution() { + try { + initializeWithEntryPoint(); + createDebugFiles(); + analyze(); + } catch (ImprecisionException e) { + Assert.fail(e.getMessage()); + } + // To never execute the @Test method... + org.junit.Assume.assumeTrue(false); + } + + private void createDebugFiles() { + ideVizFile = + new File( + "target/IDEViz/" + + getTestCaseClassName() + + "/IDEViz-" + + testMethodName.getMethodName() + + ".json"); + if (!ideVizFile.getParentFile().exists()) { + try { + Files.createDirectories(ideVizFile.getParentFile().toPath()); + } catch (IOException e) { + throw new RuntimeException("Was not able to create directories for IDEViz output!"); + } + } + dotFile = + new File( + "target/dot/" + + getTestCaseClassName() + + "/Dot-" + + testMethodName.getMethodName() + + ".dot"); + if (!dotFile.getParentFile().exists()) { + try { + Files.createDirectories(dotFile.getParentFile().toPath()); + } catch (IOException e) { + throw new RuntimeException("Was not able to create directories for dot output!"); + } + } + } + + public String getTestCaseClassName() { + return this.getClass().getName().replace("class ", ""); + } + + /** + * This method can be used in test cases to create branching. It is not optimized away. + * + * @return + */ + protected boolean staticallyUnknown() { + return true; + } + + static int getJavaVersion() { + String version = System.getProperty("java.version"); + if (version.startsWith("1.")) { + version = version.substring(2, 3); + } else { + int dot = version.indexOf("."); + if (dot != -1) { + version = version.substring(0, dot); + } + } + return Integer.parseInt(version); + } +} diff --git a/testCore/src/main/java/test/Assertion.java b/testCore/src/main/java/test/Assertion.java index 4d14706e..da95362b 100644 --- a/testCore/src/main/java/test/Assertion.java +++ b/testCore/src/main/java/test/Assertion.java @@ -12,7 +12,7 @@ package test; public interface Assertion { - public boolean isSatisfied(); + boolean isSatisfied(); - public boolean isImprecise(); + boolean isImprecise(); } diff --git a/testCore/src/main/java/test/FrameworkScopeFactory.java b/testCore/src/main/java/test/FrameworkScopeFactory.java new file mode 100644 index 00000000..07c1f78c --- /dev/null +++ b/testCore/src/main/java/test/FrameworkScopeFactory.java @@ -0,0 +1,517 @@ +package test; + +import static test.AbstractTestingFramework.getJavaVersion; + +import boomerang.framework.soot.SootFrameworkScope; +import boomerang.framework.soot.jimple.BoomerangPretransformer; +import boomerang.framework.sootup.BoomerangPreInterceptor; +import boomerang.framework.sootup.SootUpFrameworkScope; +import boomerang.scene.FrameworkScope; +import com.google.common.collect.Lists; +import jakarta.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; +import soot.*; +import soot.jimple.Jimple; +import soot.jimple.JimpleBody; +import soot.options.Options; +import sootup.SourceTypeSplittingAnalysisInputLocation; +import sootup.callgraph.CallGraphAlgorithm; +import sootup.callgraph.RapidTypeAnalysisAlgorithm; +import sootup.core.frontend.BodySource; +import sootup.core.frontend.ResolveException; +import sootup.core.graph.MutableBlockStmtGraph; +import sootup.core.inputlocation.AnalysisInputLocation; +import sootup.core.inputlocation.EagerInputLocation; +import sootup.core.jimple.basic.NoPositionInformation; +import sootup.core.model.ClassModifier; +import sootup.core.model.MethodModifier; +import sootup.core.model.SootClassMember; +import sootup.core.model.SourceType; +import sootup.core.signatures.MethodSignature; +import sootup.core.signatures.PackageName; +import sootup.core.transform.BodyInterceptor; +import sootup.interceptors.*; +import sootup.java.bytecode.frontend.inputlocation.DefaultRuntimeAnalysisInputLocation; +import sootup.java.bytecode.frontend.inputlocation.JavaClassPathAnalysisInputLocation; +import sootup.java.core.JavaSootClass; +import sootup.java.core.JavaSootMethod; +import sootup.java.core.OverridingJavaClassSource; +import sootup.java.core.types.JavaClassType; +import sootup.java.core.views.JavaView; +import sootup.jimple.frontend.JimpleStringAnalysisInputLocation; +import sootup.jimple.frontend.JimpleView; + +// TODO: refactor as parameterized test -> update to junit 5 +public class FrameworkScopeFactory { + + // FIXME: adapt to be used by Guided...Tests and CustomFlowTests --> no need to create a + // in-memory-entrypoint! --> uses processdir + // see + // https://github.com/secure-software-engineering/SparseBoomerang/blob/4c491929237d869f6efdd9fcadbd065c1729610a/boomerangPDS/src/test/java/boomerang/guided/DemandDrivenGuidedAnalysisTest.java#L463 + public static FrameworkScope init(String classPath, String fqClassName) { + return init(classPath, fqClassName, null, new ArrayList<>(), Collections.emptyList()); + } + + public static FrameworkScope init( + String classPath, + String fqClassName, + String customEntrypointMethodName, + List includedPackages, + List excludedPackages) { + + // TODO: ms: currently: switch here to test desired framework - refactor e.g. into parameterized + // tests! + return getSootFrameworkScope( + classPath, fqClassName, customEntrypointMethodName, includedPackages, excludedPackages); + } + + private static FrameworkScope getSootFrameworkScope( + String pathStr, + String className, + String customEntrypointMethodName, + List includedPackages, + List excludedPackages) { + + // System.out.println("framework:soot"); + + List eps = Lists.newArrayList(); + SootMethod sootTestMethod = null; + int classCount = 0; + + G.v().reset(); + + Options.v().set_whole_program(true); + Options.v().set_output_format(Options.output_format_none); + Options.v().set_no_bodies_for_excluded(true); + Options.v().set_allow_phantom_refs(true); + + if (!includedPackages.isEmpty()) { + Options.v().set_include(includedPackages); + } + + Options.v().setPhaseOption("jb", "use-original-names:true"); + Options.v().set_keep_line_number(true); + + Options.v().setPhaseOption("jb.sils", "enabled:false"); + Options.v().setPhaseOption("jb", "use-original-names:true"); + + if (!excludedPackages.isEmpty()) { + Options.v().set_exclude(excludedPackages); + } + + if (customEntrypointMethodName == null) { + Options.v().setPhaseOption("cg.cha", "on"); + Options.v().setPhaseOption("cg.cha", "verbose:true"); + + Options.v().set_prepend_classpath(true); + List processDir = Collections.singletonList(pathStr); + Options.v().set_process_dir(processDir); + + Scene.v().loadNecessaryClasses(); + + for (SootClass sootClass : Scene.v().getClasses()) { + classCount++; + String scStr = sootClass.toString(); + if (scStr.equals(className) || (scStr.startsWith(className + "$"))) { + sootClass.setApplicationClass(); + eps.addAll(sootClass.getMethods()); + } + } + if (eps.isEmpty()) { + throw new IllegalStateException( + "No entrypoints given/found in " + classCount + " classes."); + } + Scene.v().setEntryPoints(eps); + + PackManager.v().runPacks(); + BoomerangPretransformer.v().reset(); + BoomerangPretransformer.v().apply(); + + } else { + Options.v().setPhaseOption("cg.spark", "on"); + Options.v().setPhaseOption("cg.spark", "verbose:true"); + + // which runtime library needs to be configured + if (getJavaVersion() < 9) { + Options.v().set_prepend_classpath(true); + Options.v().set_soot_classpath(pathStr); + } else if (getJavaVersion() >= 9) { + Options.v().set_soot_classpath("VIRTUAL_FS_FOR_JDK" + File.pathSeparator + pathStr); + } + + // create entrypoint class/method + SootClass sootTestCaseClass = Scene.v().forceResolve(className, SootClass.BODIES); + for (SootMethod m : sootTestCaseClass.getMethods()) { + if (m.getName().equals(customEntrypointMethodName)) { + sootTestMethod = m; + break; + } + } + if (sootTestMethod == null) { + throw new RuntimeException( + "The method with name " + + customEntrypointMethodName + + " was not found in the Soot Scene."); + } + sootTestMethod.getDeclaringClass().setApplicationClass(); + + String targetClass = getTargetClass(sootTestMethod, className); + + Scene.v().addBasicClass(targetClass, SootClass.BODIES); + Scene.v().loadNecessaryClasses(); + + SootClass c = Scene.v().forceResolve(targetClass, SootClass.BODIES); + if (c != null) { + c.setApplicationClass(); + } + + SootMethod methodByName = c.getMethodByName("main"); + eps.add(methodByName); + + for (SootMethod m : sootTestCaseClass.getMethods()) { + if (m.isStaticInitializer()) { + eps.add(m); + } + } + + // collect entrypoints + for (SootClass inner : Scene.v().getClasses()) { + classCount++; + if (inner.getName().contains(sootTestCaseClass.getName())) { + inner.setApplicationClass(); + for (SootMethod m : inner.getMethods()) { + if (m.isStaticInitializer()) { + eps.add(m); + } + } + } + } + + if (eps.isEmpty()) { + throw new IllegalStateException( + "No entrypoints given/found in " + classCount + " classes."); + } + // System.out.println("classes: " + classCount); + Scene.v().setEntryPoints(eps); + + Transform transform = + new Transform( + "wjtp.ifds", + new SceneTransformer() { + @Override + protected void internalTransform(String phaseName, Map options) { + BoomerangPretransformer.v().reset(); + BoomerangPretransformer.v().apply(); + } + }); + + // analyze + PackManager.v() + .getPack("wjtp") + .add(transform); // whole programm, jimple, user-defined transformations + PackManager.v().getPack("cg").apply(); // call graph package + PackManager.v().getPack("wjtp").apply(); + } + + /* + System.out.println("classes: " + Scene.v().getClasses().size()); + Scene.v().getClasses().stream() + .sorted(Comparator.comparing(SootClass::toString)) + .forEach(System.out::println); + */ + + return new SootFrameworkScope(); + } + + private static String getTargetClass(SootMethod sootTestMethod, String testCaseClassName) { + SootClass sootClass = new SootClass("dummyClass"); + Type paramType = ArrayType.v(RefType.v("java.lang.String"), 1); + SootMethod mainMethod = + new SootMethod( + "main", + Collections.singletonList(paramType), + VoidType.v(), + Modifier.PUBLIC | Modifier.STATIC); + sootClass.addMethod(mainMethod); + JimpleBody body = Jimple.v().newBody(mainMethod); + mainMethod.setActiveBody(body); + RefType testCaseType = RefType.v(testCaseClassName); + Local loc = Jimple.v().newLocal("l0", paramType); + body.getLocals().add(loc); + body.getUnits().add(Jimple.v().newIdentityStmt(loc, Jimple.v().newParameterRef(paramType, 0))); + Local allocatedTestObj = Jimple.v().newLocal("dummyObj", testCaseType); + body.getLocals().add(allocatedTestObj); + body.getUnits() + .add(Jimple.v().newAssignStmt(allocatedTestObj, Jimple.v().newNewExpr(testCaseType))); + body.getUnits() + .add( + Jimple.v() + .newInvokeStmt( + Jimple.v().newVirtualInvokeExpr(allocatedTestObj, sootTestMethod.makeRef()))); + body.getUnits().add(Jimple.v().newReturnVoidStmt()); + + Scene.v().addClass(sootClass); + body.validate(); + return sootClass.toString(); + } + + /** SootUp Framework setup TODO: [ms] refactor me! */ + private static FrameworkScope getSootUpFrameworkScope( + String pathStr, + String className, + String customEntrypointMethodName, + List includedPackages, + List excludedPackages) { + + System.out.println("framework:sootup"); + + // FIXME add dependent classs from entrypoint + Path testClassesBinRoot = Paths.get(System.getProperty("user.dir") + "/target/test-classes/"); + try { + Files.walk(testClassesBinRoot) + .filter(f -> f.toFile().isDirectory()) + .forEach( + x -> { + if (x != testClassesBinRoot) { + Path relativize = testClassesBinRoot.relativize(x); + includedPackages.add(relativize.toString().replace("/", ".") + ".*"); + } + }); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // configure interceptors + // TODO: check if the interceptor needs a reset in between runs + List bodyInterceptors = + new ArrayList<>( + List.of(new CastAndReturnInliner(), new LocalSplitter(), new TypeAssigner())); + // new ArrayList<>(BytecodeBodyInterceptors.Default.getBodyInterceptors()); + bodyInterceptors.add(new BoomerangPreInterceptor()); + + // configure AnalysisInputLocations + List inputLocations = new ArrayList<>(); + + DefaultRuntimeAnalysisInputLocation runtimeInputLocation = + new DefaultRuntimeAnalysisInputLocation(); + + System.out.println("incl" + includedPackages); + System.out.println("ex" + excludedPackages); + + if (true) { + inputLocations.add(runtimeInputLocation); + } else { + SourceTypeSplittingAnalysisInputLocation.ApplicationAnalysisInputLocation + applicationAnalysisInputLocationRuntime = + new SourceTypeSplittingAnalysisInputLocation.ApplicationAnalysisInputLocation( + runtimeInputLocation, includedPackages); + + SourceTypeSplittingAnalysisInputLocation.LibraryAnalysisInputLocation + sourceTypeLibraryAnalysisInputLocationRuntime = + new SourceTypeSplittingAnalysisInputLocation.LibraryAnalysisInputLocation( + applicationAnalysisInputLocationRuntime, excludedPackages); + + inputLocations.add(applicationAnalysisInputLocationRuntime); + inputLocations.add(sourceTypeLibraryAnalysisInputLocationRuntime); + } + + JavaClassPathAnalysisInputLocation classPathInputLocation = + new JavaClassPathAnalysisInputLocation(pathStr, SourceType.Application, bodyInterceptors); + + if (includedPackages.isEmpty() && excludedPackages.isEmpty()) { + inputLocations.add(classPathInputLocation); + } else { + SourceTypeSplittingAnalysisInputLocation.ApplicationAnalysisInputLocation + applicationAnalysisInputLocation = + new SourceTypeSplittingAnalysisInputLocation.ApplicationAnalysisInputLocation( + classPathInputLocation, includedPackages); + + SourceTypeSplittingAnalysisInputLocation.LibraryAnalysisInputLocation + sourceTypeLibraryAnalysisInputLocation = + new SourceTypeSplittingAnalysisInputLocation.LibraryAnalysisInputLocation( + applicationAnalysisInputLocation, excludedPackages); + inputLocations.add(applicationAnalysisInputLocation); + inputLocations.add(sourceTypeLibraryAnalysisInputLocation); + } + + /* + // before: figure out if included/excluded was intended as: && or || + new ScopedAnalysisInputLocation.AllowlistingScopedAnalysisInputLocation( + classPathInputLocation, includedPackages), + new ScopedAnalysisInputLocation.DenylistingScopedAnalysisInputLocation( + classPathInputLocation, excludedPackages)) + */ + + JavaView javaView; + Collection classes; + sootup.callgraph.CallGraph cg; + List entypointSignatures = Lists.newArrayList(); + + if (customEntrypointMethodName == null) { + System.out.println(inputLocations); + javaView = new JavaView(inputLocations); + System.out.println(inputLocations.get(0).getSourceType()); + inputLocations + .get(0) + .getClassSources(javaView) + .forEach(cs -> System.out.println(cs.getClassType())); + System.out.println("-----"); + System.out.println(inputLocations.get(1).getSourceType()); + inputLocations + .get(1) + .getClassSources(javaView) + .forEach(cs -> System.out.println(cs.getClassType())); + System.out.println("-----"); + System.out.println(inputLocations.get(2).getSourceType()); + inputLocations + .get(2) + .getClassSources(javaView) + .forEach(cs -> System.out.println(cs.getClassType())); + System.out.println("-----"); + // System.out.println(inputLocations.get(3).getSourceType()); + // inputLocations.get(3).getClassSources(javaView).forEach( cs -> + // System.out.println(cs.getClassType())); + + classes = javaView.getClasses().collect(Collectors.toList()); + // collect entrypoints + for (JavaSootClass sootClass : classes) { + String scStr = sootClass.toString(); + if (scStr.equals(className) || (scStr.contains(className + "$"))) { + sootClass.getMethods().stream() + .map(SootClassMember::getSignature) + .forEach(entypointSignatures::add); + } + } + + } else { + + // build dummy entrypoint class + String jimpleClassStr = + "class dummyClass\n" + + "{\n" + + " public static void main(java.lang.String[])\n" + + " {\n" + + " " + + className + + " dummyObj;\n" + + " java.lang.String[] l0;\n" + + " l0 := @parameter0: java.lang.String[];\n" + + " dummyObj = new " + + className + + ";\n" + + " virtualinvoke dummyObj.<" + + className + + ": void " + + customEntrypointMethodName + + "()>();\n" + + " return;\n" + + " }\n" + + "}"; + + JavaClassType dummyClassType = new JavaClassType("dummyClass", new PackageName("")); + JimpleStringAnalysisInputLocation jimpleStringAnalysisInputLocation = + new JimpleStringAnalysisInputLocation( + jimpleClassStr, SourceType.Application, Collections.emptyList()); + JimpleView jimpleView = new JimpleView(jimpleStringAnalysisInputLocation); + Optional aClass = jimpleView.getClass(dummyClassType); + + assert aClass.isPresent(); + sootup.core.model.SootClass sootClass = aClass.get(); + + MethodSignature methodSignature = + jimpleView + .getIdentifierFactory() + .parseMethodSignature(""); + BodySource bodySource = + new BodySource() { + @Nonnull + @Override + public sootup.core.model.Body resolveBody(@Nonnull Iterable iterable) + throws ResolveException, IOException { + return sootup.core.model.Body.builder( + new MutableBlockStmtGraph( + sootClass + .getMethod(methodSignature.getSubSignature()) + .get() + .getBody() + .getStmtGraph())) + .setMethodSignature(methodSignature) + .build(); + } + + @Override + public Object resolveAnnotationsDefaultValue() { + return null; + } + + @Nonnull + @Override + public MethodSignature getSignature() { + return methodSignature; + } + }; + JavaSootMethod method = + new JavaSootMethod( + bodySource, + methodSignature, + EnumSet.of(MethodModifier.PUBLIC, MethodModifier.STATIC), + Collections.emptySet(), + Collections.emptyList(), + NoPositionInformation.getInstance()); + + OverridingJavaClassSource dummyClassSource = + new OverridingJavaClassSource( + new EagerInputLocation(), + Paths.get("/in-memory"), + dummyClassType, + null, + Collections.emptySet(), + null, + Collections.emptySet(), + Collections.singleton(method), + NoPositionInformation.getInstance(), + EnumSet.of(ClassModifier.PUBLIC), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList()); + + inputLocations.add( + new EagerInputLocation( + Collections.singletonMap(dummyClassType, dummyClassSource), SourceType.Application)); + + javaView = new JavaView(inputLocations); + classes = javaView.getClasses().collect(Collectors.toList()); + + MethodSignature dummyEntrypoint = + javaView + .getIdentifierFactory() + .parseMethodSignature(""); + assert javaView.getMethod(dummyEntrypoint).isPresent(); + + entypointSignatures.add(dummyEntrypoint); + } + + System.out.println( + "classes: " + + classes.size()); // soot has 1911 for boomerang.guided.DemandDrivenGuidedAnalysisTest + + classes.stream() + .sorted(Comparator.comparing(sootup.core.model.SootClass::toString)) + .forEach(System.out::println); + + // initialize CallGraphAlgorithm + // TODO: use spark when available + CallGraphAlgorithm cga = new RapidTypeAnalysisAlgorithm(javaView); + cg = cga.initialize(entypointSignatures); + + cg.exportAsDot(); + + return new SootUpFrameworkScope(javaView, cg, entypointSignatures); + } +} diff --git a/testCore/src/main/java/test/core/selfrunning/AbstractTestingFramework.java b/testCore/src/main/java/test/core/selfrunning/AbstractTestingFramework.java deleted file mode 100644 index 967814a6..00000000 --- a/testCore/src/main/java/test/core/selfrunning/AbstractTestingFramework.java +++ /dev/null @@ -1,255 +0,0 @@ -/** - * ***************************************************************************** Copyright (c) 2018 - * Fraunhofer IEM, Paderborn, Germany. This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 which is available at - * http://www.eclipse.org/legal/epl-2.0. - * - *

SPDX-License-Identifier: EPL-2.0 - * - *

Contributors: Johannes Spaeth - initial API and implementation - * ***************************************************************************** - */ -package test.core.selfrunning; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.rules.TestName; -import soot.*; -import soot.jimple.Jimple; -import soot.jimple.JimpleBody; -import soot.options.Options; - -public abstract class AbstractTestingFramework { - @Rule public TestName testMethodName = new TestName(); - protected SootMethod sootTestMethod; - protected File ideVizFile; - protected File dotFile; - - @Before - public void beforeTestCaseExecution() { - initializeSootWithEntryPoint(); - createDebugFiles(); - try { - analyze(); - } catch (ImprecisionException e) { - Assert.fail(e.getMessage()); - } - // To never execute the @Test method... - org.junit.Assume.assumeTrue(false); - } - - private void createDebugFiles() { - ideVizFile = - new File( - "target/IDEViz/" - + getTestCaseClassName() - + "/IDEViz-" - + testMethodName.getMethodName() - + ".json"); - if (!ideVizFile.getParentFile().exists()) { - try { - Files.createDirectories(ideVizFile.getParentFile().toPath()); - } catch (IOException e) { - throw new RuntimeException("Was not able to create directories for IDEViz output!"); - } - } - dotFile = - new File( - "target/dot/" - + getTestCaseClassName() - + "/Dot-" - + testMethodName.getMethodName() - + ".dot"); - if (!dotFile.getParentFile().exists()) { - try { - Files.createDirectories(dotFile.getParentFile().toPath()); - } catch (IOException e) { - throw new RuntimeException("Was not able to create directories for dot output!"); - } - } - } - - private void analyze() { - Transform transform = new Transform("wjtp.ifds", createAnalysisTransformer()); - PackManager.v() - .getPack("wjtp") - .add(transform); // whole programm, jimple, user-defined transformations - PackManager.v().getPack("cg").apply(); // call graph package - PackManager.v().getPack("wjtp").apply(); - } - - protected abstract SceneTransformer createAnalysisTransformer(); - - @SuppressWarnings("static-access") - private void initializeSootWithEntryPoint() { - G.v().reset(); - Options.v().set_whole_program(true); - - // https://soot-build.cs.uni-paderborn.de/public/origin/develop/soot/soot-develop/options/soot_options.htm#phase_5_2 - // Options.v().setPhaseOption("cg.cha", "on"); - // Options.v().setPhaseOption("cg.cha", "verbose:true"); - - Options.v().setPhaseOption("cg.spark", "on"); - Options.v().setPhaseOption("cg.spark", "verbose:true"); - Options.v().set_output_format(Options.output_format_none); - - Options.v().set_no_bodies_for_excluded(true); - Options.v().set_allow_phantom_refs(true); - - Options.v().set_include(getIncludeList()); - - Options.v().setPhaseOption("jb.sils", "enabled:false"); - Options.v().setPhaseOption("jb", "use-original-names:true"); - - Options.v().set_exclude(excludedPackages()); - - // JAVA VERSION 8 - if (getJavaVersion() < 9) { - Options.v().set_prepend_classpath(true); - Options.v().set_soot_classpath(getSootClassPath()); - } - // JAVA VERSION 9 - else if (getJavaVersion() >= 9) { - Options.v() - .set_soot_classpath("VIRTUAL_FS_FOR_JDK" + File.pathSeparator + getSootClassPath()); - } - - // Options.v().set_main_class(this.getTargetClass()); - SootClass sootTestCaseClass = Scene.v().forceResolve(getTestCaseClassName(), SootClass.BODIES); - - for (SootMethod m : sootTestCaseClass.getMethods()) { - if (m.getName().equals(testMethodName.getMethodName())) sootTestMethod = m; - } - if (sootTestMethod == null) - throw new RuntimeException( - "The method with name " - + testMethodName.getMethodName() - + " was not found in the Soot Scene."); - sootTestMethod.getDeclaringClass().setApplicationClass(); - Scene.v().addBasicClass(getTargetClass(), SootClass.BODIES); - Scene.v().loadNecessaryClasses(); - SootClass c = Scene.v().forceResolve(getTargetClass(), SootClass.BODIES); - if (c != null) { - c.setApplicationClass(); - } - SootMethod methodByName = c.getMethodByName("main"); - List ePoints = new LinkedList<>(); - for (SootMethod m : sootTestCaseClass.getMethods()) { - if (m.isStaticInitializer()) ePoints.add(m); - } - for (SootClass inner : Scene.v().getClasses()) { - if (inner.getName().contains(sootTestCaseClass.getName())) { - inner.setApplicationClass(); - for (SootMethod m : inner.getMethods()) { - if (m.isStaticInitializer()) ePoints.add(m); - } - } - } - ePoints.add(methodByName); - Scene.v().setEntryPoints(ePoints); - } - - protected String getSootClassPath() { - String userdir = System.getProperty("user.dir"); - String javaHome = System.getProperty("java.home"); - if (javaHome == null || javaHome.equals("")) - throw new RuntimeException("Could not get property java.home!"); - - String sootCp = userdir + "/target/test-classes"; - if (getJavaVersion() < 9) { - sootCp += File.pathSeparator + javaHome + "/lib/rt.jar"; - sootCp += File.pathSeparator + javaHome + "/lib/jce.jar"; - } - return sootCp; - } - - protected List getIncludeList() { - List includeList = new LinkedList<>(); - includeList.add("java.lang.*"); - includeList.add("java.util.*"); - includeList.add("java.io.*"); - includeList.add("sun.misc.*"); - includeList.add("java.net.*"); - includeList.add("sun.nio.*"); - includeList.add("javax.servlet.*"); - return includeList; - } - - private String getTargetClass() { - SootClass sootClass = new SootClass("dummyClass"); - Type paramType = ArrayType.v(RefType.v("java.lang.String"), 1); - SootMethod mainMethod = - new SootMethod( - "main", - Collections.singletonList(paramType), - VoidType.v(), - Modifier.PUBLIC | Modifier.STATIC); - sootClass.addMethod(mainMethod); - JimpleBody body = Jimple.v().newBody(mainMethod); - mainMethod.setActiveBody(body); - RefType testCaseType = RefType.v(getTestCaseClassName()); - Local loc = Jimple.v().newLocal("l0", paramType); - body.getLocals().add(loc); - body.getUnits().add(Jimple.v().newIdentityStmt(loc, Jimple.v().newParameterRef(paramType, 0))); - Local allocatedTestObj = Jimple.v().newLocal("dummyObj", testCaseType); - body.getLocals().add(allocatedTestObj); - body.getUnits() - .add(Jimple.v().newAssignStmt(allocatedTestObj, Jimple.v().newNewExpr(testCaseType))); - body.getUnits() - .add( - Jimple.v() - .newInvokeStmt( - Jimple.v().newVirtualInvokeExpr(allocatedTestObj, sootTestMethod.makeRef()))); - body.getUnits().add(Jimple.v().newReturnVoidStmt()); - - Scene.v().addClass(sootClass); - body.validate(); - return sootClass.toString(); - } - - public String getTestCaseClassName() { - return this.getClass().getName().replace("class ", ""); - } - - public List excludedPackages() { - List excludedPackages = new LinkedList<>(); - excludedPackages.add("sun.*"); - excludedPackages.add("javax.*"); - excludedPackages.add("com.sun.*"); - excludedPackages.add("com.ibm.*"); - excludedPackages.add("org.xml.*"); - excludedPackages.add("org.w3c.*"); - excludedPackages.add("apple.awt.*"); - excludedPackages.add("com.apple.*"); - return excludedPackages; - } - - /** - * This method can be used in test cases to create branching. It is not optimized away. - * - * @return - */ - protected boolean staticallyUnknown() { - return true; - } - - private static int getJavaVersion() { - String version = System.getProperty("java.version"); - if (version.startsWith("1.")) { - version = version.substring(2, 3); - } else { - int dot = version.indexOf("."); - if (dot != -1) { - version = version.substring(0, dot); - } - } - return Integer.parseInt(version); - } -}