├── .classpath
├── .gitignore
├── .gitmodules
├── .project
├── .settings
└── org.eclipse.jdt.core.prefs
├── LICENSE.txt
├── README.md
├── lib
├── boomerang.jar
├── grph-1.8.0-big.jar
├── heros-trunk.jar
└── soot-trunk.jar
├── src
└── ideal
│ ├── Analysis.java
│ ├── AnalysisContext.java
│ ├── AnalysisProblem.java
│ ├── AnalysisSolver.java
│ ├── AnalysisTimeoutException.java
│ ├── InternalAnalysisProblem.java
│ ├── debug
│ ├── IDebugger.java
│ └── NullDebugger.java
│ ├── edgefunction
│ ├── AnalysisEdgeFunctions.java
│ └── ForwardEdgeFunctions.java
│ ├── flowfunctions
│ ├── ForwardFlowFunctions.java
│ └── WrappedAccessGraph.java
│ └── pointsofaliasing
│ ├── CallSite.java
│ ├── InstanceFieldWrite.java
│ ├── NullnessCheck.java
│ └── PointOfAlias.java
├── targets
├── file
│ ├── File.java
│ ├── ObjectWithField.java
│ ├── SummaryTarget1.java
│ ├── Target1.java
│ ├── Target10.java
│ ├── Target11.java
│ ├── Target12.java
│ ├── Target13.java
│ ├── Target14.java
│ ├── Target15.java
│ ├── Target16.java
│ ├── Target17.java
│ ├── Target18.java
│ ├── Target19.java
│ ├── Target2.java
│ ├── Target20.java
│ ├── Target21.java
│ ├── Target22.java
│ ├── Target23.java
│ ├── Target24.java
│ ├── Target25.java
│ ├── Target26.java
│ ├── Target27.java
│ ├── Target28.java
│ ├── Target29.java
│ ├── Target3.java
│ ├── Target30.java
│ ├── Target4.java
│ ├── Target5.java
│ ├── Target6.java
│ ├── Target7.java
│ ├── Target8.java
│ └── Target9.java
├── inputstream
│ ├── InputStreamTarget1.java
│ ├── InputStreamTarget2.java
│ └── InputStreamTarget3.java
├── iterator
│ ├── IteratorTarget1.java
│ ├── IteratorTarget2.java
│ ├── IteratorTarget3.java
│ ├── IteratorTarget4.java
│ ├── IteratorTarget5.java
│ ├── IteratorTarget6.java
│ ├── IteratorTarget7.java
│ ├── IteratorTarget8.java
│ ├── IteratorTarget9.java
│ ├── MyIterator.java
│ └── MyLinkedList.java
├── keystore
│ ├── KeyStoreTarget1.java
│ ├── KeyStoreTarget2.java
│ └── KeyStoreTarget3.java
├── printstream
│ └── PrintStreamTarget1.java
├── printwriter
│ └── PrintWriterTarget1.java
├── socket
│ ├── SocketTarget1.java
│ ├── SocketTarget2.java
│ ├── SocketTarget3.java
│ └── SocketTarget4.java
├── stack
│ ├── StackTarget1.java
│ ├── StackTarget2.java
│ ├── StackTarget3.java
│ └── StackTarget4.java
├── urlconn
│ ├── URLConnTarget1.java
│ └── URLConnTarget2.java
└── vector
│ ├── VectorTarget1.java
│ ├── VectorTarget2.java
│ ├── VectorTarget3.java
│ └── VectorTarget4.java
├── targetsBin
├── file
│ ├── File.class
│ ├── ObjectWithField.class
│ ├── SummaryTarget1.class
│ ├── Target1.class
│ ├── Target10.class
│ ├── Target11$Flow.class
│ ├── Target11$ImplFlow1.class
│ ├── Target11$ImplFlow2.class
│ ├── Target11.class
│ ├── Target12.class
│ ├── Target13.class
│ ├── Target14.class
│ ├── Target15.class
│ ├── Target16.class
│ ├── Target17.class
│ ├── Target18.class
│ ├── Target19.class
│ ├── Target2.class
│ ├── Target20.class
│ ├── Target21.class
│ ├── Target22.class
│ ├── Target23.class
│ ├── Target24.class
│ ├── Target25.class
│ ├── Target26.class
│ ├── Target27.class
│ ├── Target28.class
│ ├── Target29.class
│ ├── Target3.class
│ ├── Target30.class
│ ├── Target4.class
│ ├── Target5.class
│ ├── Target6.class
│ ├── Target7.class
│ ├── Target8.class
│ └── Target9.class
├── inputstream
│ ├── InputStreamTarget1.class
│ ├── InputStreamTarget2.class
│ └── InputStreamTarget3.class
├── iterator
│ ├── IteratorTarget1.class
│ ├── IteratorTarget2.class
│ ├── IteratorTarget3.class
│ ├── IteratorTarget4.class
│ ├── IteratorTarget5.class
│ ├── IteratorTarget6.class
│ ├── IteratorTarget7.class
│ ├── IteratorTarget8.class
│ ├── IteratorTarget9.class
│ ├── MyIterator.class
│ └── MyLinkedList.class
├── keystore
│ ├── KeyStoreTarget1.class
│ ├── KeyStoreTarget2.class
│ └── KeyStoreTarget3.class
├── printstream
│ └── PrintStreamTarget1.class
├── printwriter
│ └── PrintWriterTarget1.class
├── socket
│ ├── SocketTarget1$1.class
│ ├── SocketTarget1.class
│ ├── SocketTarget2.class
│ ├── SocketTarget3.class
│ └── SocketTarget4.class
├── stack
│ ├── StackTarget1.class
│ ├── StackTarget2.class
│ ├── StackTarget3.class
│ └── StackTarget4.class
├── urlconn
│ ├── URLConnTarget1$1.class
│ ├── URLConnTarget1.class
│ ├── URLConnTarget2$1.class
│ └── URLConnTarget2.class
└── vector
│ ├── VectorTarget1.class
│ ├── VectorTarget2.class
│ ├── VectorTarget3.class
│ └── VectorTarget4.class
├── tests
└── typestate
│ └── tests
│ ├── FileMustBeClosedTests.java
│ ├── InputStreamTests.java
│ ├── IteratorTests.java
│ ├── KeystoreTests.java
│ ├── PrintStreamTests.java
│ ├── PrintWriterTests.java
│ ├── SocketTests.java
│ ├── StackTests.java
│ ├── URLConnTests.java
│ ├── VectorTests.java
│ └── base
│ ├── TestingFramework.java
│ └── TypestateTestingFramework.java
└── typestate
└── typestate
├── IdentityTransition.java
├── Join.java
├── ResultCollection.java
├── TransitionFunction.java
├── TypestateAnalysis.java
├── TypestateAnalysisProblem.java
├── TypestateChangeFunction.java
├── TypestateDomainValue.java
├── TypestateEdgeFunctions.java
├── finiteautomata
├── MatcherStateMachine.java
├── MatcherTransition.java
├── State.java
└── Transition.java
└── impl
├── fileanalysis
├── FileMustBeClosedAnalysis.java
└── FileMustBeClosedStateMachine.java
├── inputstream
├── InputStreamAnalysis.java
└── InputStreamStateMachine.java
├── iteratoranalysis
├── HasNextAnalysis.java
├── HasNextStateMachine.java
└── allocsite
│ ├── HasNextAnalysis.java
│ └── HasNextStateMachine.java
├── keystore
├── KeyStoreAnalysis.java
└── KeyStoreStateMachine.java
├── outputstream
├── OutputStreamAnalysis.java
└── OutputStreamStateMachine.java
├── pipedinputstream
├── PipedInputStreamAnalysis.java
└── PipedInputStreamStateMachine.java
├── pipedoutputstream
├── PipedOutputStreamAnalysis.java
└── PipedOutputStreamStateMachine.java
├── printstream
├── PrintStreamAnalysis.java
└── PrintStreamStateMachine.java
├── printwriter
├── PrintWriterAnalysis.java
└── PrintWriterStateMachine.java
├── signature
├── SignatureAnalysis.java
└── SignatureStateMachine.java
├── socket
├── SocketAnalysis.java
└── SocketStateMachine.java
├── urlconn
├── URLConnAnalysis.java
└── URLConnStateMachine.java
└── vector
├── VectorAnalysis.java
└── VectorStateMachine.java
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | bin
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "libs/boomerang"]
2 | path = libs/boomerang
3 | url = git@github.com:uasys/boomerang.git
4 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ideal
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
5 | org.eclipse.jdt.core.compiler.compliance=1.7
6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
11 | org.eclipse.jdt.core.compiler.source=1.7
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **A new and more efficient version of IDE/AL can be found [here](https://github.com/CROSSINGTUD/WPDS).**
2 |
3 | IDE/AL - Alias-Aware Framework for Interprocedural Dataflow Analysis
4 | ===============================================================
5 |
6 | This project is an extension to the [Heros](https://github.com/Sable/heros) framework
7 | and allows automatic reasoning of aliases during an object tracking static analysis. Two examples
8 | of such an analysis are a taint or typestate analysis.
9 |
10 | We implemented a typestate analysis in IDE/AL. A typestate analysis reasons about object and their states.
11 | One such property is: A file must always be closed at the end of its lifetime.
12 |
13 | ```
14 | File file = new File();
15 | File alias = file;
16 | file.open();
17 | alias.close();
18 | ```
19 |
20 | In the example above, an alias to the object is created. There are two accessors to the same file object (```file``` and ```alias```). While
21 | one of them receives the open call, the ```close``` call is triggered on the other accessor. IDE/AL automatically reasons
22 | about the alias relationship internally and then propagates the typestate states over an objects flow graph.
23 | In the example the typestate analysis implemented in IDE/AL can correctly reason about the object being correctly used.
24 | The typestate analysis therefore must only specify the seed with is the accessor ```file``` at the statement ```file.open()``` , and the edge functions. The edge functions dictate the transformation of the environments along the flow path (e.g. when the object is switched from state open to closed). The seed and the edge functions are both specified through the interface [AnalysisProblem](src/ideal/AnalysisProblem.java).
25 |
26 |
27 | # Examples
28 |
29 | For examples on how to use IDE/AL have a look at the test cases. They can be found [here](tests/typestate/tests).
30 |
31 | # Instructions
32 |
33 | This project is dependent on [Boomerang](https://github.com/uasys/boomerang), which requires [Soot](https://github.com/Sable/soot), [Heros](https://github.com/Sable/heros) and [Jasmin](https://github.com/Sable/jasmin) as submodules.
34 | To checkout this project use the --recursive option to allow all submodules to be initialized and cloned automatically, i.e.
35 |
36 | ```
37 | git clone --recursive git@github.com:uasys/ideal.git
38 | ```
39 |
40 | Once the checkout is done, there is a libs folder containing the Boomerang project.
41 | Import the Boomerang project as an existing Java project into your eclipse workspace.
42 | Do the same for Heros, Soot and Jasmin which are located in the libs folder of Boomerang, i.e. below
43 |
44 | ```
45 | libs/boomerang/libs/(heros|soot|jasmin)/
46 | ```
47 |
48 | IDE/AL does not contain compile time errors anymore and is readily set up.
49 |
50 | # Project Structure
51 |
52 | Import the project into eclipse. The project contians four different source folders:
53 |
54 | * *src*: The main source code of IDE/AL. IDE/AL can be used for any data-flow analysis based on IDE that also tracks object references.
55 | * *typestate*: The implementation of a typestate analysis in IDE/AL. This source code mainly implements the edge functions over the object flow graph retrieved from IDE/AL.
56 | * *targets*: The program code the typestate analysis analyses.
57 | * *tests*: JUnit tests for the typestate analysis.
58 |
59 | # Licencse
60 | IDE/AL is released under LGPL - see [LICENSE.txt](LICENSE.txt) for details.
61 |
62 | # Authors
63 | IDE/AL has been developed by [Johannes Späth](mailto:joh.spaeth@gmail.com), [Karim Ali](http://karimali.ca) and [Eric Bodden](http://bodden.de).
64 |
--------------------------------------------------------------------------------
/lib/boomerang.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/lib/boomerang.jar
--------------------------------------------------------------------------------
/lib/grph-1.8.0-big.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/lib/grph-1.8.0-big.jar
--------------------------------------------------------------------------------
/lib/heros-trunk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/lib/heros-trunk.jar
--------------------------------------------------------------------------------
/lib/soot-trunk.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/lib/soot-trunk.jar
--------------------------------------------------------------------------------
/src/ideal/AnalysisContext.java:
--------------------------------------------------------------------------------
1 | package ideal;
2 |
3 | import java.util.Collection;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | import com.google.common.base.Stopwatch;
8 | import com.google.common.collect.HashMultimap;
9 | import com.google.common.collect.Multimap;
10 |
11 | import boomerang.AliasFinder;
12 | import boomerang.BoomerangOptions;
13 | import boomerang.BoomerangTimeoutException;
14 | import boomerang.accessgraph.AccessGraph;
15 | import boomerang.cache.AliasResults;
16 | import boomerang.cache.ResultCache;
17 | import boomerang.context.IContextRequester;
18 | import boomerang.context.NoContextRequester;
19 | import boomerang.debug.BoomerangEfficiencyDebugger;
20 | import heros.solver.Pair;
21 | import heros.solver.PathEdge;
22 | import ideal.debug.IDebugger;
23 | import ideal.edgefunction.AnalysisEdgeFunctions;
24 | import ideal.flowfunctions.WrappedAccessGraph;
25 | import ideal.pointsofaliasing.CallSite;
26 | import ideal.pointsofaliasing.InstanceFieldWrite;
27 | import ideal.pointsofaliasing.NullnessCheck;
28 | import ideal.pointsofaliasing.PointOfAlias;
29 | import soot.Unit;
30 | import soot.jimple.infoflow.solver.cfg.BackwardsInfoflowCFG;
31 | import soot.jimple.infoflow.solver.cfg.IInfoflowCFG;
32 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG;
33 |
34 | public class AnalysisContext {
35 |
36 | /**
37 | * Global debugger object.
38 | */
39 | public final IDebugger debugger;
40 | private Set> poas = new HashSet<>();
41 | private boolean idePhase;
42 | private Multimap, WrappedAccessGraph> callSiteToFlows = HashMultimap.create();
43 | private Multimap, WrappedAccessGraph> fieldWritesToFlows = HashMultimap.create();
44 | private Set> callSiteToStrongUpdates = new HashSet<>();
45 | private Set, AccessGraph>> nullnessBranches = new HashSet<>();
46 | private IInfoflowCFG icfg;
47 | private AnalysisSolver solver;
48 | private BackwardsInfoflowCFG bwicfg;
49 | private AnalysisEdgeFunctions edgeFunc;
50 |
51 | public AnalysisContext(IInfoflowCFG icfg, BackwardsInfoflowCFG bwicfg, AnalysisEdgeFunctions edgeFunc,
52 | IDebugger debugger) {
53 | this.icfg = icfg;
54 | this.bwicfg = bwicfg;
55 | this.debugger = debugger;
56 | this.edgeFunc = edgeFunc;
57 | }
58 |
59 | public void setSolver(AnalysisSolver solver) {
60 | this.solver = solver;
61 | }
62 |
63 | public AnalysisEdgeFunctions getEdgeFunctions() {
64 | return edgeFunc;
65 | }
66 |
67 | public boolean addPOA(PointOfAlias poa) {
68 | return poas.add(poa);
69 | }
70 |
71 | public Set> getAndClearPOA() {
72 | HashSet> res = new HashSet<>(poas);
73 | poas.clear();
74 | return res;
75 | }
76 |
77 | public boolean isInIDEPhase() {
78 | return idePhase;
79 | }
80 |
81 | public void enableIDEPhase() {
82 | idePhase = true;
83 | }
84 |
85 | /**
86 | * This methods stores the results, the indirect flow, from alias queries for the appropriate call sites. Then, in the IDE phase,
87 | * the flow edges can be re-created from those earlier stored flows.
88 | * @param callSitePOA
89 | * @param res
90 | * @param isStrongUpdate
91 | */
92 | public void storeComputedCallSiteFlow(CallSite callSitePOA, Set> res,
93 | boolean isStrongUpdate) {
94 | for (PathEdge edge : res) {
95 | WrappedAccessGraph receivesUpdate = edge.factAtTarget();
96 | callSiteToFlows.put(callSitePOA.ignoreEvent(), receivesUpdate);
97 | if (isStrongUpdate) {
98 | debugger.detectedStrongUpdate(callSitePOA.getCallSite(), receivesUpdate);
99 | callSiteToStrongUpdates
100 | .add(new Pair(callSitePOA.getCallSite(), receivesUpdate.getDelegate()));
101 | }
102 | }
103 | }
104 |
105 | /**
106 | * Retrieves for a given call site POA the flow that occured.
107 | * @param cs The call site POA object.
108 | * @return
109 | */
110 | public Collection callSiteFlows(CallSite cs) {
111 | if (!isInIDEPhase())
112 | throw new RuntimeException("This can only be applied in the kill phase");
113 | return callSiteToFlows.get(cs.ignoreEvent());
114 | }
115 |
116 | /**
117 | * At a field write statement all indirect flows are stored by calling that function.
118 | * @param instanceFieldWrite
119 | * @param outFlows
120 | */
121 | public void storeComputeInstanceFieldWrite(InstanceFieldWrite instanceFieldWrite,
122 | Set outFlows) {
123 | fieldWritesToFlows.putAll(instanceFieldWrite, outFlows);
124 | }
125 |
126 | /**
127 | * Retrieve the flows at field write statements.
128 | * @param ifr
129 | * @return
130 | */
131 | public Collection instanceFieldWriteFlows(InstanceFieldWrite ifr) {
132 | if (!isInIDEPhase())
133 | throw new RuntimeException("This can only be applied in the kill phase");
134 | return fieldWritesToFlows.get(ifr);
135 | }
136 |
137 | /**
138 | * For a given callSite check is a strong update can be performed for the returnSideNode.
139 | * @param callSite
140 | * @param returnSideNode
141 | * @return
142 | */
143 | public boolean isStrongUpdate(Unit callSite, WrappedAccessGraph returnSideNode) {
144 | Pair key = new Pair<>(callSite, returnSideNode.getDelegate());
145 | return callSiteToStrongUpdates.contains(key);
146 | }
147 |
148 |
149 | public boolean isNullnessBranch(Unit curr, Unit succ, WrappedAccessGraph returnSideNode) {
150 | Pair, AccessGraph> key = new Pair<>(new Pair(curr, succ),
151 | returnSideNode.getDelegate());
152 | return nullnessBranches.contains(key);
153 | }
154 |
155 | public void storeComputedNullnessFlow(NullnessCheck nullnessCheck, AliasResults results) {
156 | for (AccessGraph receivesUpdate : results.mayAliasSet()) {
157 | nullnessBranches.add(new Pair, AccessGraph>(
158 | new Pair(nullnessCheck.getCurr(), nullnessCheck.getSucc()), receivesUpdate));
159 | }
160 | }
161 |
162 | public IInfoflowCFG icfg() {
163 | return icfg;
164 | }
165 |
166 | public IContextRequester getContextRequestorFor(final WrappedAccessGraph d1, final Unit stmt) {
167 | return solver.getContextRequestorFor(d1, stmt);
168 | }
169 |
170 | public AliasResults aliasesFor(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1) {
171 | Analysis.checkTimeout();
172 | BoomerangOptions opts = new BoomerangOptions();
173 | opts.setQueryBudget(Analysis.ALIAS_BUDGET);
174 | opts.setTrackStaticFields(Analysis.ENABLE_STATIC_FIELDS);
175 | AliasFinder boomerang = new AliasFinder(icfg(),opts);
176 | debugger.beforeAlias(boomerangAccessGraph, curr, d1);
177 | try {
178 | boomerang.startQuery();
179 | AliasResults res = boomerang.findAliasAtStmt(boomerangAccessGraph.getDelegate(), curr,
180 | getContextRequestorFor(d1, curr));
181 | debugger.onAliasesComputed(boomerangAccessGraph, curr, d1, res);
182 | return res;
183 | } catch (BoomerangTimeoutException e) {
184 | debugger.onAliasTimeout(boomerangAccessGraph, curr, d1);
185 | Analysis.checkTimeout();
186 | return new AliasResults();
187 | }
188 | }
189 |
190 | public void destroy() {
191 | poas = null;
192 | callSiteToFlows.clear();
193 | callSiteToFlows = null;
194 | fieldWritesToFlows.clear();
195 | fieldWritesToFlows = null;
196 | callSiteToStrongUpdates = null;
197 | nullnessBranches = null;
198 | icfg = null;
199 | solver = null;
200 | bwicfg = null;
201 | }
202 |
203 | }
204 |
--------------------------------------------------------------------------------
/src/ideal/AnalysisProblem.java:
--------------------------------------------------------------------------------
1 | package ideal;
2 |
3 | import java.util.Collection;
4 |
5 | import boomerang.accessgraph.AccessGraph;
6 | import heros.EdgeFunction;
7 | import heros.solver.Pair;
8 | import heros.solver.PathEdge;
9 | import ideal.edgefunction.AnalysisEdgeFunctions;
10 | import ideal.flowfunctions.WrappedAccessGraph;
11 | import soot.SootMethod;
12 | import soot.Unit;
13 |
14 | public interface AnalysisProblem {
15 |
16 | /**
17 | * This function generates the seed. Each (reachable) statement of the analyzed code is visited.
18 | * To place a seed, a pair of access graph and an edge function must be specified. From this node
19 | * the analysis starts its analysis.
20 | * @param stmt The statement over which is itearted over
21 | * @param calledMethod If stmt is a call site, this set contains the set of called method for the call site.
22 | * @return
23 | */
24 | Collection>> generate(Unit stmt,
25 | Collection calledMethod);
26 |
27 | /**
28 | * This function must generate and return the AnalysisEdgeFunctions that are used for the analysis.
29 | * As for standard IDE in Heros, the edge functions for normal-, call-, return- and call-to-return flows
30 | * have to be specified.
31 | */
32 | AnalysisEdgeFunctions edgeFunctions();
33 |
34 | /**
35 | * This is invoked as a callback when the analysis is finised. It retrieves the seed and the solver as input.
36 | * The client may wish to use that information.
37 | */
38 | void onAnalysisFinished(PathEdge seed, AnalysisSolver solver);
39 |
40 | /**
41 | * Just used to report errors in the typestate analysis.
42 | * @return
43 | */
44 | boolean isInErrorState();
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/ideal/AnalysisSolver.java:
--------------------------------------------------------------------------------
1 | package ideal;
2 |
3 | import java.util.Collection;
4 | import java.util.HashMap;
5 | import java.util.HashSet;
6 | import java.util.Map;
7 | import java.util.Map.Entry;
8 | import java.util.Set;
9 |
10 | import com.google.common.collect.Table.Cell;
11 |
12 | import boomerang.context.Context;
13 | import boomerang.context.IContextRequester;
14 | import heros.EdgeFunction;
15 | import heros.InterproceduralCFG;
16 | import heros.solver.IDESolver;
17 | import heros.solver.Pair;
18 | import heros.solver.PathEdge;
19 | import ideal.edgefunction.AnalysisEdgeFunctions;
20 | import ideal.flowfunctions.WrappedAccessGraph;
21 | import soot.SootMethod;
22 | import soot.Unit;
23 | import soot.jimple.infoflow.solver.cfg.IInfoflowCFG;
24 |
25 | public class AnalysisSolver
26 | extends IDESolver> {
27 |
28 | private AnalysisEdgeFunctions edgeFn2;
29 |
30 | public AnalysisSolver(InterproceduralCFG icfg,
31 | AnalysisContext context, AnalysisEdgeFunctions edgeFn) {
32 | super(new InternalAnalysisProblem(icfg, context, edgeFn));
33 | edgeFn2 = edgeFn;
34 | }
35 |
36 | /**
37 | * Starts the IFDS phase with the given path edge ->
38 | * @param d1
39 | * @param curr
40 | * @param d2
41 | */
42 | public void injectPhase1Seed(WrappedAccessGraph d1, Unit curr, WrappedAccessGraph d2) {
43 | super.propagate(d1, curr, d2, allBottom, null, true);
44 | runExecutorAndAwaitCompletion();
45 | }
46 |
47 | public IInfoflowCFG icfg() {
48 | return (IInfoflowCFG) icfg;
49 | }
50 |
51 |
52 | /**
53 | * Starts the IDE phase with the given path edge -> and the initial edge function
54 | */
55 | public void injectPhase2Seed(WrappedAccessGraph d1, Unit curr, WrappedAccessGraph d2,
56 | EdgeFunction initialFunction, AnalysisContext context) {
57 | super.propagate(d1, curr, d2, initialFunction, null, true);
58 | runExecutorAndAwaitCompletion();
59 | }
60 |
61 | @Override
62 | public void runExecutorAndAwaitCompletion() {
63 | while (!worklist.isEmpty()) {
64 | Runnable pop = worklist.pop();
65 | if (propagationCount % 1000 == 0) {
66 | Analysis.checkTimeout();
67 | }
68 | pop.run();
69 | }
70 | }
71 |
72 |
73 | @Override
74 | protected void scheduleValueProcessing(ValuePropagationTask vpt) {
75 | Analysis.checkTimeout();
76 | super.scheduleValueProcessing(vpt);
77 | }
78 |
79 | @Override
80 | protected void scheduleValueComputationTask(ValueComputationTask task) {
81 | Analysis.checkTimeout();
82 | super.scheduleValueComputationTask(task);
83 | }
84 |
85 |
86 | public IContextRequester getContextRequestorFor(final WrappedAccessGraph d1, final Unit stmt) {
87 | return new IContextRequester() {
88 | @Override
89 | public Collection getCallSiteOf(Context child) {
90 | if (!(child instanceof AnalysisSolver.AliasContext)) {
91 | throw new RuntimeException("Test ");
92 | }
93 | @SuppressWarnings("unchecked")
94 | AliasContext aliasContext = (AliasContext) child;
95 | Set res = new HashSet<>();
96 | if (aliasContext.fact.equals(zeroValue)) {
97 | for (Unit callsites : icfg.getCallersOf(icfg.getMethodOf(aliasContext.stmt))) {
98 | res.add(new AliasContext(zeroValue, callsites));
99 | }
100 | return res;
101 | }
102 | Collection startPoints = icfg.getStartPointsOf(icfg.getMethodOf(aliasContext.stmt));
103 |
104 | for (Unit sp : startPoints) {
105 |
106 | Map>> inc = incoming(aliasContext.fact, sp);
107 |
108 | for (Entry>> e : inc.entrySet()) {
109 | for (Pair p : e.getValue()) {
110 | res.add(new AliasContext(p.getO2(), e.getKey()));
111 | }
112 | }
113 | }
114 | return res;
115 | }
116 |
117 | @Override
118 | public Context initialContext(Unit stmt) {
119 | return new AliasContext(d1, stmt);
120 | }
121 | };
122 | }
123 |
124 | private class AliasContext implements Context {
125 | final Unit stmt;
126 | final WrappedAccessGraph fact;
127 |
128 | AliasContext(WrappedAccessGraph fact, Unit stmt) {
129 | this.fact = fact;
130 | this.stmt = stmt;
131 | }
132 |
133 | @Override
134 | public Unit getStmt() {
135 | return stmt;
136 | }
137 |
138 | @Override
139 | public int hashCode() {
140 | final int prime = 31;
141 | int result = 1;
142 | result = prime * result + ((fact == null) ? 0 : fact.hashCode());
143 | result = prime * result + ((stmt == null) ? 0 : stmt.hashCode());
144 | return result;
145 | }
146 |
147 | @Override
148 | public boolean equals(Object obj) {
149 | if (this == obj)
150 | return true;
151 | if (obj == null)
152 | return false;
153 | if (getClass() != obj.getClass())
154 | return false;
155 | @SuppressWarnings("unchecked")
156 | AliasContext other = (AliasContext) obj;
157 | if (fact == null) {
158 | if (other.fact != null)
159 | return false;
160 | } else if (!fact.equals(other.fact))
161 | return false;
162 | if (stmt == null) {
163 | if (other.stmt != null)
164 | return false;
165 | } else if (!stmt.equals(other.stmt))
166 | return false;
167 | return true;
168 | }
169 |
170 | }
171 |
172 | public void computeValues(PathEdge seed) {
173 | HashMap> map = new HashMap>();
174 | HashSet hashSet = new HashSet<>();
175 | hashSet.add(seed.factAtTarget());
176 | map.put(seed.getTarget(), hashSet);
177 | super.computeValues(map);
178 | }
179 |
180 | public void destroy() {
181 | jumpFn.clear();
182 | incoming.clear();
183 | endSummary.clear();
184 | incoming.clear();
185 | }
186 |
187 | public V bottom(){
188 | return edgeFn2.bottom();
189 | }
190 |
191 | public Set>> getPathEdgesAt(Unit statement) {
192 | return jumpFn.lookupByTarget(statement);
193 | }
194 | }
195 |
--------------------------------------------------------------------------------
/src/ideal/AnalysisTimeoutException.java:
--------------------------------------------------------------------------------
1 | package ideal;
2 |
3 | public class AnalysisTimeoutException extends RuntimeException {
4 |
5 | /**
6 | *
7 | */
8 | private static final long serialVersionUID = 1L;
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/src/ideal/InternalAnalysisProblem.java:
--------------------------------------------------------------------------------
1 | package ideal;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 |
6 | import boomerang.accessgraph.AccessGraph;
7 | import heros.EdgeFunction;
8 | import heros.EdgeFunctions;
9 | import heros.FlowFunctions;
10 | import heros.IDETabulationProblem;
11 | import heros.InterproceduralCFG;
12 | import heros.JoinLattice;
13 | import heros.edgefunc.AllBottom;
14 | import heros.edgefunc.AllTop;
15 | import ideal.edgefunction.AnalysisEdgeFunctions;
16 | import ideal.edgefunction.ForwardEdgeFunctions;
17 | import ideal.flowfunctions.ForwardFlowFunctions;
18 | import ideal.flowfunctions.WrappedAccessGraph;
19 | import soot.SootMethod;
20 | import soot.Unit;
21 |
22 | public class InternalAnalysisProblem implements
23 | IDETabulationProblem> {
24 |
25 | private InterproceduralCFG icfg;
26 | private AnalysisContext context;
27 | private AnalysisEdgeFunctions edgeFunctions;
28 | public final static WrappedAccessGraph ZERO = new WrappedAccessGraph(new AccessGraph(null, null));
29 |
30 | InternalAnalysisProblem(InterproceduralCFG icfg, AnalysisContext context,
31 | AnalysisEdgeFunctions edgeFunctions) {
32 | this.icfg = icfg;
33 | this.context = context;
34 | this.edgeFunctions = edgeFunctions;
35 | }
36 |
37 | @Override
38 | public boolean followReturnsPastSeeds() {
39 | return true;
40 | }
41 |
42 | @Override
43 | public boolean autoAddZero() {
44 | return false;
45 | }
46 |
47 | @Override
48 | public int numThreads() {
49 | return 1;
50 | }
51 |
52 | @Override
53 | public boolean computeValues() {
54 | return false;
55 | }
56 |
57 | @Override
58 | public FlowFunctions flowFunctions() {
59 | return new ForwardFlowFunctions(context);
60 | }
61 |
62 | @Override
63 | public InterproceduralCFG interproceduralCFG() {
64 | return icfg;
65 | }
66 |
67 | @Override
68 | public Map> initialSeeds() {
69 | return null;
70 | }
71 |
72 | @Override
73 | public WrappedAccessGraph zeroValue() {
74 | return ZERO;
75 | }
76 |
77 | @Override
78 | public EdgeFunctions edgeFunctions() {
79 | return new ForwardEdgeFunctions<>(context, edgeFunctions);
80 | }
81 |
82 | @Override
83 | public JoinLattice joinLattice() {
84 | return new JoinLattice() {
85 |
86 | @Override
87 | public V topElement() {
88 | return edgeFunctions.top();
89 | }
90 |
91 | @Override
92 | public V bottomElement() {
93 | return edgeFunctions.bottom();
94 | }
95 |
96 | @Override
97 | public V join(V left, V right) {
98 | if (left == topElement() && right == topElement()) {
99 | return topElement();
100 | }
101 | if (left == bottomElement() && right == bottomElement()) {
102 | return bottomElement();
103 | }
104 | return edgeFunctions.join(left, right);
105 | }
106 | };
107 | }
108 |
109 | @Override
110 | public EdgeFunction allTopFunction() {
111 | return new AllTop(edgeFunctions.top());
112 | }
113 |
114 | public EdgeFunction allBottomFunction() {
115 | return new AllBottom(edgeFunctions.top());
116 | }
117 |
118 | @Override
119 | public boolean recordEdges() {
120 | return false;
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/ideal/debug/IDebugger.java:
--------------------------------------------------------------------------------
1 | package ideal.debug;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 |
6 | import boomerang.accessgraph.AccessGraph;
7 | import boomerang.cache.AliasResults;
8 | import heros.EdgeFunction;
9 | import heros.solver.PathEdge;
10 | import ideal.AnalysisSolver;
11 | import ideal.flowfunctions.WrappedAccessGraph;
12 | import ideal.pointsofaliasing.PointOfAlias;
13 | import soot.Unit;
14 |
15 | public interface IDebugger {
16 |
17 | void computedSeeds(Map, EdgeFunction> seedToInitivalValue);
18 |
19 | void beforeAnalysis();
20 |
21 | void startWithSeed(PathEdge seed);
22 |
23 | void startPhase1WithSeed(PathEdge seed, AnalysisSolver solver);
24 |
25 |
26 | void startPhase2WithSeed(PathEdge s, AnalysisSolver solver);
27 |
28 | void finishPhase1WithSeed(PathEdge seed, AnalysisSolver solver);
29 |
30 | void finishPhase2WithSeed(PathEdge s, AnalysisSolver solver);
31 |
32 | void finishWithSeed(PathEdge seed, boolean timeout, boolean isInErrorState,
33 | AnalysisSolver solver);
34 |
35 | void afterAnalysis();
36 |
37 | void startAliasPhase(Set> pointsOfAlias);
38 |
39 | void startForwardPhase(Set> worklist);
40 |
41 | void onAliasesComputed(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1,
42 | AliasResults res);
43 |
44 | void onAliasTimeout(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1);
45 |
46 | void beforeAlias(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1);
47 |
48 | void killAsOfStrongUpdate(WrappedAccessGraph d1, Unit callSite, WrappedAccessGraph callNode, WrappedAccessGraph returnSideNode,
49 | WrappedAccessGraph returnSideNode2);
50 |
51 | void detectedStrongUpdate(Unit callSite, WrappedAccessGraph receivesUpdate);
52 |
53 | void onAnalysisTimeout(PathEdge seed);
54 |
55 | void solvePOA(PointOfAlias p);
56 |
57 | void onNormalPropagation(WrappedAccessGraph d1, Unit curr, Unit succ, WrappedAccessGraph source);
58 |
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/src/ideal/debug/NullDebugger.java:
--------------------------------------------------------------------------------
1 | package ideal.debug;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 |
6 | import boomerang.cache.AliasResults;
7 | import heros.EdgeFunction;
8 | import heros.solver.PathEdge;
9 | import ideal.AnalysisSolver;
10 | import ideal.flowfunctions.WrappedAccessGraph;
11 | import ideal.pointsofaliasing.PointOfAlias;
12 | import soot.Unit;
13 |
14 | public class NullDebugger implements IDebugger {
15 |
16 | @Override
17 | public void computedSeeds(Map, EdgeFunction> seedToInitivalValue) {
18 |
19 | }
20 |
21 | @Override
22 | public void beforeAnalysis() {
23 |
24 | }
25 |
26 | @Override
27 | public void startWithSeed(PathEdge seed) {
28 |
29 | }
30 |
31 | @Override
32 | public void startPhase1WithSeed(PathEdge seed, AnalysisSolver solver) {
33 |
34 | }
35 |
36 | @Override
37 | public void startPhase2WithSeed(PathEdge s, AnalysisSolver solver) {
38 | }
39 |
40 | @Override
41 | public void finishPhase1WithSeed(PathEdge seed, AnalysisSolver solver) {
42 |
43 | }
44 |
45 | @Override
46 | public void finishPhase2WithSeed(PathEdge s, AnalysisSolver solver) {
47 |
48 | }
49 |
50 | @Override
51 | public void finishWithSeed(PathEdge seed, boolean timeout, boolean isInErrorState, AnalysisSolver solver) {
52 |
53 | }
54 |
55 | @Override
56 | public void afterAnalysis() {
57 |
58 | }
59 |
60 | @Override
61 | public void startAliasPhase(Set> pointsOfAlias) {
62 |
63 | }
64 |
65 | @Override
66 | public void startForwardPhase(Set> worklist) {
67 |
68 | }
69 |
70 | @Override
71 | public void onAliasesComputed(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1,
72 | AliasResults res) {
73 |
74 | }
75 |
76 | @Override
77 | public void onAliasTimeout(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1) {
78 |
79 | }
80 |
81 | @Override
82 | public void beforeAlias(WrappedAccessGraph boomerangAccessGraph, Unit curr, WrappedAccessGraph d1) {
83 |
84 | }
85 |
86 | @Override
87 | public void killAsOfStrongUpdate(WrappedAccessGraph d1, Unit callSite, WrappedAccessGraph callNode,
88 | WrappedAccessGraph returnSideNode, WrappedAccessGraph returnSideNode2) {
89 |
90 | }
91 |
92 | @Override
93 | public void detectedStrongUpdate(Unit callSite, WrappedAccessGraph receivesUpdate) {
94 |
95 | }
96 |
97 | @Override
98 | public void onAnalysisTimeout(PathEdge seed) {
99 |
100 | }
101 |
102 | @Override
103 | public void solvePOA(PointOfAlias p) {
104 |
105 | }
106 |
107 | @Override
108 | public void onNormalPropagation(WrappedAccessGraph sourceFact, Unit curr, Unit succ,WrappedAccessGraph d2) {
109 |
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/ideal/edgefunction/AnalysisEdgeFunctions.java:
--------------------------------------------------------------------------------
1 | package ideal.edgefunction;
2 |
3 | import heros.EdgeFunctions;
4 | import ideal.flowfunctions.WrappedAccessGraph;
5 | import soot.SootMethod;
6 | import soot.Unit;
7 |
8 | /**
9 | * This class just lifts the regular JoinLattice from the Heros solver to the EdgeFunction.
10 | *
11 | */
12 | public interface AnalysisEdgeFunctions extends EdgeFunctions {
13 | V bottom();
14 |
15 | V top();
16 |
17 | V join(V left, V right);
18 | }
19 |
--------------------------------------------------------------------------------
/src/ideal/edgefunction/ForwardEdgeFunctions.java:
--------------------------------------------------------------------------------
1 | package ideal.edgefunction;
2 |
3 | import heros.EdgeFunction;
4 | import heros.EdgeFunctions;
5 | import heros.edgefunc.AllBottom;
6 | import heros.edgefunc.AllTop;
7 | import ideal.AnalysisContext;
8 | import ideal.flowfunctions.WrappedAccessGraph;
9 | import soot.SootMethod;
10 | import soot.Unit;
11 |
12 | public class ForwardEdgeFunctions implements EdgeFunctions {
13 |
14 | private AnalysisContext context;
15 | private final EdgeFunction ALL_TOP;
16 | private final AnalysisEdgeFunctions edgeFunctions;
17 | private final AllBottom ALL_BOTTOM;
18 |
19 | public ForwardEdgeFunctions(AnalysisContext context,
20 | AnalysisEdgeFunctions edgeFunctions) {
21 | this.context = context;
22 | this.edgeFunctions = edgeFunctions;
23 | this.ALL_TOP = new AllTop(edgeFunctions.top());
24 | this.ALL_BOTTOM = new AllBottom(edgeFunctions.top());
25 | }
26 |
27 | @Override
28 | public EdgeFunction getNormalEdgeFunction(WrappedAccessGraph d1, Unit curr,
29 | WrappedAccessGraph currNode, Unit succ, WrappedAccessGraph succNode) {
30 | if (!context.isInIDEPhase())
31 | return ALL_BOTTOM;
32 |
33 | if (context.isNullnessBranch(curr, succ, currNode)) {
34 | return ALL_TOP;
35 | }
36 | return edgeFunctions.getNormalEdgeFunction(d1, curr, currNode, succ, succNode);
37 | }
38 |
39 | @Override
40 | public EdgeFunction getCallEdgeFunction(WrappedAccessGraph callerD1, Unit callSite,
41 | WrappedAccessGraph srcNode, SootMethod calleeMethod, WrappedAccessGraph destNode) {
42 | if (!context.isInIDEPhase())
43 | return ALL_BOTTOM;
44 | return edgeFunctions.getCallEdgeFunction(callerD1, callSite, srcNode, calleeMethod, destNode);
45 | }
46 |
47 | @Override
48 | public EdgeFunction getReturnEdgeFunction(WrappedAccessGraph callerD1,
49 | Unit callSite, SootMethod calleeMethod, Unit exitStmt, WrappedAccessGraph exitNode, Unit returnSite,
50 | WrappedAccessGraph retNode) {
51 | if (!context.isInIDEPhase())
52 | return ALL_BOTTOM;
53 | return edgeFunctions.getReturnEdgeFunction(callerD1, callSite, calleeMethod, exitStmt, exitNode,
54 | returnSite,
55 | retNode);
56 | }
57 |
58 | @Override
59 | public EdgeFunction getCallToReturnEdgeFunction(WrappedAccessGraph d1,
60 | Unit callSite, WrappedAccessGraph callNode, Unit returnSite, WrappedAccessGraph returnSideNode) {
61 | if (!context.isInIDEPhase())
62 | return ALL_BOTTOM;
63 |
64 | // Assign the top function to call-to-return flows where we know about a strong update.
65 | if (context.isStrongUpdate(callSite, returnSideNode)) {
66 | context.debugger.killAsOfStrongUpdate(d1, callSite, callNode, returnSideNode, returnSideNode);
67 | return ALL_TOP;
68 | }
69 | return edgeFunctions.getCallToReturnEdgeFunction(d1, callSite, callNode, returnSite,
70 | returnSideNode);
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/ideal/flowfunctions/WrappedAccessGraph.java:
--------------------------------------------------------------------------------
1 | package ideal.flowfunctions;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | import boomerang.accessgraph.AccessGraph;
7 | import boomerang.accessgraph.FieldGraph;
8 | import boomerang.accessgraph.WrappedSootField;
9 | import heros.solver.JoinHandlingNode;
10 | import soot.Local;
11 | import soot.SootField;
12 | import soot.Type;
13 | import soot.Unit;
14 | import soot.Value;
15 |
16 | public class WrappedAccessGraph implements JoinHandlingNode{
17 |
18 | private final AccessGraph delegate;
19 | private boolean hasEvent;
20 | public WrappedAccessGraph(AccessGraph g, boolean hasEvent){
21 | this.delegate = g;
22 | this.hasEvent = hasEvent;
23 | }
24 |
25 | public WrappedAccessGraph(AccessGraph g){
26 | this(g, false);
27 | }
28 | public boolean baseMatches(Value arg) {
29 | return delegate.baseMatches(arg);
30 | }
31 | public Local getBase() {
32 | return delegate.getBase();
33 | }
34 | public WrappedAccessGraph deriveWithNewLocal(Local local, Type type) {
35 | return new WrappedAccessGraph(delegate.deriveWithNewLocal(local, type), hasEvent);
36 | }
37 | public Type getBaseType() {
38 | return delegate.getBaseType();
39 | }
40 | public FieldGraph getFieldGraph() {
41 | return delegate.getFieldGraph();
42 | }
43 |
44 | public int getFieldCount() {
45 | return delegate.getFieldCount();
46 | }
47 |
48 | public AccessGraph getDelegate() {
49 | return delegate;
50 | }
51 |
52 | public boolean hasEvent() {
53 | return hasEvent;
54 | }
55 |
56 | public WrappedSootField getLastField() {
57 | return delegate.getLastField();
58 | }
59 |
60 | public Set popLastField() {
61 | Set res = new HashSet<>();
62 | for(AccessGraph g : delegate.popLastField()){
63 | res.add(new WrappedAccessGraph(g,hasEvent));
64 | }
65 | return res;
66 | }
67 |
68 | public boolean isStatic() {
69 | return delegate.isStatic();
70 | }
71 |
72 | public boolean baseAndFirstFieldMatches(Value base, SootField field) {
73 | return delegate.baseAndFirstFieldMatches(base, field);
74 | }
75 |
76 | public Set popFirstField() {
77 | Set res = new HashSet<>();
78 | for(AccessGraph g : delegate.popFirstField()){
79 | res.add(new WrappedAccessGraph(g,hasEvent));
80 | }
81 | return res;
82 | }
83 |
84 | public WrappedAccessGraph prependField(WrappedSootField newFirstField) {
85 | return new WrappedAccessGraph(delegate.prependField(newFirstField),hasEvent);
86 | }
87 |
88 | public WrappedAccessGraph makeStatic() {
89 | return new WrappedAccessGraph(delegate.makeStatic(), hasEvent);
90 | }
91 |
92 | public WrappedSootField getFirstField() {
93 | return delegate.getFirstField();
94 | }
95 |
96 | public boolean firstFieldMatches(SootField field) {
97 | return delegate.firstFieldMatches(field);
98 | }
99 |
100 | public WrappedAccessGraph deriveWithoutAllocationSite() {
101 | return new WrappedAccessGraph(delegate.deriveWithoutAllocationSite(),hasEvent);
102 | }
103 |
104 | public boolean hasAllocationSite() {
105 | return delegate.hasAllocationSite();
106 | }
107 |
108 | public Unit getSourceStmt() {
109 | return delegate.getSourceStmt();
110 | }
111 |
112 | @Override
113 | public int hashCode() {
114 | final int prime = 31;
115 | int result = 1;
116 | result = prime * result + ((delegate == null) ? 0 : delegate.hashCode());
117 | result = prime * result + (hasEvent ? 1231 : 1237);
118 | return result;
119 | }
120 |
121 | @Override
122 | public boolean equals(Object obj) {
123 | if (this == obj)
124 | return true;
125 | if (obj == null)
126 | return false;
127 | if (getClass() != obj.getClass())
128 | return false;
129 | WrappedAccessGraph other = (WrappedAccessGraph) obj;
130 | if (delegate == null) {
131 | if (other.delegate != null)
132 | return false;
133 | } else if (!delegate.equals(other.delegate))
134 | return false;
135 | if (hasEvent != other.hasEvent)
136 | return false;
137 | return true;
138 | }
139 |
140 | @Override
141 | public boolean handleJoin(WrappedAccessGraph joiningNode) {
142 | return false;
143 | }
144 |
145 | @Override
146 | public heros.solver.JoinHandlingNode.JoinKey createJoinKey() {
147 | return null;
148 | }
149 |
150 | @Override
151 | public void setCallingContext(WrappedAccessGraph callingContext) {
152 | this.hasEvent = callingContext.hasEvent || hasEvent;
153 | }
154 |
155 | public WrappedAccessGraph deriveWithoutEvent() {
156 | return new WrappedAccessGraph(delegate, false);
157 | }
158 | public WrappedAccessGraph deriveWithEvent() {
159 | return new WrappedAccessGraph(delegate, true);
160 | }
161 |
162 | public Type getType() {
163 | return delegate.getType();
164 | }
165 |
166 | public String toString(){
167 | return delegate.toString() + " "+hasEvent;
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/src/ideal/pointsofaliasing/CallSite.java:
--------------------------------------------------------------------------------
1 | package ideal.pointsofaliasing;
2 |
3 | import java.util.Collection;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | import boomerang.accessgraph.AccessGraph;
8 | import boomerang.accessgraph.WrappedSootField;
9 | import boomerang.cache.AliasResults;
10 | import heros.solver.PathEdge;
11 | import ideal.AnalysisContext;
12 | import ideal.flowfunctions.WrappedAccessGraph;
13 | import soot.Unit;
14 |
15 | public class CallSite extends PointOfAlias {
16 |
17 | private WrappedAccessGraph callerCallSiteFact;
18 |
19 | public CallSite(WrappedAccessGraph callerD1, Unit stmt, WrappedAccessGraph callerCallSiteFact,
20 | WrappedAccessGraph callerD2, Unit returnSite) {
21 | super(callerD1, stmt, callerD2, returnSite);
22 | this.callerCallSiteFact = callerCallSiteFact;
23 | }
24 |
25 | @Override
26 | public Collection> getPathEdges(AnalysisContext tsanalysis) {
27 | Collection> res = new HashSet<>();
28 | if (d2.hasEvent())
29 | res = balancedReturn(tsanalysis);
30 | if (d2.getFieldCount() > 0 && !callerCallSiteFact.equals(d2))
31 | res.addAll(unbalancedReturn(tsanalysis));
32 | return res;
33 | }
34 |
35 | private Collection> balancedReturn(AnalysisContext tsanalysis) {
36 | Set> res = new HashSet<>();
37 | AliasResults results = tsanalysis.aliasesFor(d2, curr, d1);
38 | for (AccessGraph mayAliasingWrappedAccessGraph : results.mayAliasSet()) {
39 | res.add(new PathEdge(d1, succ,
40 | new WrappedAccessGraph(mayAliasingWrappedAccessGraph, d2.hasEvent())));
41 | }
42 | checkMustAlias(results, res, tsanalysis);
43 | return res;
44 | }
45 |
46 | private Collection> unbalancedReturn(AnalysisContext tsanalysis) {
47 | WrappedSootField lastField = d2.getLastField();
48 | Set popLastField = d2.popLastField();
49 | Set> res = new HashSet<>();
50 | for (WrappedAccessGraph withoutLast : popLastField) {
51 | AliasResults results = tsanalysis.aliasesFor(withoutLast, curr, d1);
52 |
53 | for (AccessGraph mayAliasingWrappedAccessGraph : results.mayAliasSet()) {
54 | AccessGraph g = mayAliasingWrappedAccessGraph.appendFields(new WrappedSootField[] { lastField });
55 | res.add(new PathEdge(d1, succ, new WrappedAccessGraph(g, d2.hasEvent())));
56 | }
57 | }
58 | tsanalysis.storeComputedCallSiteFlow(this, res, false);
59 | return res;
60 | }
61 |
62 | private void checkMustAlias(AliasResults results, Set> res,
63 | AnalysisContext context) {
64 | boolean isStrongUpdate = results.keySet().size() == 1;
65 | context.storeComputedCallSiteFlow(this, res, isStrongUpdate);
66 | }
67 |
68 | public Unit getCallSite() {
69 | return curr;
70 | }
71 |
72 | @Override
73 | public String toString() {
74 | return "[CallSite " + super.toString() + " returns to: " + succ + "]";
75 | }
76 |
77 | public CallSite ignoreEvent() {
78 | return new CallSite(d1.deriveWithoutEvent(), curr, callerCallSiteFact.deriveWithoutEvent(),
79 | d2.deriveWithoutEvent(), succ);
80 | }
81 |
82 | @Override
83 | public int hashCode() {
84 | final int prime = 31;
85 | int result = super.hashCode();
86 | result = prime * result + ((callerCallSiteFact == null) ? 0 : callerCallSiteFact.hashCode());
87 | return result;
88 | }
89 |
90 | @Override
91 | public boolean equals(Object obj) {
92 | if (this == obj)
93 | return true;
94 | if (!super.equals(obj))
95 | return false;
96 | if (getClass() != obj.getClass())
97 | return false;
98 | CallSite other = (CallSite) obj;
99 | if (callerCallSiteFact == null) {
100 | if (other.callerCallSiteFact != null)
101 | return false;
102 | } else if (!callerCallSiteFact.equals(other.callerCallSiteFact))
103 | return false;
104 | return true;
105 | }
106 |
107 | public boolean triggersQuery() {
108 | return d2.hasEvent() || (d2.getFieldCount() > 0 && !callerCallSiteFact.equals(d2));
109 | }
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/src/ideal/pointsofaliasing/InstanceFieldWrite.java:
--------------------------------------------------------------------------------
1 | package ideal.pointsofaliasing;
2 |
3 | import java.util.Collection;
4 | import java.util.HashSet;
5 | import java.util.Set;
6 |
7 | import com.google.common.base.Stopwatch;
8 |
9 | import boomerang.AliasFinder;
10 | import boomerang.accessgraph.AccessGraph;
11 | import boomerang.cache.AliasResults;
12 | import heros.solver.PathEdge;
13 | import ideal.AnalysisContext;
14 | import ideal.flowfunctions.WrappedAccessGraph;
15 | import soot.Local;
16 | import soot.Unit;
17 |
18 | public class InstanceFieldWrite extends PointOfAlias {
19 |
20 | private Local base;
21 |
22 | public InstanceFieldWrite(WrappedAccessGraph d1, Unit stmt, Local base, WrappedAccessGraph d2, Unit succ) {
23 | super(d1, stmt, d2, succ);
24 | this.base = base;
25 | }
26 |
27 | @Override
28 | public Collection> getPathEdges(AnalysisContext tsanalysis) {
29 | Set> res = new HashSet<>();
30 |
31 | AliasFinder aliasFinder = new AliasFinder(tsanalysis.icfg());
32 | aliasFinder.startQuery();
33 | WrappedAccessGraph accessGraph = new WrappedAccessGraph(new AccessGraph(base, base.getType()));
34 | AliasResults results = tsanalysis.aliasesFor(accessGraph, curr, d1);
35 |
36 | Set outFlows = new HashSet<>();
37 | for (AccessGraph mayAliasingWrappedAccessGraph : results.mayAliasSet()) {
38 | WrappedAccessGraph withFields = new WrappedAccessGraph(mayAliasingWrappedAccessGraph.appendGraph(d2.getFieldGraph()),d2.hasEvent());
39 | outFlows.add(withFields);
40 | res.add(new PathEdge(d1, succ, withFields));
41 | }
42 | tsanalysis.storeComputeInstanceFieldWrite(this, outFlows);
43 | return res;
44 | }
45 |
46 | public Unit getCallSite() {
47 | return curr;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/ideal/pointsofaliasing/NullnessCheck.java:
--------------------------------------------------------------------------------
1 | package ideal.pointsofaliasing;
2 |
3 | import java.util.Collection;
4 | import java.util.Collections;
5 |
6 | import boomerang.cache.AliasResults;
7 | import heros.solver.PathEdge;
8 | import ideal.AnalysisContext;
9 | import ideal.flowfunctions.WrappedAccessGraph;
10 | import soot.Unit;
11 |
12 | public class NullnessCheck extends PointOfAlias {
13 | public NullnessCheck(WrappedAccessGraph callerD1, Unit stmt, WrappedAccessGraph callerD2, Unit returnSite) {
14 | super(callerD1, stmt, callerD2, returnSite);
15 | }
16 |
17 | @Override
18 | public Collection> getPathEdges(
19 | AnalysisContext tsanalysis) {
20 | AliasResults results = tsanalysis.aliasesFor(d2, curr, d1);
21 | if (results.keySet().size() == 1) {
22 | tsanalysis.storeComputedNullnessFlow(this, results);
23 | }
24 | return Collections.emptySet();
25 | }
26 |
27 | public Unit getCurr() {
28 | return curr;
29 | }
30 |
31 | public Unit getSucc() {
32 | return succ;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "[Nullness " + super.toString() + " ifs to: " + succ + "]";
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/ideal/pointsofaliasing/PointOfAlias.java:
--------------------------------------------------------------------------------
1 | package ideal.pointsofaliasing;
2 |
3 | import java.util.Collection;
4 |
5 | import heros.solver.PathEdge;
6 | import ideal.AnalysisContext;
7 | import ideal.flowfunctions.WrappedAccessGraph;
8 | import soot.Unit;
9 |
10 | public abstract class PointOfAlias {
11 | protected WrappedAccessGraph d2;
12 | protected Unit curr;
13 | protected Unit succ;
14 | protected WrappedAccessGraph d1;
15 |
16 | public PointOfAlias(WrappedAccessGraph d1, Unit stmt, WrappedAccessGraph d2, Unit succ) {
17 | this.d1 = d1;
18 | this.curr = stmt;
19 | this.d2 = d2;
20 | this.succ = succ;
21 | }
22 |
23 |
24 | /**
25 | * Generates the path edges the given POA should generate.
26 | */
27 | public abstract Collection> getPathEdges(
28 | AnalysisContext tsanalysis);
29 |
30 |
31 |
32 | public String toString() {
33 | return "<" + d1.toString() + ">-<" + curr.toString() + "," + d2 + ">";
34 | }
35 |
36 | @Override
37 | public int hashCode() {
38 | final int prime = 31;
39 | int result = 1;
40 | result = prime * result + ((curr == null) ? 0 : curr.hashCode());
41 | result = prime * result + ((d1 == null) ? 0 : d1.hashCode());
42 | result = prime * result + ((d2 == null) ? 0 : d2.hashCode());
43 | result = prime * result + ((succ == null) ? 0 : succ.hashCode());
44 | return result;
45 | }
46 |
47 | @Override
48 | public boolean equals(Object obj) {
49 | if (this == obj)
50 | return true;
51 | if (obj == null)
52 | return false;
53 | if (getClass() != obj.getClass())
54 | return false;
55 | @SuppressWarnings("rawtypes")
56 | PointOfAlias other = (PointOfAlias) obj;
57 | if (curr == null) {
58 | if (other.curr != null)
59 | return false;
60 | } else if (!curr.equals(other.curr))
61 | return false;
62 | if (d1 == null) {
63 | if (other.d1 != null)
64 | return false;
65 | } else if (!d1.equals(other.d1))
66 | return false;
67 | if (d2 == null) {
68 | if (other.d2 != null)
69 | return false;
70 | } else if (!d2.equals(other.d2))
71 | return false;
72 | if (succ == null) {
73 | if (other.succ != null)
74 | return false;
75 | } else if (!succ.equals(other.succ))
76 | return false;
77 | return true;
78 | };
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/targets/file/File.java:
--------------------------------------------------------------------------------
1 | package file;
2 | public class File {
3 | public void open() {
4 |
5 | }
6 |
7 | public void close() {
8 | };
9 |
10 | public int hashCode() {
11 | return 9;
12 | }
13 |
14 | public void wrappedClose(){
15 | close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/ObjectWithField.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class ObjectWithField {
4 | File field;
5 | }
6 |
--------------------------------------------------------------------------------
/targets/file/SummaryTarget1.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class SummaryTarget1 {
4 | public static void main(String[] args) {
5 | File file1 = new File();
6 | call(file1);
7 | file1.close();
8 | File file = new File();
9 | File alias = file;
10 | call(alias);
11 | file.close();
12 | }
13 |
14 | private static void call(File alias) {
15 | alias.open();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target1.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target1 {
4 | public static void main(String[] args) {
5 | File file = new File();
6 | file.open();
7 | file.close();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/targets/file/Target10.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target10 {
4 | public static void main(String[] args) {
5 | File file = new File();
6 | file.open();
7 | flows(file, true);
8 | }
9 |
10 | private static void flows(File file, boolean b) {
11 | if (b)
12 | file.close();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/targets/file/Target11.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target11 {
4 | public static void main(String[] args) {
5 | Target11 target11 = new Target11();
6 | File file = new File();
7 | Flow flow = (args != null ? target11.new ImplFlow1() : target11.new ImplFlow2());
8 | flow.flow(file);
9 | }
10 |
11 | private static void flows(File file, boolean b) {
12 | if (b)
13 | file.close();
14 | }
15 |
16 | public class ImplFlow1 implements Flow {
17 |
18 | @Override
19 | public void flow(File file) {
20 | file.open();
21 | }
22 |
23 | }
24 | public class ImplFlow2 implements Flow {
25 |
26 | @Override
27 | public void flow(File file) {
28 | file.close();
29 | }
30 |
31 | }
32 | private interface Flow {
33 | void flow(File file);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/targets/file/Target12.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target12 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | flows(container);
7 | if (args != null)
8 | container.field.close();
9 | }
10 |
11 | private static void flows(ObjectWithField container) {
12 | container.field = new File();
13 | File field = container.field;
14 | field.open();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/targets/file/Target13.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target13 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | flows(container);
7 | if (container.field != null)
8 | container.field.close();
9 | }
10 |
11 | private static void flows(ObjectWithField container) {
12 | container.field = new File();
13 | File field = container.field;
14 | field.open();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/targets/file/Target14.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target14 {
4 | public static void main(String[] args) {
5 | File file = null;
6 | if (args != null)
7 | file = new File();
8 |
9 | file.open();
10 | if (file != null)
11 | file.close();
12 | }
13 |
14 | private static void flows(ObjectWithField container) {
15 | container.field = new File();
16 | File field = container.field;
17 | field.open();
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/targets/file/Target15.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target15 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | flows(a, b);
8 | }
9 |
10 | private static void flows(ObjectWithField a, ObjectWithField b) {
11 | File file = new File();
12 | file.open();
13 | a.field = file;
14 | File alias = b.field;
15 | alias.close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target16.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target16 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | file.open();
9 | flows(a, b, file);
10 | }
11 |
12 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
13 | a.field = file;
14 | File alias = b.field;
15 | if (alias != null)
16 | alias.close();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/targets/file/Target17.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target17 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | a.field = file;
9 | file.open();
10 | if (b.field != null)
11 | b.field.close();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/targets/file/Target18.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target18 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | file.open();
9 | flows(a, b, file);
10 | }
11 |
12 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
13 | a.field = file;
14 | File alias = b.field;
15 | if (alias != null)
16 | call();
17 | }
18 |
19 | private static void call() {
20 | // TODO Auto-generated method stub
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/targets/file/Target19.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target19 {
4 | public static void main(String[] args) {
5 | File b = null;
6 | File a = new File();
7 | a.open();
8 | File e = new File();
9 | e.open();
10 | if (args != null) {
11 | b = a;
12 | } else {
13 | b = e;
14 | }
15 | b.close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target2.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target2 {
4 | public static void main(String[] args) {
5 | File file = new File();
6 | File alias = file;
7 | call(alias, file);
8 | }
9 |
10 | private static void call(File file1, File file2) {
11 | file1.open();
12 | file2.close();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/targets/file/Target20.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target20 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | file.open();
9 | flows(a, b, file);
10 | }
11 |
12 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
13 | a.field = file;
14 | File alias = b.field;
15 | if (alias != null)
16 | call();
17 | }
18 |
19 | private static void call() {
20 | // TODO Auto-generated method stub
21 |
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/targets/file/Target21.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target21 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | file.open();
9 | flows(a, b, file);
10 | b.field.close();
11 | }
12 |
13 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
14 | a.field = file;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/targets/file/Target22.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target22 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | File file = new File();
7 | file.open();
8 | a.field = file;
9 | if (a.field != null) {
10 | a.field.close();
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/targets/file/Target23.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target23 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = null;
6 | if (args != null)
7 | a = new ObjectWithField();
8 | File file = new File();
9 | file.open();
10 | a.field = file;
11 | if (a != null) {
12 | a.field.close();
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/targets/file/Target24.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target24 {
4 | public static void main(String[] args) {
5 | File b = null;
6 | File a = new File();
7 | a.open();
8 | File e = new File();
9 | e.open();
10 | if (args != null) {
11 | b = a;
12 | } else {
13 | b = e;
14 | }
15 | if (b != null)
16 | b.close();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/targets/file/Target25.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target25 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = new ObjectWithField();
7 | File file = new File();
8 | if (args != null) {
9 | b.field = file;
10 | } else {
11 | a.field = file;
12 | }
13 | a.field.open();
14 | b.field.close();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/targets/file/Target26.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target26 {
4 | public static void main(String[] args) {
5 | File first = createOpenedFile();
6 | clse(first);
7 |
8 | File second = createOpenedFile();
9 | second.hashCode();
10 | }
11 |
12 | private static void clse(File first) {
13 | first.close();
14 | }
15 |
16 | public static File createOpenedFile() {
17 | File f = new File();
18 | f.open();
19 | return f;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/targets/file/Target27.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target27 {
4 | public static void main(String[] args) {
5 | File first = createOpenedFile();
6 | first.close();
7 |
8 | File second = createOpenedFile();
9 | second.getClass();
10 | }
11 |
12 | public static File createOpenedFile() {
13 | File f = new File();
14 | f.open();
15 | return f;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target28.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target28 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | file.open();
9 | wrappedFlows(a, b, file);
10 | }
11 |
12 | private static void wrappedFlows(ObjectWithField a, ObjectWithField b, File file) {
13 | flows(a,b,file);
14 | }
15 |
16 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
17 | a.field = file;
18 | File alias = b.field;
19 | if (alias != null)
20 | alias.close();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/targets/file/Target29.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target29 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | wrappedFlows(a, b, file);
9 | }
10 |
11 | private static void wrappedFlows(ObjectWithField a, ObjectWithField b, File file) {
12 | flows(a,b,file);
13 | }
14 |
15 | private static void flows(ObjectWithField a, ObjectWithField b, File file) {
16 | a.field = file;
17 | File alias = b.field;
18 | if (alias != null)
19 | file.open();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/targets/file/Target3.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target3 {
4 | public static void main(String[] args) {
5 | File file = new File();
6 | File alias = file;
7 | call(alias);
8 | file.close();
9 | }
10 |
11 | private static void call(File alias) {
12 | alias.open();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/targets/file/Target30.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target30 {
4 | public static void main(String[] args) {
5 | ObjectWithField a = new ObjectWithField();
6 | ObjectWithField b = a;
7 | File file = new File();
8 | bar(a,file);
9 | File c = b.field;
10 | c.close();
11 | }
12 |
13 | private static void bar(ObjectWithField a, File file) {
14 | file.open();
15 | a.field = file;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target4.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target4 {
4 | public static void main(String[] args) {
5 | File file = new File();
6 | File alias = file;
7 | call(alias);
8 | }
9 |
10 | private static void call(File alias) {
11 | alias.open();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/targets/file/Target5.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target5 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | container.field = new File();
7 | File a = container.field;
8 | a.open();
9 | a.close();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/targets/file/Target6.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target6 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | container.field = new File();
7 | File a = container.field;
8 | a.open();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/targets/file/Target7.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target7 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | container.field = new File();
7 | flows(container);
8 | }
9 |
10 | private static void flows(ObjectWithField container) {
11 | File field = container.field;
12 | field.open();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/targets/file/Target8.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target8 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | container.field = new File();
7 | ObjectWithField otherContainer = new ObjectWithField();
8 | File a = container.field;
9 | otherContainer.field = a;
10 | flows(container);
11 | }
12 |
13 | private static void flows(ObjectWithField container) {
14 | File field = container.field;
15 | field.open();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/targets/file/Target9.java:
--------------------------------------------------------------------------------
1 | package file;
2 |
3 | public class Target9 {
4 | public static void main(String[] args) {
5 | ObjectWithField container = new ObjectWithField();
6 | flows(container);
7 | container.field.close();
8 | }
9 |
10 | private static void flows(ObjectWithField container) {
11 | container.field = new File();
12 | File field = container.field;
13 | field.open();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/targets/inputstream/InputStreamTarget1.java:
--------------------------------------------------------------------------------
1 | package inputstream;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | public class InputStreamTarget1 {
8 | public static void main(String... args) throws IOException {
9 | InputStream inputStream = new FileInputStream("");
10 | inputStream.close();
11 | inputStream.read();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/targets/inputstream/InputStreamTarget2.java:
--------------------------------------------------------------------------------
1 | package inputstream;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | public class InputStreamTarget2 {
8 | public static void main(String... args) throws IOException {
9 | InputStream inputStream = new FileInputStream("");
10 | inputStream.close();
11 | inputStream.close();
12 | inputStream.read();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/targets/inputstream/InputStreamTarget3.java:
--------------------------------------------------------------------------------
1 | package inputstream;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | public class InputStreamTarget3 {
8 | public static void main(String... args) throws IOException {
9 | InputStream inputStream = new FileInputStream("");
10 | inputStream.read();
11 | inputStream.close();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/targets/iterator/IteratorTarget1.java:
--------------------------------------------------------------------------------
1 | package iterator;
2 |
3 | import java.util.LinkedList;
4 | import java.util.List;
5 |
6 | public class IteratorTarget1 {
7 | public static void main(String... args) {
8 | List |