├── .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 list = new LinkedList<>(); 9 | list.add(new Object()); 10 | java.util.Iterator iterator = list.iterator(); 11 | iterator.hasNext(); 12 | iterator.next(); 13 | iterator.next(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget2.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | 6 | public class IteratorTarget2 { 7 | public static void main(String... args) { 8 | List list = new LinkedList<>(); 9 | list.add(new Object()); 10 | list.add(new Object()); 11 | for (Object l : list) { 12 | System.out.println(l); 13 | } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget3.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | public class IteratorTarget3 { 4 | public static void main(String... args) { 5 | MyLinkedList list = new MyLinkedList<>(); 6 | list.add(new Object()); 7 | java.util.Iterator iterator = list.iterator(); 8 | iterator.hasNext(); 9 | iterator.next(); 10 | iterator.next(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget4.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class IteratorTarget4 { 6 | public static void main(String... args) { 7 | LinkedList list = new LinkedList<>(); 8 | list.add(new Object()); 9 | for (Object each : list) { 10 | try { 11 | each.toString(); 12 | } catch (Throwable e) { 13 | e.getMessage(); 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget5.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.HashSet; 4 | 5 | public class IteratorTarget5 { 6 | public static void main(String... args) { 7 | HashSet list = new HashSet<>(); 8 | // LinkedHashSet list2 = new LinkedHashSet<>(); 9 | list.add(new Object()); 10 | for (Object each : list) { 11 | // list2.add(each); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget6.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.LinkedList; 4 | 5 | public class IteratorTarget6 { 6 | public static void main(String... args) { 7 | LinkedList list = new LinkedList<>(); 8 | LinkedList list2 = new LinkedList<>(); 9 | list.add(new Object()); 10 | for (Object each : list) { 11 | list2.add(each); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget7.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.LinkedHashSet; 4 | 5 | public class IteratorTarget7 { 6 | public static void main(String... args) { 7 | LinkedHashSet list = new LinkedHashSet<>(); 8 | LinkedHashSet list2 = new LinkedHashSet<>(); 9 | list.add(new Object()); 10 | for (Object each : list) { 11 | list2.add(each); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget8.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.LinkedHashSet; 4 | 5 | public class IteratorTarget8 { 6 | public static void main(String... args) { 7 | invoke(); 8 | } 9 | 10 | private static boolean invoke() { 11 | LinkedHashSet list = new LinkedHashSet<>(); 12 | list.add(new Object()); 13 | for (Object each : list) { 14 | if (each.hashCode() == 1) 15 | return true; 16 | } 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /targets/iterator/IteratorTarget9.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | 7 | public class IteratorTarget9 { 8 | 9 | public static void main(String[] args) { 10 | List l1 = new ArrayList(); 11 | List l2 = new ArrayList(); 12 | 13 | l1.add("foo"); 14 | l1.add("moo"); 15 | l1.add("zoo"); 16 | 17 | Object v; 18 | for (Iterator it1 = l1.iterator(); it1.hasNext(); v = it1.next()) { 19 | System.out.println(foo(it1)); 20 | } 21 | } 22 | 23 | public static Object foo(Iterator it) { 24 | return it.next(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /targets/iterator/MyIterator.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.Iterator; 4 | 5 | public class MyIterator implements Iterator { 6 | 7 | @Override 8 | public boolean hasNext() { 9 | return false; 10 | } 11 | 12 | @Override 13 | public V next() { 14 | return null; 15 | } 16 | 17 | @Override 18 | public void remove() { 19 | // TODO Auto-generated method stub 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /targets/iterator/MyLinkedList.java: -------------------------------------------------------------------------------- 1 | package iterator; 2 | 3 | import java.util.Iterator; 4 | 5 | public class MyLinkedList { 6 | 7 | public void add(Object object) { 8 | // TODO Auto-generated method stub 9 | 10 | } 11 | 12 | public Iterator iterator() { 13 | return new MyIterator(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /targets/keystore/KeyStoreTarget1.java: -------------------------------------------------------------------------------- 1 | package keystore; 2 | 3 | import java.io.IOException; 4 | import java.security.KeyStore; 5 | import java.security.KeyStoreException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.cert.CertificateException; 8 | 9 | public class KeyStoreTarget1 { 10 | public static void main(String... args) 11 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 12 | KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 13 | 14 | java.io.FileInputStream fis = null; 15 | try { 16 | fis = new java.io.FileInputStream("keyStoreName"); 17 | ks.load(fis, null); 18 | } finally { 19 | if (fis != null) { 20 | fis.close(); 21 | } 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /targets/keystore/KeyStoreTarget2.java: -------------------------------------------------------------------------------- 1 | package keystore; 2 | 3 | import java.io.IOException; 4 | import java.security.KeyStore; 5 | import java.security.KeyStoreException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.cert.CertificateException; 8 | 9 | public class KeyStoreTarget2 { 10 | public static void main(String... args) 11 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 12 | KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 13 | ks.aliases(); 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /targets/keystore/KeyStoreTarget3.java: -------------------------------------------------------------------------------- 1 | package keystore; 2 | 3 | import java.io.IOException; 4 | import java.security.KeyStore; 5 | import java.security.KeyStoreException; 6 | import java.security.NoSuchAlgorithmException; 7 | import java.security.cert.CertificateException; 8 | 9 | public class KeyStoreTarget3 { 10 | public static void main(String... args) 11 | throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { 12 | KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 13 | 14 | java.io.FileInputStream fis = null; 15 | try { 16 | fis = new java.io.FileInputStream("keyStoreName"); 17 | ks.load(fis, null); 18 | } finally { 19 | if (fis != null) { 20 | fis.close(); 21 | } 22 | } 23 | ks.aliases(); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /targets/printstream/PrintStreamTarget1.java: -------------------------------------------------------------------------------- 1 | package printstream; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintStream; 5 | 6 | public class PrintStreamTarget1 { 7 | public static void main(String... args) throws IOException { 8 | PrintStream inputStream = new PrintStream(""); 9 | inputStream.close(); 10 | inputStream.flush(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/printwriter/PrintWriterTarget1.java: -------------------------------------------------------------------------------- 1 | package printwriter; 2 | 3 | import java.io.IOException; 4 | import java.io.PrintWriter; 5 | 6 | public class PrintWriterTarget1 { 7 | public static void main(String... args) throws IOException { 8 | PrintWriter inputStream = new PrintWriter(""); 9 | inputStream.close(); 10 | inputStream.flush(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/socket/SocketTarget1.java: -------------------------------------------------------------------------------- 1 | package socket; 2 | 3 | import java.io.IOException; 4 | import java.net.Socket; 5 | import java.net.SocketAddress; 6 | 7 | public class SocketTarget1 { 8 | public static void main(String... args) throws IOException { 9 | Socket socket = new Socket(); 10 | socket.connect(new SocketAddress() {}); 11 | socket.sendUrgentData(2); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /targets/socket/SocketTarget2.java: -------------------------------------------------------------------------------- 1 | package socket; 2 | 3 | import java.io.IOException; 4 | import java.net.Socket; 5 | 6 | public class SocketTarget2 { 7 | public static void main(String... args) throws IOException { 8 | Socket socket = new Socket(); 9 | socket.sendUrgentData(2); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /targets/socket/SocketTarget3.java: -------------------------------------------------------------------------------- 1 | package socket; 2 | 3 | import java.io.IOException; 4 | import java.net.Socket; 5 | 6 | public class SocketTarget3 { 7 | public static void main(String... args) throws IOException { 8 | Socket socket = new Socket(); 9 | socket.sendUrgentData(2); 10 | socket.sendUrgentData(2); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/socket/SocketTarget4.java: -------------------------------------------------------------------------------- 1 | package socket; 2 | 3 | import java.io.IOException; 4 | import java.net.Socket; 5 | import java.util.Collection; 6 | import java.util.Iterator; 7 | import java.util.LinkedList; 8 | 9 | public class SocketTarget4 { 10 | public static Socket createSocket() { 11 | return new Socket(); 12 | } 13 | 14 | public static Collection createSockets() { 15 | Collection result = new LinkedList<>(); 16 | for (int i = 0; i < 5; i++) { 17 | result.add(new Socket()); 18 | } 19 | return result; 20 | } 21 | 22 | 23 | 24 | public static void talk(Socket s) throws IOException { 25 | s.getChannel(); 26 | } 27 | 28 | public static void main(String... args) throws IOException { 29 | Collection sockets = createSockets(); 30 | for (Iterator it = sockets.iterator(); it.hasNext();) { 31 | Socket s = (Socket) it.next(); 32 | s.connect(null); 33 | talk(s); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /targets/stack/StackTarget1.java: -------------------------------------------------------------------------------- 1 | package stack; 2 | 3 | import java.io.IOException; 4 | import java.util.Stack; 5 | 6 | public class StackTarget1 { 7 | public static void main(String... args) throws IOException { 8 | Stack s = new Stack(); 9 | if (args == null) 10 | s.peek(); 11 | else { 12 | Stack r = s; 13 | r.pop(); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /targets/stack/StackTarget2.java: -------------------------------------------------------------------------------- 1 | package stack; 2 | 3 | import java.io.IOException; 4 | import java.util.Stack; 5 | 6 | public class StackTarget2 { 7 | public static void main(String... args) throws IOException { 8 | Stack s = new Stack(); 9 | s.add(new Object()); 10 | if (args == null) 11 | s.peek(); 12 | else 13 | s.pop(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /targets/stack/StackTarget3.java: -------------------------------------------------------------------------------- 1 | package stack; 2 | 3 | import java.io.IOException; 4 | import java.util.Stack; 5 | 6 | public class StackTarget3 { 7 | public static void main(String... args) throws IOException { 8 | Stack s = new Stack(); 9 | s.peek(); 10 | s.pop(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/stack/StackTarget4.java: -------------------------------------------------------------------------------- 1 | package stack; 2 | 3 | import java.io.IOException; 4 | import java.util.Stack; 5 | 6 | public class StackTarget4 { 7 | public static void main(String... args) throws IOException { 8 | Stack s = new Stack(); 9 | s.peek(); 10 | s.pop(); 11 | 12 | Stack c = new Stack(); 13 | c.add(new Object()); 14 | c.peek(); 15 | c.pop(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /targets/urlconn/URLConnTarget1.java: -------------------------------------------------------------------------------- 1 | package urlconn; 2 | 3 | import java.io.IOException; 4 | import java.net.HttpURLConnection; 5 | 6 | public class URLConnTarget1 { 7 | public static void main(String... args) throws IOException { 8 | HttpURLConnection httpURLConnection = new HttpURLConnection(null) { 9 | 10 | @Override 11 | public void connect() throws IOException { 12 | // TODO Auto-generated method stub 13 | System.out.println(""); 14 | } 15 | 16 | @Override 17 | public boolean usingProxy() { 18 | // TODO Auto-generated method stub 19 | return false; 20 | } 21 | 22 | @Override 23 | public void disconnect() { 24 | // TODO Auto-generated method stub 25 | 26 | } 27 | }; 28 | httpURLConnection.connect(); 29 | httpURLConnection.setDoOutput(true); 30 | httpURLConnection.setAllowUserInteraction(false); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /targets/urlconn/URLConnTarget2.java: -------------------------------------------------------------------------------- 1 | package urlconn; 2 | 3 | import java.io.IOException; 4 | import java.net.HttpURLConnection; 5 | 6 | public class URLConnTarget2 { 7 | public static void main(String... args) throws IOException { 8 | HttpURLConnection httpURLConnection = new HttpURLConnection(null) { 9 | 10 | @Override 11 | public void connect() throws IOException { 12 | // TODO Auto-generated method stub 13 | System.out.println(""); 14 | } 15 | 16 | @Override 17 | public boolean usingProxy() { 18 | // TODO Auto-generated method stub 19 | return false; 20 | } 21 | 22 | @Override 23 | public void disconnect() { 24 | // TODO Auto-generated method stub 25 | 26 | } 27 | }; 28 | httpURLConnection.setDoOutput(true); 29 | httpURLConnection.setAllowUserInteraction(false); 30 | 31 | httpURLConnection.connect(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /targets/vector/VectorTarget1.java: -------------------------------------------------------------------------------- 1 | package vector; 2 | 3 | import java.io.IOException; 4 | import java.util.Vector; 5 | 6 | public class VectorTarget1 { 7 | public static void main(String... args) throws IOException { 8 | Vector s = new Vector(); 9 | s.lastElement(); 10 | s.elementAt(0); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /targets/vector/VectorTarget2.java: -------------------------------------------------------------------------------- 1 | package vector; 2 | 3 | import java.io.IOException; 4 | import java.util.Vector; 5 | 6 | public class VectorTarget2 { 7 | public static void main(String... args) throws IOException { 8 | Vector s = new Vector(); 9 | s.add(new Object()); 10 | if (args == null) 11 | s.firstElement(); 12 | else 13 | s.elementAt(0); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /targets/vector/VectorTarget3.java: -------------------------------------------------------------------------------- 1 | package vector; 2 | 3 | import java.io.IOException; 4 | import java.util.Vector; 5 | 6 | public class VectorTarget3 { 7 | public static void main(String... args) throws IOException { 8 | Vector s = new Vector(); 9 | if (args == null) 10 | s.lastElement(); 11 | else 12 | s.elementAt(0); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /targets/vector/VectorTarget4.java: -------------------------------------------------------------------------------- 1 | package vector; 2 | 3 | import java.util.Vector; 4 | 5 | public class VectorTarget4 { 6 | public static void main(String[] args) { 7 | try { 8 | Vector v = new Vector(); 9 | v.removeAllElements(); 10 | v.firstElement(); 11 | } catch (Exception e) { 12 | e.printStackTrace(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /targetsBin/file/File.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/File.class -------------------------------------------------------------------------------- /targetsBin/file/ObjectWithField.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/ObjectWithField.class -------------------------------------------------------------------------------- /targetsBin/file/SummaryTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/SummaryTarget1.class -------------------------------------------------------------------------------- /targetsBin/file/Target1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target1.class -------------------------------------------------------------------------------- /targetsBin/file/Target10.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target10.class -------------------------------------------------------------------------------- /targetsBin/file/Target11$Flow.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target11$Flow.class -------------------------------------------------------------------------------- /targetsBin/file/Target11$ImplFlow1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target11$ImplFlow1.class -------------------------------------------------------------------------------- /targetsBin/file/Target11$ImplFlow2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target11$ImplFlow2.class -------------------------------------------------------------------------------- /targetsBin/file/Target11.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target11.class -------------------------------------------------------------------------------- /targetsBin/file/Target12.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target12.class -------------------------------------------------------------------------------- /targetsBin/file/Target13.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target13.class -------------------------------------------------------------------------------- /targetsBin/file/Target14.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target14.class -------------------------------------------------------------------------------- /targetsBin/file/Target15.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target15.class -------------------------------------------------------------------------------- /targetsBin/file/Target16.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target16.class -------------------------------------------------------------------------------- /targetsBin/file/Target17.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target17.class -------------------------------------------------------------------------------- /targetsBin/file/Target18.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target18.class -------------------------------------------------------------------------------- /targetsBin/file/Target19.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target19.class -------------------------------------------------------------------------------- /targetsBin/file/Target2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target2.class -------------------------------------------------------------------------------- /targetsBin/file/Target20.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target20.class -------------------------------------------------------------------------------- /targetsBin/file/Target21.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target21.class -------------------------------------------------------------------------------- /targetsBin/file/Target22.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target22.class -------------------------------------------------------------------------------- /targetsBin/file/Target23.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target23.class -------------------------------------------------------------------------------- /targetsBin/file/Target24.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target24.class -------------------------------------------------------------------------------- /targetsBin/file/Target25.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target25.class -------------------------------------------------------------------------------- /targetsBin/file/Target26.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target26.class -------------------------------------------------------------------------------- /targetsBin/file/Target27.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target27.class -------------------------------------------------------------------------------- /targetsBin/file/Target28.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target28.class -------------------------------------------------------------------------------- /targetsBin/file/Target29.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target29.class -------------------------------------------------------------------------------- /targetsBin/file/Target3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target3.class -------------------------------------------------------------------------------- /targetsBin/file/Target30.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target30.class -------------------------------------------------------------------------------- /targetsBin/file/Target4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target4.class -------------------------------------------------------------------------------- /targetsBin/file/Target5.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target5.class -------------------------------------------------------------------------------- /targetsBin/file/Target6.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target6.class -------------------------------------------------------------------------------- /targetsBin/file/Target7.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target7.class -------------------------------------------------------------------------------- /targetsBin/file/Target8.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target8.class -------------------------------------------------------------------------------- /targetsBin/file/Target9.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/file/Target9.class -------------------------------------------------------------------------------- /targetsBin/inputstream/InputStreamTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/inputstream/InputStreamTarget1.class -------------------------------------------------------------------------------- /targetsBin/inputstream/InputStreamTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/inputstream/InputStreamTarget2.class -------------------------------------------------------------------------------- /targetsBin/inputstream/InputStreamTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/inputstream/InputStreamTarget3.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget1.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget2.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget3.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget4.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget5.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget5.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget6.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget6.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget7.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget7.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget8.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget8.class -------------------------------------------------------------------------------- /targetsBin/iterator/IteratorTarget9.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/IteratorTarget9.class -------------------------------------------------------------------------------- /targetsBin/iterator/MyIterator.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/MyIterator.class -------------------------------------------------------------------------------- /targetsBin/iterator/MyLinkedList.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/iterator/MyLinkedList.class -------------------------------------------------------------------------------- /targetsBin/keystore/KeyStoreTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/keystore/KeyStoreTarget1.class -------------------------------------------------------------------------------- /targetsBin/keystore/KeyStoreTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/keystore/KeyStoreTarget2.class -------------------------------------------------------------------------------- /targetsBin/keystore/KeyStoreTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/keystore/KeyStoreTarget3.class -------------------------------------------------------------------------------- /targetsBin/printstream/PrintStreamTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/printstream/PrintStreamTarget1.class -------------------------------------------------------------------------------- /targetsBin/printwriter/PrintWriterTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/printwriter/PrintWriterTarget1.class -------------------------------------------------------------------------------- /targetsBin/socket/SocketTarget1$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/socket/SocketTarget1$1.class -------------------------------------------------------------------------------- /targetsBin/socket/SocketTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/socket/SocketTarget1.class -------------------------------------------------------------------------------- /targetsBin/socket/SocketTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/socket/SocketTarget2.class -------------------------------------------------------------------------------- /targetsBin/socket/SocketTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/socket/SocketTarget3.class -------------------------------------------------------------------------------- /targetsBin/socket/SocketTarget4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/socket/SocketTarget4.class -------------------------------------------------------------------------------- /targetsBin/stack/StackTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/stack/StackTarget1.class -------------------------------------------------------------------------------- /targetsBin/stack/StackTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/stack/StackTarget2.class -------------------------------------------------------------------------------- /targetsBin/stack/StackTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/stack/StackTarget3.class -------------------------------------------------------------------------------- /targetsBin/stack/StackTarget4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/stack/StackTarget4.class -------------------------------------------------------------------------------- /targetsBin/urlconn/URLConnTarget1$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/urlconn/URLConnTarget1$1.class -------------------------------------------------------------------------------- /targetsBin/urlconn/URLConnTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/urlconn/URLConnTarget1.class -------------------------------------------------------------------------------- /targetsBin/urlconn/URLConnTarget2$1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/urlconn/URLConnTarget2$1.class -------------------------------------------------------------------------------- /targetsBin/urlconn/URLConnTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/urlconn/URLConnTarget2.class -------------------------------------------------------------------------------- /targetsBin/vector/VectorTarget1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/vector/VectorTarget1.class -------------------------------------------------------------------------------- /targetsBin/vector/VectorTarget2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/vector/VectorTarget2.class -------------------------------------------------------------------------------- /targetsBin/vector/VectorTarget3.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/vector/VectorTarget3.class -------------------------------------------------------------------------------- /targetsBin/vector/VectorTarget4.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/secure-software-engineering/ideal/bb64f74c929f5bb301b6662e1324846cd09bbfa2/targetsBin/vector/VectorTarget4.class -------------------------------------------------------------------------------- /tests/typestate/tests/FileMustBeClosedTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import typestate.TypestateDomainValue; 7 | import typestate.impl.fileanalysis.FileMustBeClosedAnalysis; 8 | import typestate.tests.base.TypestateTestingFramework; 9 | 10 | public class FileMustBeClosedTests extends TypestateTestingFramework { 11 | 12 | @Test 13 | public void test1() { 14 | expectNErrors("file.Target1", 0); 15 | } 16 | 17 | @Test 18 | public void test2a() { 19 | expectNErrors("file.Target2", 0); 20 | } 21 | 22 | @Test 23 | public void test2b() { 24 | expectNFacts("file.Target2", 3); 25 | } 26 | 27 | 28 | @Test 29 | public void test3a() { 30 | expectNFacts("file.Target3", 3); 31 | } 32 | 33 | @Test 34 | public void test3b() { 35 | expectNErrors("file.Target3", 0); 36 | } 37 | 38 | @Test 39 | public void test4a() { 40 | expectNErrors("file.Target4", 3); 41 | } 42 | 43 | @Test 44 | public void test5() { 45 | expectNErrors("file.Target5", 0); 46 | } 47 | 48 | @Test 49 | public void test6() { 50 | expectNErrors("file.Target6", 4); 51 | } 52 | 53 | @Test 54 | public void test7() { 55 | expectNErrors("file.Target7", 3); 56 | } 57 | 58 | @Test 59 | public void test8() { 60 | expectNErrors("file.Target8", 6); 61 | } 62 | 63 | @Test 64 | public void summaryTest() { 65 | expectNErrors("file.SummaryTarget1", 0); 66 | } 67 | 68 | @Test 69 | public void test9() { 70 | expectNErrors("file.Target9", 0); 71 | } 72 | 73 | @Test 74 | public void test12() { 75 | expectNErrors("file.Target12", 2); 76 | } 77 | 78 | @Test 79 | public void test13() { 80 | expectNErrors("file.Target13", 0); 81 | } 82 | 83 | @Test 84 | public void test14() { 85 | expectNErrors("file.Target14", 0); 86 | } 87 | 88 | @Test 89 | public void test15() { 90 | expectNErrors("file.Target15", 0); 91 | } 92 | 93 | @Test 94 | public void test16() { 95 | expectNErrors("file.Target16", 0); 96 | } 97 | @Test 98 | public void test28() { 99 | expectNErrors("file.Target28", 0); 100 | } 101 | @Test 102 | public void test29() { 103 | expectNErrors("file.Target29", 5); 104 | } 105 | @Test 106 | public void test17() { 107 | expectNErrors("file.Target17", 0); 108 | } 109 | 110 | @Test 111 | public void test18() { 112 | expectNErrors("file.Target18", 5); 113 | } 114 | 115 | @Test 116 | public void test19() { 117 | expectAtLeastOneError("file.Target19"); 118 | } 119 | 120 | @Test 121 | public void test20() { 122 | expectNErrors("file.Target20", 5); 123 | } 124 | 125 | @Test 126 | public void test22() { 127 | expectNErrors("file.Target22", 0); 128 | } 129 | 130 | @Test 131 | public void test23() { 132 | expectNErrors("file.Target23", 4); 133 | } 134 | 135 | @Test 136 | public void test24() { 137 | expectNErrors("file.Target24", 5); 138 | } 139 | 140 | @Test 141 | public void test25() { 142 | expectNErrors("file.Target25", 3); 143 | } 144 | @Test 145 | public void test26() { 146 | expectNErrors("file.Target26", 2); 147 | } 148 | 149 | @Test 150 | public void test27() { 151 | expectNErrors("file.Target27", 2); 152 | } 153 | @Test 154 | public void test11() { 155 | expectNErrors("file.Target11", 2); 156 | } 157 | 158 | @Test 159 | public void test10() { 160 | expectNErrors("file.Target10", 2); 161 | } 162 | @Test 163 | public void test30() { 164 | expectNErrors("file.Target30", 0); 165 | } 166 | @Override 167 | protected Analysis createAnalysis() { 168 | return new FileMustBeClosedAnalysis(); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /tests/typestate/tests/InputStreamTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.inputstream.InputStreamAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class InputStreamTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("inputstream.InputStreamTarget1", 2); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectAtLeastOneError("inputstream.InputStreamTarget2"); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectNErrors("inputstream.InputStreamTarget3", 0); 26 | } 27 | 28 | @Override 29 | protected Analysis createAnalysis() { 30 | return new InputStreamAnalysis(new InfoflowCFG()); 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /tests/typestate/tests/IteratorTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.iteratoranalysis.HasNextAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class IteratorTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("iterator.IteratorTarget1", 1); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectNErrors("iterator.IteratorTarget2", 0); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectNErrors("iterator.IteratorTarget3", 1); 26 | } 27 | 28 | @Test 29 | public void test4() { 30 | expectNErrors("iterator.IteratorTarget4", 0); 31 | } 32 | 33 | 34 | @Test 35 | public void test5() { 36 | expectNErrors("iterator.IteratorTarget5", 0); 37 | } 38 | 39 | 40 | @Test 41 | public void test6() { 42 | expectNErrors("iterator.IteratorTarget6", 0); 43 | } 44 | 45 | @Test 46 | public void test7() { 47 | expectNErrors("iterator.IteratorTarget7", 0); 48 | } 49 | 50 | @Test 51 | public void test8() { 52 | expectNErrors("iterator.IteratorTarget8", 0); 53 | } 54 | 55 | @Test 56 | public void test9() { 57 | expectNErrors("iterator.IteratorTarget9", 1); 58 | } 59 | @Override 60 | protected Analysis createAnalysis() { 61 | return new HasNextAnalysis(new InfoflowCFG()); 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /tests/typestate/tests/KeystoreTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.keystore.KeyStoreAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class KeystoreTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("keystore.KeyStoreTarget1", 0); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectNErrors("keystore.KeyStoreTarget2", 1); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectNErrors("keystore.KeyStoreTarget3", 0); 26 | } 27 | 28 | 29 | @Override 30 | protected Analysis createAnalysis() { 31 | return new KeyStoreAnalysis(new InfoflowCFG()); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /tests/typestate/tests/PrintStreamTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.printstream.PrintStreamAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class PrintStreamTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectAtLeastOneError("printstream.PrintStreamTarget1"); 16 | } 17 | 18 | @Override 19 | protected Analysis createAnalysis() { 20 | return new PrintStreamAnalysis(new InfoflowCFG()); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /tests/typestate/tests/PrintWriterTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.printwriter.PrintWriterAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class PrintWriterTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectAtLeastOneError("printwriter.PrintWriterTarget1"); 16 | } 17 | 18 | @Override 19 | protected Analysis createAnalysis() { 20 | return new PrintWriterAnalysis(new InfoflowCFG()); 21 | } 22 | 23 | } -------------------------------------------------------------------------------- /tests/typestate/tests/SocketTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.socket.SocketAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class SocketTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectAtLeastOneError("socket.SocketTarget1"); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectAtLeastOneError("socket.SocketTarget2"); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectAtLeastOneError("socket.SocketTarget3"); 26 | } 27 | 28 | @Test 29 | public void test4() { 30 | expectNErrors("socket.SocketTarget4", 0); 31 | } 32 | 33 | @Override 34 | protected Analysis createAnalysis() { 35 | return new SocketAnalysis(new InfoflowCFG()); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/typestate/tests/StackTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.vector.VectorAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class StackTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("stack.StackTarget1", 3); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectNErrors("stack.StackTarget2", 0); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectNErrors("stack.StackTarget3", 2); 26 | } 27 | 28 | @Test 29 | public void test4() { 30 | expectNErrors("stack.StackTarget4", 2); 31 | } 32 | @Override 33 | protected Analysis createAnalysis() { 34 | return new VectorAnalysis(new InfoflowCFG()); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /tests/typestate/tests/URLConnTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.urlconn.URLConnAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class URLConnTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("urlconn.URLConnTarget1", 2); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectNErrors("urlconn.URLConnTarget2", 0); 21 | } 22 | 23 | @Override 24 | protected Analysis createAnalysis() { 25 | return new URLConnAnalysis(new InfoflowCFG()); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /tests/typestate/tests/VectorTests.java: -------------------------------------------------------------------------------- 1 | package typestate.tests; 2 | 3 | import org.junit.Test; 4 | 5 | import ideal.Analysis; 6 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 7 | import typestate.TypestateDomainValue; 8 | import typestate.impl.vector.VectorAnalysis; 9 | import typestate.tests.base.TypestateTestingFramework; 10 | 11 | public class VectorTests extends TypestateTestingFramework { 12 | 13 | @Test 14 | public void test1() { 15 | expectNErrors("vector.VectorTarget1", 2); 16 | } 17 | 18 | @Test 19 | public void test2() { 20 | expectNErrors("vector.VectorTarget2", 0); 21 | } 22 | 23 | @Test 24 | public void test3() { 25 | expectNErrors("vector.VectorTarget3", 2); 26 | } 27 | 28 | @Test 29 | public void test4() { 30 | expectNErrors("vector.VectorTarget4", 2); 31 | } 32 | @Override 33 | protected Analysis createAnalysis() { 34 | return new VectorAnalysis(new InfoflowCFG()); 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /tests/typestate/tests/base/TestingFramework.java: -------------------------------------------------------------------------------- 1 | package typestate.tests.base; 2 | import java.util.LinkedList; 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import ideal.Analysis; 7 | import soot.G; 8 | import soot.PackManager; 9 | import soot.Scene; 10 | import soot.SceneTransformer; 11 | import soot.SootClass; 12 | import soot.SootMethod; 13 | import soot.Transform; 14 | import soot.options.Options; 15 | 16 | public abstract class TestingFramework { 17 | 18 | private Analysis analysis; 19 | protected long analysisTime; 20 | 21 | @SuppressWarnings("static-access") 22 | protected void initializeSoot(String targetClass, String sootCp) { 23 | G.v().reset(); 24 | Options.v().set_whole_program(true); 25 | Options.v().setPhaseOption("jb", "use-original-names:true"); 26 | Options.v().setPhaseOption("cg.spark", "on"); 27 | Options.v().set_prepend_classpath(true); 28 | Options.v().setPhaseOption("cg", "trim-clinit:false"); 29 | Options.v().set_no_bodies_for_excluded(true); 30 | Options.v().set_allow_phantom_refs(true); 31 | 32 | List includeList = new LinkedList(); 33 | includeList.add("java.lang.*"); 34 | includeList.add("java.util.*"); 35 | includeList.add("java.io.*"); 36 | includeList.add("sun.misc.*"); 37 | includeList.add("java.net.*"); 38 | includeList.add("javax.servlet.*"); 39 | includeList.add("javax.crypto.*"); 40 | includeList.add("java.security.*"); 41 | 42 | includeList.add("android.*"); 43 | includeList.add("org.apache.http.*"); 44 | Options.v().set_include(includeList); 45 | Options.v().set_soot_classpath(sootCp); 46 | Options.v().set_main_class(targetClass); 47 | Scene.v().addBasicClass(targetClass, SootClass.BODIES); 48 | Scene.v().loadNecessaryClasses(); 49 | SootClass c = Scene.v().forceResolve(targetClass, SootClass.BODIES); 50 | if (c != null) { 51 | c.setApplicationClass(); 52 | } 53 | SootMethod methodByName = c.getMethodByName("main"); 54 | List ePoints = new LinkedList<>(); 55 | ePoints.add(methodByName); 56 | Scene.v().setEntryPoints(ePoints); 57 | } 58 | 59 | public void run(String targetClass, String classPath) { 60 | initializeSoot(targetClass, classPath); 61 | Transform transform = new Transform("wjtp.ifds", new SceneTransformer() { 62 | protected void internalTransform(String phaseName, 63 | @SuppressWarnings("rawtypes") Map options) { 64 | System.out.println(Scene.v().getMainMethod().getActiveBody()); 65 | System.out.println(Scene.v().getReachableMethods().size()); 66 | TestingFramework.this.getAnalysis().run(); 67 | } 68 | }); 69 | PackManager.v().getPack("wjtp").add(transform); 70 | PackManager.v().getPack("cg").apply(); 71 | PackManager.v().getPack("wjtp").apply(); 72 | } 73 | 74 | protected abstract Analysis createAnalysis(); 75 | 76 | protected Analysis getAnalysis() { 77 | if (analysis == null) 78 | analysis = createAnalysis(); 79 | return analysis; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /tests/typestate/tests/base/TypestateTestingFramework.java: -------------------------------------------------------------------------------- 1 | package typestate.tests.base; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.util.Set; 7 | 8 | import com.google.common.collect.Table.Cell; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import soot.SootMethod; 12 | import typestate.ResultCollection; 13 | import typestate.TypestateAnalysis; 14 | import typestate.TypestateDomainValue; 15 | 16 | public abstract class TypestateTestingFramework extends TestingFramework { 17 | 18 | public void expectNErrors(String targetClass, int n) { 19 | String userdir = System.getProperty("user.dir"); 20 | String sootCp = userdir + "/targetsBin"; 21 | expectNErrors(targetClass, sootCp, n); 22 | } 23 | 24 | public void expectNErrors(String targetClass, String sootCp, int n) { 25 | run(targetClass, sootCp); 26 | Set> errors = ((TypestateAnalysis) getAnalysis()).getErrors(); 27 | assertEquals(errors.toString(), n, errors.size()); 28 | } 29 | public void expectNFacts(String targetClass, int n) { 30 | String userdir = System.getProperty("user.dir"); 31 | String sootCp = userdir + "/targetsBin"; 32 | run(targetClass, sootCp); 33 | ResultCollection pathEdges = ((TypestateAnalysis) getAnalysis()).getPathEdgesAtEndOfMethods(); 34 | assertEquals(pathEdges.toString(), n, pathEdges.size()); 35 | } 36 | 37 | public void expectAtLeastOneError(String targetClass) { 38 | String userdir = System.getProperty("user.dir"); 39 | String sootCp = userdir + "/targetsBin"; 40 | run(targetClass, sootCp); 41 | Set> errors = ((TypestateAnalysis) getAnalysis()).getErrors(); 42 | assertTrue("Expected at least one finding.", errors.size() > 0); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /typestate/typestate/IdentityTransition.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import typestate.finiteautomata.State; 4 | import typestate.finiteautomata.Transition; 5 | 6 | public class IdentityTransition extends Transition { 7 | public static final State ID = new State() { 8 | @Override 9 | public boolean isErrorState() { 10 | return false; 11 | } 12 | 13 | @Override 14 | public boolean isInitialState() { 15 | return false; 16 | } 17 | public String toString(){ 18 | return "*"; 19 | } 20 | }; 21 | 22 | public IdentityTransition() { 23 | super(ID, ID); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /typestate/typestate/Join.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | public interface Join { 4 | public T join(T t1, T t2); 5 | } -------------------------------------------------------------------------------- /typestate/typestate/ResultCollection.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Iterator; 4 | import java.util.Set; 5 | 6 | import com.google.common.collect.HashBasedTable; 7 | import com.google.common.collect.Table; 8 | import com.google.common.collect.Table.Cell; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import ideal.flowfunctions.WrappedAccessGraph; 12 | import soot.SootMethod; 13 | import typestate.finiteautomata.Transition; 14 | 15 | public class ResultCollection implements Iterable> { 16 | private Table resultTable = HashBasedTable.create(); 17 | private Join join; 18 | 19 | public ResultCollection(Join join){ 20 | this.join = join; 21 | } 22 | public void put(SootMethod m, AccessGraph g, V v) { 23 | if (v == null) 24 | throw new RuntimeException("Value v must not be null"); 25 | V v2 = resultTable.get(m, g); 26 | if (v2 != null) 27 | v = join.join(v,v2); 28 | resultTable.put(m, g, v); 29 | } 30 | 31 | 32 | public void clear() { 33 | resultTable.clear(); 34 | } 35 | 36 | @Override 37 | public Iterator> iterator() { 38 | return resultTable.cellSet().iterator(); 39 | } 40 | 41 | public int size() { 42 | return resultTable.size(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /typestate/typestate/TransitionFunction.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Collections; 4 | import java.util.HashSet; 5 | import java.util.Set; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import heros.EdgeFunction; 11 | import heros.edgefunc.AllBottom; 12 | import heros.edgefunc.AllTop; 13 | import heros.edgefunc.EdgeIdentity; 14 | import typestate.finiteautomata.Transition; 15 | 16 | public class TransitionFunction 17 | implements EdgeFunction { 18 | 19 | public final TypestateDomainValue value; 20 | 21 | private static Logger logger = LoggerFactory.getLogger(TransitionFunction.class); 22 | 23 | public TransitionFunction(Set trans) { 24 | this.value = new TypestateDomainValue(trans); 25 | } 26 | 27 | public TransitionFunction(Transition trans) { 28 | this.value = new TypestateDomainValue(new HashSet<>(Collections.singleton(trans))); 29 | } 30 | @Override 31 | public TypestateDomainValue computeTarget(TypestateDomainValue source) { 32 | return value; 33 | } 34 | 35 | @Override 36 | public EdgeFunction composeWith( 37 | EdgeFunction secondFunction) { 38 | if (secondFunction instanceof AllTop) 39 | return secondFunction; 40 | 41 | if (secondFunction instanceof AllBottom) 42 | return this; 43 | 44 | if (secondFunction instanceof EdgeIdentity){ 45 | return this; 46 | } 47 | if (!(secondFunction instanceof TransitionFunction)) 48 | throw new RuntimeException("Wrong type, is of type: " + secondFunction); 49 | TransitionFunction func = (TransitionFunction) secondFunction; 50 | TypestateDomainValue otherTransitions = func.value; 51 | Set res = new HashSet<>(); 52 | for (Transition first : value.getTransitions()) { 53 | for (Transition second : otherTransitions.getTransitions()) { 54 | if (second.from().equals(IdentityTransition.ID) 55 | && second.to().equals(IdentityTransition.ID)) { 56 | res.add(first); 57 | } else if (first.to().equals(second.from()) || first.to().equals(IdentityTransition.ID) 58 | || second.from().equals(IdentityTransition.ID)) 59 | res.add(new Transition(first.from(), second.to())); 60 | // else 61 | // res.add(first); 62 | } 63 | } 64 | logger.debug("ComposeWith: {} with {} -> {}", this, secondFunction, 65 | new TransitionFunction(res)); 66 | return new TransitionFunction(res); 67 | } 68 | 69 | @Override 70 | public EdgeFunction joinWith( 71 | EdgeFunction otherFunction) { 72 | if (otherFunction instanceof AllTop) 73 | return this; 74 | if (otherFunction instanceof AllBottom) 75 | return otherFunction; 76 | if (otherFunction instanceof EdgeIdentity) { 77 | Set transitions = new HashSet<>(); 78 | transitions.add(new IdentityTransition()); 79 | transitions.addAll(value.getTransitions()); 80 | return new TransitionFunction(transitions); 81 | } 82 | TransitionFunction func = (TransitionFunction) otherFunction; 83 | Set transitions = func.value.getTransitions(); 84 | transitions.addAll(value.getTransitions()); 85 | return new TransitionFunction(transitions); 86 | } 87 | 88 | @Override 89 | public boolean equalTo(EdgeFunction other) { 90 | if(!(other instanceof TransitionFunction)) 91 | return false; 92 | TransitionFunction func = (TransitionFunction) other; 93 | return func.value.equals(value); 94 | } 95 | 96 | public String toString() { 97 | return "{Func:" + value.toString() + "}"; 98 | }; 99 | } 100 | -------------------------------------------------------------------------------- /typestate/typestate/TypestateAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Set; 4 | 5 | import com.google.common.collect.Table.Cell; 6 | 7 | import boomerang.accessgraph.AccessGraph; 8 | import ideal.Analysis; 9 | import ideal.debug.IDebugger; 10 | import soot.SootMethod; 11 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 12 | 13 | public class TypestateAnalysis extends Analysis { 14 | 15 | public TypestateAnalysis(TypestateChangeFunction func, InfoflowCFG cfg) { 16 | super(new TypestateAnalysisProblem(func), cfg); 17 | } 18 | 19 | public TypestateAnalysis(TypestateChangeFunction func, InfoflowCFG cfg, IDebugger debugger) { 20 | super(new TypestateAnalysisProblem(func), cfg, debugger); 21 | } 22 | 23 | public Set> getErrors() { 24 | return ((TypestateAnalysisProblem) problem).getErrors(); 25 | } 26 | 27 | public ResultCollection getPathEdgesAtEndOfMethods() { 28 | return ((TypestateAnalysisProblem) problem).getPathEdgesAtEndOfMethods(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /typestate/typestate/TypestateAnalysisProblem.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import java.util.Set; 8 | 9 | import com.google.common.collect.Table.Cell; 10 | 11 | import boomerang.BoomerangContext; 12 | import boomerang.accessgraph.AccessGraph; 13 | import heros.EdgeFunction; 14 | import heros.solver.Pair; 15 | import heros.solver.PathEdge; 16 | import ideal.AnalysisProblem; 17 | import ideal.AnalysisSolver; 18 | import ideal.InternalAnalysisProblem; 19 | import ideal.edgefunction.AnalysisEdgeFunctions; 20 | import ideal.flowfunctions.WrappedAccessGraph; 21 | import soot.MethodOrMethodContext; 22 | import soot.Scene; 23 | import soot.SootMethod; 24 | import soot.Unit; 25 | import soot.jimple.toolkits.callgraph.ReachableMethods; 26 | import soot.util.queue.QueueReader; 27 | import typestate.finiteautomata.Transition; 28 | 29 | public class TypestateAnalysisProblem implements AnalysisProblem { 30 | 31 | private TypestateChangeFunction func; 32 | private Set> errorPathEdges = new HashSet<>(); 33 | private ResultCollection endingPathsOfPropagation = new ResultCollection<>(new Join(){ 34 | 35 | @Override 36 | public TypestateDomainValue join(TypestateDomainValue t1, TypestateDomainValue t2) { 37 | Set transitions = t1.getTransitions(); 38 | Set transitions2 = t2.getTransitions(); 39 | transitions.addAll(transitions2); 40 | return new TypestateDomainValue(transitions); 41 | }}); 42 | 43 | public TypestateAnalysisProblem(TypestateChangeFunction func) { 44 | this.func = func; 45 | } 46 | 47 | @Override 48 | public AnalysisEdgeFunctions edgeFunctions() { 49 | return new TypestateEdgeFunctions(func); 50 | } 51 | 52 | @Override 53 | public void onAnalysisFinished(PathEdge seed, 54 | AnalysisSolver solver) { 55 | ReachableMethods rm = Scene.v().getReachableMethods(); 56 | QueueReader listener = rm.listener(); 57 | while (listener.hasNext()) { 58 | MethodOrMethodContext next = listener.next(); 59 | SootMethod method = next.method(); 60 | if (!method.hasActiveBody()) 61 | continue; 62 | 63 | 64 | Collection endPointsOf = solver.icfg().getEndPointsOf(method); 65 | 66 | for (Unit eP : endPointsOf) { 67 | Set localsAtEndPoint = new HashSet<>(); 68 | for (Cell> cell : solver 69 | .getPathEdgesAt(eP)) { 70 | if (!cell.getRowKey().equals(InternalAnalysisProblem.ZERO)) { 71 | continue; 72 | } 73 | localsAtEndPoint.add(cell.getColumnKey()); 74 | } 75 | boolean escapes = false; 76 | for (WrappedAccessGraph ag : localsAtEndPoint) { 77 | if (BoomerangContext.isParameterOrThisValue(method, ag.getBase())) { 78 | escapes = true; 79 | } 80 | } 81 | if (!escapes) { 82 | Map resultAt = solver.resultsAt(eP); 83 | for (Entry fact : resultAt.entrySet()) { 84 | if (localsAtEndPoint.contains(fact.getKey())) { 85 | if (!fact.getValue().equals(solver.bottom())) 86 | endingPathsOfPropagation 87 | .put(method, fact.getKey().getDelegate(), fact.getValue()); 88 | } 89 | } 90 | } 91 | 92 | } 93 | } 94 | for (Cell res : endingPathsOfPropagation) { 95 | if (res.getValue().endsInErrorState()) { 96 | errorPathEdges.add(res); 97 | } 98 | } 99 | } 100 | 101 | @Override 102 | public Collection>> generate(Unit stmt, 103 | Collection optional) { 104 | return func.generate(stmt, optional); 105 | } 106 | 107 | public Set> getErrors() { 108 | return errorPathEdges; 109 | } 110 | 111 | public ResultCollection getPathEdgesAtEndOfMethods() { 112 | return endingPathsOfPropagation; 113 | } 114 | 115 | @Override 116 | public boolean isInErrorState() { 117 | return !errorPathEdges.isEmpty(); 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /typestate/typestate/TypestateChangeFunction.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Collection; 4 | import java.util.Set; 5 | 6 | import boomerang.accessgraph.AccessGraph; 7 | import heros.EdgeFunction; 8 | import heros.solver.Pair; 9 | import soot.SootMethod; 10 | import soot.Unit; 11 | import typestate.finiteautomata.Transition; 12 | 13 | public interface TypestateChangeFunction { 14 | Set getReturnTransitionsFor(AccessGraph callerD1, Unit callSite, 15 | SootMethod calleeMethod, Unit exitStmt, AccessGraph exitNode, Unit returnSite, 16 | AccessGraph retNode); 17 | 18 | Collection>> generate(Unit stmt, 19 | Collection optional); 20 | 21 | Set getCallTransitionsFor(AccessGraph callerD1, Unit callSite, 22 | SootMethod calleeMethod, AccessGraph srcNode, AccessGraph destNode); 23 | 24 | boolean seedInApplicationClass(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /typestate/typestate/TypestateDomainValue.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | import typestate.finiteautomata.Transition; 7 | 8 | public class TypestateDomainValue { 9 | 10 | private final Set transitions; 11 | 12 | public TypestateDomainValue(Set trans) { 13 | this.transitions = trans; 14 | } 15 | 16 | public TypestateDomainValue() { 17 | this.transitions = new HashSet<>(); 18 | } 19 | 20 | @Override 21 | public int hashCode() { 22 | final int prime = 31; 23 | int result = 1; 24 | result = prime * result + ((transitions == null) ? 0 : transitions.hashCode()); 25 | return result; 26 | } 27 | 28 | @Override 29 | public boolean equals(Object obj) { 30 | if (this == obj) 31 | return true; 32 | if (obj == null) 33 | return false; 34 | if (getClass() != obj.getClass()) 35 | return false; 36 | TypestateDomainValue other = (TypestateDomainValue) obj; 37 | if (transitions == null) { 38 | if (other.transitions != null) 39 | return false; 40 | } else if (!transitions.equals(other.transitions)) 41 | return false; 42 | return true; 43 | } 44 | 45 | public Set getTransitions() { 46 | return new HashSet<>(transitions); 47 | } 48 | 49 | public boolean endsInErrorState() { 50 | for (Transition t : transitions) { 51 | if (t.to().isErrorState()) 52 | return true; 53 | } 54 | return false; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return transitions.toString(); 60 | } 61 | 62 | static final TypestateDomainValue BOTTOM = new TypestateDomainValue() { 63 | public int hashCode() { 64 | return 101001011; 65 | }; 66 | 67 | public boolean equals(Object obj) { 68 | return obj == BOTTOM; 69 | }; 70 | 71 | public String toString() { 72 | return "BOTTOM"; 73 | }; 74 | }; 75 | static final TypestateDomainValue TOP = new TypestateDomainValue() { 76 | public int hashCode() { 77 | return 101001010; 78 | }; 79 | 80 | public boolean equals(Object obj) { 81 | return obj == TOP; 82 | }; 83 | 84 | public String toString() { 85 | return "TOP"; 86 | }; 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /typestate/typestate/TypestateEdgeFunctions.java: -------------------------------------------------------------------------------- 1 | package typestate; 2 | 3 | import java.util.Set; 4 | 5 | import heros.EdgeFunction; 6 | import heros.edgefunc.AllBottom; 7 | import heros.edgefunc.EdgeIdentity; 8 | import ideal.edgefunction.AnalysisEdgeFunctions; 9 | import ideal.flowfunctions.WrappedAccessGraph; 10 | import soot.SootMethod; 11 | import soot.Unit; 12 | import typestate.finiteautomata.Transition; 13 | 14 | public class TypestateEdgeFunctions implements AnalysisEdgeFunctions { 15 | 16 | public final static EdgeFunction ALL_BOTTOM = 17 | new AllBottom(TypestateDomainValue.BOTTOM); 18 | private TypestateChangeFunction func; 19 | 20 | public TypestateEdgeFunctions(TypestateChangeFunction func) { 21 | this.func = func; 22 | } 23 | 24 | @Override 25 | public EdgeFunction getNormalEdgeFunction(WrappedAccessGraph d1, Unit curr, 26 | WrappedAccessGraph currNode, Unit succ, WrappedAccessGraph succNode) { 27 | return EdgeIdentity.v(); 28 | } 29 | 30 | @Override 31 | public EdgeFunction getCallEdgeFunction(WrappedAccessGraph callerD1, Unit callSite, 32 | WrappedAccessGraph srcNode, SootMethod calleeMethod, WrappedAccessGraph destNode) { 33 | Set trans = 34 | func.getCallTransitionsFor(callerD1.getDelegate(), callSite, calleeMethod, srcNode.getDelegate(), destNode.getDelegate()); 35 | if (trans.isEmpty()) 36 | return EdgeIdentity.v(); 37 | return new TransitionFunction(trans); 38 | } 39 | 40 | @Override 41 | public EdgeFunction getReturnEdgeFunction(WrappedAccessGraph callerD1, 42 | Unit callSite, SootMethod calleeMethod, Unit exitStmt, WrappedAccessGraph exitNode, Unit returnSite, 43 | WrappedAccessGraph retNode) { 44 | 45 | Set trans = func.getReturnTransitionsFor(callerD1.getDelegate(), callSite, calleeMethod, 46 | exitStmt, exitNode.getDelegate(), returnSite, retNode.getDelegate()); 47 | if (trans.isEmpty()) 48 | return EdgeIdentity.v(); 49 | return new TransitionFunction(trans); 50 | } 51 | 52 | @Override 53 | public EdgeFunction getCallToReturnEdgeFunction(WrappedAccessGraph d1, 54 | Unit callSite, WrappedAccessGraph callNode, Unit returnSite, WrappedAccessGraph returnSideNode) { 55 | return EdgeIdentity.v(); 56 | } 57 | 58 | @Override 59 | public TypestateDomainValue bottom() { 60 | return TypestateDomainValue.BOTTOM; 61 | } 62 | 63 | @Override 64 | public TypestateDomainValue top() { 65 | return TypestateDomainValue.TOP; 66 | } 67 | 68 | @Override 69 | public TypestateDomainValue join(TypestateDomainValue left, TypestateDomainValue right) { 70 | Set transitions = left.getTransitions(); 71 | transitions.addAll(right.getTransitions()); 72 | return new TypestateDomainValue(transitions); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /typestate/typestate/finiteautomata/MatcherStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.finiteautomata; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.regex.Pattern; 10 | 11 | import boomerang.BoomerangContext; 12 | import boomerang.accessgraph.AccessGraph; 13 | import heros.EdgeFunction; 14 | import heros.solver.Pair; 15 | import soot.Local; 16 | import soot.Scene; 17 | import soot.SootClass; 18 | import soot.SootMethod; 19 | import soot.Unit; 20 | import soot.jimple.AssignStmt; 21 | import soot.jimple.InstanceInvokeExpr; 22 | import soot.jimple.Stmt; 23 | import typestate.TransitionFunction; 24 | import typestate.TypestateChangeFunction; 25 | import typestate.TypestateDomainValue; 26 | import typestate.finiteautomata.MatcherTransition.Parameter; 27 | import typestate.finiteautomata.MatcherTransition.Type; 28 | 29 | public abstract class MatcherStateMachine implements TypestateChangeFunction { 30 | public Set transition = new HashSet<>(); 31 | 32 | public void addTransition(MatcherTransition trans) { 33 | transition.add(trans); 34 | } 35 | 36 | public Set getReturnTransitionsFor(AccessGraph callerD1, Unit callSite, SootMethod calleeMethod, 37 | Unit exitStmt, AccessGraph exitNode, Unit returnSite, AccessGraph retNode) { 38 | return getMatchingTransitions(calleeMethod, exitNode, Type.OnReturn); 39 | } 40 | 41 | public Set getCallTransitionsFor(AccessGraph callerD1, Unit callSite, SootMethod callee, 42 | AccessGraph srcNode, AccessGraph destNode) { 43 | return getMatchingTransitions(callee, destNode, Type.OnCall); 44 | } 45 | 46 | private Set getMatchingTransitions(SootMethod method, AccessGraph node, Type type) { 47 | Set res = new HashSet<>(); 48 | if (node.getFieldCount() == 0) { 49 | for (MatcherTransition trans : transition) { 50 | 51 | if (trans.matches(method) && trans.getType().equals(type)) { 52 | Parameter param = trans.getParam(); 53 | if (param.equals(Parameter.This) && BoomerangContext.isThisValue(method, node.getBase())) 54 | res.add(new Transition(trans.from(), trans.to())); 55 | if (param.equals(Parameter.Param1) 56 | && method.getActiveBody().getParameterLocal(0).equals(node.getBase())) 57 | res.add(new Transition(trans.from(), trans.to())); 58 | if (param.equals(Parameter.Param2) 59 | && method.getActiveBody().getParameterLocal(1).equals(node.getBase())) 60 | res.add(new Transition(trans.from(), trans.to())); 61 | } 62 | } 63 | } 64 | 65 | return res; 66 | } 67 | 68 | protected Set selectMethodByName(Collection classes, String pattern) { 69 | Set res = new HashSet<>(); 70 | for (SootClass c : classes) { 71 | for (SootMethod m : c.getMethods()) { 72 | if (Pattern.matches(pattern, m.getName())) 73 | res.add(m); 74 | } 75 | } 76 | return res; 77 | } 78 | 79 | protected List getSubclassesOf(String className) { 80 | SootClass sootClass = Scene.v().getSootClass(className); 81 | List list = Scene.v().getActiveHierarchy().getSubclassesOfIncluding(sootClass); 82 | List res = new LinkedList<>(); 83 | for (SootClass c : list) { 84 | res.add(c); 85 | } 86 | return res; 87 | } 88 | 89 | protected Collection>> generateAtConstructor(Unit unit, 90 | Collection calledMethod, MatcherTransition initialTrans) { 91 | boolean matches = false; 92 | for (SootMethod method : calledMethod) { 93 | if (initialTrans.matches(method)) { 94 | matches = true; 95 | } 96 | } 97 | if (!matches) 98 | return Collections.emptySet(); 99 | if (unit instanceof Stmt) { 100 | Stmt stmt = (Stmt) unit; 101 | if (stmt.containsInvokeExpr()) 102 | if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { 103 | InstanceInvokeExpr iie = (InstanceInvokeExpr) stmt.getInvokeExpr(); 104 | if (iie.getBase() instanceof Local) { 105 | Local l = (Local) iie.getBase(); 106 | Set>> out = new HashSet<>(); 107 | out.add(new Pair>( 108 | new AccessGraph(l, l.getType()), new TransitionFunction(initialTrans))); 109 | return out; 110 | } 111 | } 112 | } 113 | return Collections.emptySet(); 114 | } 115 | 116 | protected Collection>> generateReturnValueOf(Unit unit, 117 | Collection calledMethod, MatcherTransition initialTrans) { 118 | boolean matches = false; 119 | for (SootMethod method : calledMethod) { 120 | if (initialTrans.matches(method)) { 121 | matches = true; 122 | } 123 | } 124 | if (!matches) 125 | return Collections.emptySet(); 126 | if (!matches) 127 | return Collections.emptySet(); 128 | if (unit instanceof AssignStmt) { 129 | Set>> out = new HashSet<>(); 130 | AssignStmt stmt = (AssignStmt) unit; 131 | out.add(new Pair>( 132 | new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), 133 | new TransitionFunction(initialTrans))); 134 | return out; 135 | } 136 | return Collections.emptySet(); 137 | } 138 | 139 | protected Collection>> generateThisAtAnyCallSitesOf(Unit unit, 140 | Collection calledMethod, Set hasToCall, MatcherTransition initialTrans) { 141 | for (SootMethod callee : calledMethod) { 142 | if (hasToCall.contains(callee)) { 143 | if (unit instanceof Stmt) { 144 | if (((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { 145 | InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); 146 | Local thisLocal = (Local) iie.getBase(); 147 | Set>> out = new HashSet<>(); 148 | out.add(new Pair>( 149 | new AccessGraph(thisLocal, thisLocal.getType()), new TransitionFunction(initialTrans))); 150 | return out; 151 | } 152 | } 153 | 154 | } 155 | } 156 | return Collections.emptySet(); 157 | }} 158 | -------------------------------------------------------------------------------- /typestate/typestate/finiteautomata/MatcherTransition.java: -------------------------------------------------------------------------------- 1 | package typestate.finiteautomata; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | import java.util.regex.Pattern; 6 | 7 | import soot.MethodOrMethodContext; 8 | import soot.Scene; 9 | import soot.SootMethod; 10 | import soot.jimple.toolkits.callgraph.ReachableMethods; 11 | import soot.util.queue.QueueReader; 12 | 13 | public class MatcherTransition extends Transition { 14 | private Set matchingMethods = new HashSet<>(); 15 | private Type type; 16 | private Parameter param; 17 | 18 | public enum Type { 19 | OnCall, OnReturn, None 20 | } 21 | 22 | public enum Parameter { 23 | This, Param1, Param2; 24 | } 25 | 26 | public MatcherTransition(State from, String methodMatcher, Parameter param, State to, Type type) { 27 | super(from, to); 28 | this.type = type; 29 | this.param = param; 30 | ReachableMethods methods = Scene.v().getReachableMethods(); 31 | QueueReader listener = methods.listener(); 32 | while (listener.hasNext()) { 33 | MethodOrMethodContext next = listener.next(); 34 | SootMethod method = next.method(); 35 | if (Pattern.matches(methodMatcher, method.getSignature())) { 36 | matchingMethods.add(method); 37 | } 38 | } 39 | } 40 | 41 | public MatcherTransition(State from, Set matchingMethods, Parameter param, State to, Type type) { 42 | super(from, to); 43 | this.type = type; 44 | this.param = param; 45 | this.matchingMethods = matchingMethods; 46 | } 47 | 48 | public boolean matches(SootMethod method) { 49 | return matchingMethods.contains(method); 50 | } 51 | 52 | public Type getType() { 53 | return type; 54 | } 55 | 56 | 57 | @Override 58 | public int hashCode() { 59 | final int prime = 31; 60 | int result = super.hashCode(); 61 | result = prime * result + ((matchingMethods == null) ? 0 : matchingMethods.hashCode()); 62 | result = prime * result + ((param == null) ? 0 : param.hashCode()); 63 | result = prime * result + ((type == null) ? 0 : type.hashCode()); 64 | return result; 65 | } 66 | 67 | @Override 68 | public boolean equals(Object obj) { 69 | if (this == obj) 70 | return true; 71 | if (!super.equals(obj)) 72 | return false; 73 | if (getClass() != obj.getClass()) 74 | return false; 75 | MatcherTransition other = (MatcherTransition) obj; 76 | if (matchingMethods == null) { 77 | if (other.matchingMethods != null) 78 | return false; 79 | } else if (!matchingMethods.equals(other.matchingMethods)) 80 | return false; 81 | if (param != other.param) 82 | return false; 83 | if (type != other.type) 84 | return false; 85 | return true; 86 | } 87 | 88 | public Parameter getParam() { 89 | return param; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /typestate/typestate/finiteautomata/State.java: -------------------------------------------------------------------------------- 1 | package typestate.finiteautomata; 2 | 3 | public interface State { 4 | public boolean isErrorState(); 5 | 6 | public boolean isInitialState(); 7 | } 8 | -------------------------------------------------------------------------------- /typestate/typestate/finiteautomata/Transition.java: -------------------------------------------------------------------------------- 1 | package typestate.finiteautomata; 2 | 3 | public class Transition { 4 | private final State from; 5 | private final State to; 6 | 7 | public Transition(State from, State to) { 8 | this.from = from; 9 | this.to = to; 10 | } 11 | 12 | public State from() { 13 | return from; 14 | } 15 | 16 | public State to() { 17 | return to; 18 | } 19 | 20 | @Override 21 | public int hashCode() { 22 | final int prime = 31; 23 | int result = 1; 24 | result = prime * result + ((from == null) ? 0 : from.hashCode()); 25 | result = prime * result + ((to == null) ? 0 : to.hashCode()); 26 | return result; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object obj) { 31 | if (this == obj) 32 | return true; 33 | if (obj == null) 34 | return false; 35 | if (getClass() != obj.getClass()) 36 | return false; 37 | Transition other = (Transition) obj; 38 | if (from == null) { 39 | if (other.from != null) 40 | return false; 41 | } else if (!from.equals(other.from)) 42 | return false; 43 | if (to == null) { 44 | if (other.to != null) 45 | return false; 46 | } else if (!to.equals(other.to)) 47 | return false; 48 | return true; 49 | } 50 | 51 | public String toString() { 52 | return "" + from + "->" + to; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /typestate/typestate/impl/fileanalysis/FileMustBeClosedAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.fileanalysis; 2 | import ideal.debug.IDebugger; 3 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 4 | import typestate.TypestateAnalysis; 5 | import typestate.TypestateDomainValue; 6 | 7 | public class FileMustBeClosedAnalysis extends TypestateAnalysis { 8 | public FileMustBeClosedAnalysis() { 9 | super(new FileMustBeClosedStateMachine(), new InfoflowCFG()); 10 | } 11 | public FileMustBeClosedAnalysis(IDebugger debugger) { 12 | super(new FileMustBeClosedStateMachine(), new InfoflowCFG(), debugger); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /typestate/typestate/impl/fileanalysis/FileMustBeClosedStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.fileanalysis; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | import boomerang.accessgraph.AccessGraph; 9 | import heros.EdgeFunction; 10 | import heros.solver.Pair; 11 | import soot.Local; 12 | import soot.SootMethod; 13 | import soot.Unit; 14 | import soot.jimple.InstanceInvokeExpr; 15 | import soot.jimple.Stmt; 16 | import typestate.TransitionFunction; 17 | import typestate.TypestateChangeFunction; 18 | import typestate.TypestateDomainValue; 19 | import typestate.finiteautomata.MatcherStateMachine; 20 | import typestate.finiteautomata.MatcherTransition; 21 | import typestate.finiteautomata.MatcherTransition.Parameter; 22 | import typestate.finiteautomata.MatcherTransition.Type; 23 | import typestate.finiteautomata.State; 24 | import typestate.finiteautomata.Transition; 25 | 26 | public class FileMustBeClosedStateMachine extends MatcherStateMachine 27 | implements TypestateChangeFunction { 28 | private MatcherTransition initialTrans; 29 | 30 | public static enum States implements State { 31 | NONE, INIT, OPENED, CLOSED; 32 | 33 | @Override 34 | public boolean isErrorState() { 35 | return this == OPENED; 36 | } 37 | 38 | @Override 39 | public boolean isInitialState() { 40 | return this == INIT; 41 | } 42 | } 43 | 44 | FileMustBeClosedStateMachine() { 45 | initialTrans = 46 | new MatcherTransition(States.NONE, "\\(\\)>",Parameter.This, States.INIT, 47 | Type.OnCall); 48 | addTransition(initialTrans); 49 | addTransition(new MatcherTransition(States.INIT, ".*open.*",Parameter.This, States.OPENED, Type.OnReturn)); 50 | addTransition(new MatcherTransition(States.OPENED, ".*close.*",Parameter.This, States.CLOSED, Type.OnReturn)); 51 | } 52 | 53 | 54 | 55 | @Override 56 | public Collection>> generate(Unit unit, 57 | Collection calledMethod) { 58 | boolean matches = false; 59 | for (SootMethod method : calledMethod) { 60 | if (initialTrans.matches(method)) { 61 | matches = true; 62 | } 63 | } 64 | if (!matches) 65 | return Collections.emptySet(); 66 | if (unit instanceof Stmt && ((Stmt) unit).getInvokeExpr() instanceof InstanceInvokeExpr) { 67 | InstanceInvokeExpr iie = (InstanceInvokeExpr) ((Stmt) unit).getInvokeExpr(); 68 | Set>> out = new HashSet<>(); 69 | out.add(new Pair>( 70 | new AccessGraph((Local) iie.getBase(), iie.getBase().getType()), 71 | new TransitionFunction(initialTrans))); 72 | return out; 73 | } 74 | return Collections.emptySet(); 75 | } 76 | 77 | 78 | 79 | @Override 80 | public boolean seedInApplicationClass() { 81 | return true; 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /typestate/typestate/impl/inputstream/InputStreamAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.inputstream; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class InputStreamAnalysis extends TypestateAnalysis { 9 | 10 | public InputStreamAnalysis(InfoflowCFG icfg) { 11 | super(new InputStreamStateMachine(icfg), icfg); 12 | } 13 | 14 | 15 | public InputStreamAnalysis(InfoflowCFG icfg, IDebugger debugger) { 16 | super(new InputStreamStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/inputstream/InputStreamStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.inputstream; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.InstanceInvokeExpr; 19 | import soot.jimple.ReturnVoidStmt; 20 | import soot.jimple.Stmt; 21 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 22 | import typestate.TransitionFunction; 23 | import typestate.TypestateChangeFunction; 24 | import typestate.TypestateDomainValue; 25 | import typestate.finiteautomata.MatcherStateMachine; 26 | import typestate.finiteautomata.MatcherTransition; 27 | import typestate.finiteautomata.MatcherTransition.Parameter; 28 | import typestate.finiteautomata.MatcherTransition.Type; 29 | import typestate.finiteautomata.State; 30 | import typestate.finiteautomata.Transition; 31 | 32 | public class InputStreamStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 33 | 34 | private MatcherTransition initialTrans; 35 | private InfoflowCFG icfg; 36 | 37 | public static enum States implements State { 38 | NONE, CLOSED, ERROR; 39 | 40 | @Override 41 | public boolean isErrorState() { 42 | return this == ERROR; 43 | } 44 | 45 | @Override 46 | public boolean isInitialState() { 47 | return this == CLOSED; 48 | } 49 | } 50 | 51 | InputStreamStateMachine(InfoflowCFG icfg) { 52 | this.icfg = icfg; 53 | initialTrans = new MatcherTransition(States.NONE, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition( 56 | new MatcherTransition(States.CLOSED, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.CLOSED, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 58 | addTransition(new MatcherTransition(States.ERROR, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 59 | } 60 | 61 | @Override 62 | public boolean seedInApplicationClass() { 63 | return false; 64 | } 65 | 66 | private Set closeMethods() { 67 | return selectMethodByName(getImplementersOf("java.io.InputStream"), "close"); 68 | } 69 | 70 | private Set readMethods() { 71 | return selectMethodByName(getImplementersOf("java.io.InputStream"), "read"); 72 | } 73 | 74 | 75 | private List getImplementersOf(String className) { 76 | SootClass sootClass = Scene.v().getSootClass(className); 77 | List list = Scene.v().getActiveHierarchy().getSubclassesOfIncluding(sootClass); 78 | List res = new LinkedList<>(); 79 | for (SootClass c : list) { 80 | res.add(c); 81 | } 82 | return res; 83 | } 84 | 85 | @Override 86 | public Collection>> generate(Unit unit, 87 | Collection calledMethod) { 88 | return this.generateThisAtAnyCallSitesOf(unit, calledMethod, closeMethods(), initialTrans); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /typestate/typestate/impl/iteratoranalysis/HasNextAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.iteratoranalysis; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class HasNextAnalysis extends TypestateAnalysis { 9 | 10 | public HasNextAnalysis(InfoflowCFG cfg) { 11 | super(new HasNextStateMachine(cfg), cfg); 12 | } 13 | public HasNextAnalysis(InfoflowCFG cfg, IDebugger debugger) { 14 | super(new HasNextStateMachine(cfg), cfg, debugger); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /typestate/typestate/impl/iteratoranalysis/HasNextStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.iteratoranalysis; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.RefType; 15 | import soot.Scene; 16 | import soot.SootClass; 17 | import soot.SootMethod; 18 | import soot.Unit; 19 | import soot.jimple.AssignStmt; 20 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 21 | import typestate.TransitionFunction; 22 | import typestate.TypestateChangeFunction; 23 | import typestate.TypestateDomainValue; 24 | import typestate.finiteautomata.MatcherStateMachine; 25 | import typestate.finiteautomata.MatcherTransition; 26 | import typestate.finiteautomata.MatcherTransition.Parameter; 27 | import typestate.finiteautomata.MatcherTransition.Type; 28 | import typestate.finiteautomata.State; 29 | import typestate.finiteautomata.Transition; 30 | 31 | public class HasNextStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 32 | 33 | private MatcherTransition initialTrans; 34 | private InfoflowCFG icfg; 35 | private Set hasNextMethods; 36 | 37 | public static enum States implements State { 38 | NONE, INIT, HASNEXT, ERROR; 39 | 40 | @Override 41 | public boolean isErrorState() { 42 | return this == ERROR; 43 | } 44 | 45 | @Override 46 | public boolean isInitialState() { 47 | return this == INIT; 48 | } 49 | } 50 | 51 | HasNextStateMachine(InfoflowCFG cfg) { 52 | this.icfg = cfg; 53 | initialTrans = 54 | new MatcherTransition(States.NONE, retrieveIteratorConstructors(),Parameter.This, States.INIT, Type.None); 55 | addTransition(initialTrans); 56 | addTransition( 57 | new MatcherTransition(States.INIT, retrieveNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 58 | addTransition( 59 | new MatcherTransition(States.ERROR, retrieveNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 60 | addTransition( 61 | new MatcherTransition(States.HASNEXT, retrieveNextMethods(),Parameter.This, States.INIT, Type.OnReturn)); 62 | addTransition(new MatcherTransition(States.INIT, retrieveHasNextMethods(),Parameter.This, States.HASNEXT, 63 | Type.OnReturn)); 64 | addTransition(new MatcherTransition(States.HASNEXT, retrieveHasNextMethods(),Parameter.This, States.HASNEXT, 65 | Type.OnReturn)); 66 | addTransition( 67 | new MatcherTransition(States.ERROR, retrieveHasNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 68 | } 69 | @Override 70 | public boolean seedInApplicationClass() { 71 | return true; 72 | } 73 | private Set retrieveHasNextMethods() { 74 | if (hasNextMethods == null) 75 | hasNextMethods = 76 | selectMethodByName(getImplementersOfIterator("java.util.Iterator"), "hasNext"); 77 | return hasNextMethods; 78 | } 79 | 80 | private Set retrieveNextMethods() { 81 | return selectMethodByName(getImplementersOfIterator("java.util.Iterator"), "next"); 82 | } 83 | 84 | 85 | private Set retrieveIteratorConstructors() { 86 | Set selectMethodByName = selectMethodByName(Scene.v().getClasses(), "iterator"); 87 | Set res = new HashSet<>(); 88 | for (SootMethod m : selectMethodByName) { 89 | if (m.getReturnType() instanceof RefType) { 90 | RefType refType = (RefType) m.getReturnType(); 91 | SootClass classs = refType.getSootClass(); 92 | if (classs.equals(Scene.v().getSootClass("java.util.Iterator")) 93 | || Scene.v().getActiveHierarchy() 94 | .getImplementersOf(Scene.v().getSootClass("java.util.Iterator")).contains(classs)) { 95 | res.add(m); 96 | } 97 | } 98 | } 99 | return res; 100 | } 101 | 102 | private List getImplementersOfIterator(String className) { 103 | SootClass sootClass = Scene.v().getSootClass(className); 104 | List list = Scene.v().getActiveHierarchy().getImplementersOf(sootClass); 105 | List res = new LinkedList<>(); 106 | for (SootClass c : list) { 107 | res.add(c); 108 | } 109 | return res; 110 | } 111 | 112 | @Override 113 | public Collection>> generate(Unit unit, 114 | Collection calledMethod) { 115 | boolean matches = false; 116 | for (SootMethod method : calledMethod) { 117 | if (initialTrans.matches(method)) { 118 | matches = true; 119 | } 120 | } 121 | if (!matches) 122 | return Collections.emptySet(); 123 | if (unit instanceof AssignStmt) { 124 | Set>> out = new HashSet<>(); 125 | AssignStmt stmt = (AssignStmt) unit; 126 | out.add(new Pair>( 127 | new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), 128 | new TransitionFunction(initialTrans))); 129 | return out; 130 | } 131 | return Collections.emptySet(); 132 | } 133 | 134 | @Override 135 | public Set getReturnTransitionsFor(AccessGraph callerD1, Unit callSite, 136 | SootMethod calleeMethod, Unit exitStmt, AccessGraph exitNode, Unit returnSite, 137 | AccessGraph retNode) { 138 | if (retrieveHasNextMethods().contains(calleeMethod)) { 139 | if (icfg.getMethodOf(callSite).getSignature().contains("java.lang.Object next()")) 140 | return Collections.emptySet(); 141 | } 142 | 143 | return super.getReturnTransitionsFor(callerD1, callSite, calleeMethod, exitStmt, exitNode, returnSite, retNode); 144 | } 145 | } 146 | 147 | -------------------------------------------------------------------------------- /typestate/typestate/impl/iteratoranalysis/allocsite/HasNextAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.iteratoranalysis.allocsite; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | import typestate.impl.fileanalysis.FileMustBeClosedStateMachine; 8 | 9 | public class HasNextAnalysis extends TypestateAnalysis { 10 | 11 | public HasNextAnalysis(InfoflowCFG cfg) { 12 | super(new HasNextStateMachine(cfg), cfg); 13 | } 14 | public HasNextAnalysis(InfoflowCFG cfg, IDebugger debugger) { 15 | super(new HasNextStateMachine(cfg),cfg, debugger); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /typestate/typestate/impl/iteratoranalysis/allocsite/HasNextStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.iteratoranalysis.allocsite; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.RefType; 15 | import soot.Scene; 16 | import soot.SootClass; 17 | import soot.SootMethod; 18 | import soot.Unit; 19 | import soot.jimple.AssignStmt; 20 | import soot.jimple.NewExpr; 21 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 22 | import typestate.TransitionFunction; 23 | import typestate.TypestateChangeFunction; 24 | import typestate.TypestateDomainValue; 25 | import typestate.finiteautomata.MatcherStateMachine; 26 | import typestate.finiteautomata.MatcherTransition; 27 | import typestate.finiteautomata.MatcherTransition.Parameter; 28 | import typestate.finiteautomata.MatcherTransition.Type; 29 | import typestate.finiteautomata.State; 30 | import typestate.finiteautomata.Transition; 31 | 32 | public class HasNextStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 33 | 34 | private MatcherTransition initialTrans; 35 | private InfoflowCFG icfg; 36 | private Set hasNextMethods; 37 | 38 | public static enum States implements State { 39 | NONE, INIT, HASNEXT, ERROR; 40 | 41 | @Override 42 | public boolean isErrorState() { 43 | return this == ERROR; 44 | } 45 | 46 | @Override 47 | public boolean isInitialState() { 48 | return this == INIT; 49 | } 50 | } 51 | 52 | HasNextStateMachine(InfoflowCFG cfg) { 53 | this.icfg = cfg; 54 | initialTrans = 55 | new MatcherTransition(States.NONE, retrieveIteratorConstructors(),Parameter.This, States.INIT, Type.None); 56 | addTransition(initialTrans); 57 | addTransition( 58 | new MatcherTransition(States.INIT, retrieveNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 59 | addTransition( 60 | new MatcherTransition(States.ERROR, retrieveNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 61 | addTransition( 62 | new MatcherTransition(States.HASNEXT, retrieveNextMethods(),Parameter.This, States.INIT, Type.OnReturn)); 63 | addTransition(new MatcherTransition(States.INIT, retrieveHasNextMethods(),Parameter.This, States.HASNEXT, 64 | Type.OnReturn)); 65 | addTransition(new MatcherTransition(States.HASNEXT, retrieveHasNextMethods(),Parameter.This, States.HASNEXT, 66 | Type.OnReturn)); 67 | addTransition( 68 | new MatcherTransition(States.ERROR, retrieveHasNextMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 69 | } 70 | 71 | private Set retrieveHasNextMethods() { 72 | if (hasNextMethods == null) 73 | hasNextMethods = 74 | selectMethodByName(getImplementersOfIterator("java.util.Iterator"), "hasNext"); 75 | return hasNextMethods; 76 | } 77 | 78 | private Set retrieveNextMethods() { 79 | return selectMethodByName(getImplementersOfIterator("java.util.Iterator"), "next"); 80 | } 81 | 82 | @Override 83 | public boolean seedInApplicationClass() { 84 | return true; 85 | } 86 | private Set retrieveIteratorConstructors() { 87 | Set selectMethodByName = selectMethodByName(Scene.v().getClasses(), "iterator"); 88 | Set res = new HashSet<>(); 89 | for (SootMethod m : selectMethodByName) { 90 | if (m.getReturnType() instanceof RefType) { 91 | RefType refType = (RefType) m.getReturnType(); 92 | SootClass classs = refType.getSootClass(); 93 | if (classs.equals(Scene.v().getSootClass("java.util.Iterator")) 94 | || Scene.v().getActiveHierarchy() 95 | .getImplementersOf(Scene.v().getSootClass("java.util.Iterator")).contains(classs)) { 96 | res.add(m); 97 | } 98 | } 99 | } 100 | return res; 101 | } 102 | 103 | 104 | private List getImplementersOfIterator(String className) { 105 | SootClass sootClass = Scene.v().getSootClass(className); 106 | List list = Scene.v().getActiveHierarchy().getImplementersOf(sootClass); 107 | List res = new LinkedList<>(); 108 | for (SootClass c : list) { 109 | res.add(c); 110 | } 111 | return res; 112 | } 113 | 114 | @Override 115 | public Collection>> generate(Unit unit, 116 | Collection calledMethod) { 117 | boolean matches = false; 118 | // for (SootMethod method : calledMethod) { 119 | // if (initialTrans.matches(method)) { 120 | // matches = true; 121 | // } 122 | // } 123 | // if (!matches) 124 | // return Collections.emptySet(); 125 | if (unit instanceof AssignStmt) { 126 | if (((AssignStmt) unit).getRightOp() instanceof NewExpr) { 127 | NewExpr newExpr = (NewExpr) ((AssignStmt) unit).getRightOp(); 128 | if (newExpr.getType() instanceof RefType) { 129 | RefType refType = (RefType) newExpr.getType(); 130 | System.out.println(unit); 131 | if (getImplementersOfIterator("java.util.Iterator").contains(refType.getSootClass())) { 132 | Set>> out = new HashSet<>(); 133 | AssignStmt stmt = (AssignStmt) unit; 134 | out.add(new Pair>( 135 | new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), 136 | new TransitionFunction(initialTrans))); 137 | return out; 138 | } 139 | } 140 | } 141 | 142 | } 143 | return Collections.emptySet(); 144 | } 145 | 146 | 147 | @Override 148 | public Set getReturnTransitionsFor(AccessGraph callerD1, Unit callSite, 149 | SootMethod calleeMethod, Unit exitStmt, AccessGraph exitNode, Unit returnSite, 150 | AccessGraph retNode) { 151 | if (retrieveHasNextMethods().contains(calleeMethod)) { 152 | if (icfg.getMethodOf(callSite).getSignature().contains("java.lang.Object next()")) 153 | return Collections.emptySet(); 154 | } 155 | 156 | return super.getReturnTransitionsFor(callerD1, callSite, calleeMethod, exitStmt, exitNode, returnSite, retNode); 157 | } 158 | } 159 | 160 | -------------------------------------------------------------------------------- /typestate/typestate/impl/keystore/KeyStoreAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.keystore; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class KeyStoreAnalysis extends TypestateAnalysis { 9 | 10 | public KeyStoreAnalysis(InfoflowCFG icfg) { 11 | super(new KeyStoreStateMachine(), icfg); 12 | } 13 | 14 | public KeyStoreAnalysis(InfoflowCFG icfg, IDebugger debugger) { 15 | super(new KeyStoreStateMachine(), icfg, debugger); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/keystore/KeyStoreStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.keystore; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.AssignStmt; 19 | import typestate.TransitionFunction; 20 | import typestate.TypestateChangeFunction; 21 | import typestate.TypestateDomainValue; 22 | import typestate.finiteautomata.MatcherStateMachine; 23 | import typestate.finiteautomata.MatcherTransition; 24 | import typestate.finiteautomata.MatcherTransition.Parameter; 25 | import typestate.finiteautomata.MatcherTransition.Type; 26 | import typestate.finiteautomata.State; 27 | import typestate.finiteautomata.Transition; 28 | 29 | public class KeyStoreStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 30 | 31 | private MatcherTransition initialTrans; 32 | 33 | public static enum States implements State { 34 | NONE, INIT, LOADED, ERROR; 35 | 36 | @Override 37 | public boolean isErrorState() { 38 | return this == ERROR; 39 | } 40 | 41 | @Override 42 | public boolean isInitialState() { 43 | return this == INIT; 44 | } 45 | } 46 | 47 | KeyStoreStateMachine() { 48 | initialTrans = 49 | new MatcherTransition(States.NONE, keyStoreConstructor(),Parameter.This, States.INIT, Type.OnReturn); 50 | addTransition(initialTrans); 51 | addTransition(new MatcherTransition(States.INIT, loadMethods(),Parameter.This, States.LOADED, Type.OnReturn)); 52 | 53 | addTransition( 54 | new MatcherTransition(States.INIT, anyMethodOtherThanLoad(),Parameter.This, States.ERROR, Type.OnReturn)); 55 | addTransition( 56 | new MatcherTransition(States.ERROR, anyMethodOtherThanLoad(),Parameter.This, States.ERROR, Type.OnReturn)); 57 | 58 | } 59 | @Override 60 | public boolean seedInApplicationClass() { 61 | return true; 62 | } 63 | private Set anyMethodOtherThanLoad() { 64 | List subclasses = getSubclassesOf("java.security.KeyStore"); 65 | Set loadMethods = loadMethods(); 66 | Set out = new HashSet<>(); 67 | for (SootClass c : subclasses) { 68 | for (SootMethod m : c.getMethods()) 69 | if (m.isPublic() && !loadMethods.contains(m) && !m.isStatic()) 70 | out.add(m); 71 | } 72 | return out; 73 | } 74 | 75 | private Set loadMethods() { 76 | return selectMethodByName(getSubclassesOf("java.security.KeyStore"), "load"); 77 | } 78 | 79 | 80 | private Set keyStoreConstructor() { 81 | List subclasses = getSubclassesOf("java.security.KeyStore"); 82 | Set out = new HashSet<>(); 83 | for (SootClass c : subclasses) { 84 | for (SootMethod m : c.getMethods()) 85 | if (m.getName().equals("getInstance") && m.isStatic()) 86 | out.add(m); 87 | } 88 | return out; 89 | } 90 | 91 | 92 | @Override 93 | public Collection>> generate(Unit unit, 94 | Collection calledMethod) { 95 | boolean matches = false; 96 | for (SootMethod method : calledMethod) { 97 | if (initialTrans.matches(method)) { 98 | matches = true; 99 | } 100 | } 101 | if (!matches) 102 | return Collections.emptySet(); 103 | if (unit instanceof AssignStmt) { 104 | Set>> out = new HashSet<>(); 105 | AssignStmt stmt = (AssignStmt) unit; 106 | out.add(new Pair>( 107 | new AccessGraph((Local) stmt.getLeftOp(), stmt.getLeftOp().getType()), 108 | new TransitionFunction(initialTrans))); 109 | return out; 110 | } 111 | return Collections.emptySet(); 112 | } 113 | 114 | } 115 | 116 | -------------------------------------------------------------------------------- /typestate/typestate/impl/outputstream/OutputStreamAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.outputstream; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class OutputStreamAnalysis extends TypestateAnalysis { 9 | 10 | public OutputStreamAnalysis(InfoflowCFG icfg) { 11 | super(new OutputStreamStateMachine(icfg), icfg); 12 | } 13 | 14 | 15 | public OutputStreamAnalysis(InfoflowCFG icfg, IDebugger debugger) { 16 | super(new OutputStreamStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/outputstream/OutputStreamStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.outputstream; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.InstanceInvokeExpr; 19 | import soot.jimple.ReturnVoidStmt; 20 | import soot.jimple.Stmt; 21 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 22 | import typestate.TransitionFunction; 23 | import typestate.TypestateChangeFunction; 24 | import typestate.TypestateDomainValue; 25 | import typestate.finiteautomata.MatcherStateMachine; 26 | import typestate.finiteautomata.MatcherTransition; 27 | import typestate.finiteautomata.MatcherTransition.Parameter; 28 | import typestate.finiteautomata.MatcherTransition.Type; 29 | import typestate.finiteautomata.State; 30 | import typestate.finiteautomata.Transition; 31 | 32 | public class OutputStreamStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 33 | 34 | private MatcherTransition initialTrans; 35 | private InfoflowCFG icfg; 36 | 37 | public static enum States implements State { 38 | NONE, CLOSED, ERROR; 39 | 40 | @Override 41 | public boolean isErrorState() { 42 | return this == ERROR; 43 | } 44 | 45 | @Override 46 | public boolean isInitialState() { 47 | return this == CLOSED; 48 | } 49 | } 50 | 51 | OutputStreamStateMachine(InfoflowCFG icfg) { 52 | this.icfg = icfg; 53 | initialTrans = new MatcherTransition(States.NONE, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition( 56 | new MatcherTransition(States.CLOSED, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.CLOSED, writeMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 58 | addTransition(new MatcherTransition(States.ERROR, writeMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 59 | } 60 | 61 | @Override 62 | public boolean seedInApplicationClass() { 63 | return false; 64 | } 65 | 66 | private Set closeMethods() { 67 | return selectMethodByName(getImplementersOf("java.io.OutputStream"), "close"); 68 | } 69 | 70 | private Set writeMethods() { 71 | return selectMethodByName(getImplementersOf("java.io.OutputStream"), "write"); 72 | } 73 | 74 | 75 | private List getImplementersOf(String className) { 76 | SootClass sootClass = Scene.v().getSootClass(className); 77 | List list = Scene.v().getActiveHierarchy().getSubclassesOfIncluding(sootClass); 78 | List res = new LinkedList<>(); 79 | for (SootClass c : list) { 80 | res.add(c); 81 | } 82 | return res; 83 | } 84 | 85 | @Override 86 | public Collection>> generate(Unit unit, 87 | Collection calledMethod) { 88 | return generateThisAtAnyCallSitesOf(unit,calledMethod,closeMethods(), initialTrans); 89 | } 90 | 91 | 92 | } 93 | -------------------------------------------------------------------------------- /typestate/typestate/impl/pipedinputstream/PipedInputStreamAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.pipedinputstream; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class PipedInputStreamAnalysis extends TypestateAnalysis { 9 | 10 | public PipedInputStreamAnalysis(InfoflowCFG icfg) { 11 | super(new PipedInputStreamStateMachine(icfg), icfg); 12 | } 13 | 14 | 15 | public PipedInputStreamAnalysis(InfoflowCFG icfg, IDebugger debugger) { 16 | super(new PipedInputStreamStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/pipedinputstream/PipedInputStreamStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.pipedinputstream; 2 | 3 | import java.util.Collection; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | import boomerang.accessgraph.AccessGraph; 9 | import heros.EdgeFunction; 10 | import heros.solver.Pair; 11 | import soot.SootClass; 12 | import soot.SootMethod; 13 | import soot.Unit; 14 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 15 | import typestate.TypestateChangeFunction; 16 | import typestate.TypestateDomainValue; 17 | import typestate.finiteautomata.MatcherStateMachine; 18 | import typestate.finiteautomata.MatcherTransition; 19 | import typestate.finiteautomata.MatcherTransition.Parameter; 20 | import typestate.finiteautomata.MatcherTransition.Type; 21 | import typestate.finiteautomata.State; 22 | 23 | public class PipedInputStreamStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 24 | 25 | private MatcherTransition initialTrans; 26 | 27 | public static enum States implements State { 28 | NONE, INIT, CONNECTED, ERROR; 29 | 30 | @Override 31 | public boolean isErrorState() { 32 | return this == ERROR; 33 | } 34 | 35 | @Override 36 | public boolean isInitialState() { 37 | return this == NONE; 38 | } 39 | } 40 | 41 | PipedInputStreamStateMachine(InfoflowCFG icfg) { 42 | initialTrans = new MatcherTransition(States.NONE, constructors(), Parameter.This, States.INIT, Type.OnReturn); 43 | addTransition(initialTrans); 44 | addTransition( 45 | new MatcherTransition(States.INIT, connect(), Parameter.This, States.CONNECTED, Type.OnReturn)); 46 | addTransition(new MatcherTransition(States.INIT, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 47 | addTransition(new MatcherTransition(States.CONNECTED, readMethods(), Parameter.This, States.CONNECTED, Type.OnReturn)); 48 | addTransition(new MatcherTransition(States.ERROR, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 49 | } 50 | 51 | private Set constructors() { 52 | List subclasses = getSubclassesOf("java.io.PipedInputStream"); 53 | Set out = new HashSet<>(); 54 | for (SootClass c : subclasses) { 55 | for (SootMethod m : c.getMethods()) 56 | if (m.isConstructor() && !m.toString().contains("PipedOutputStream")) 57 | out.add(m); 58 | } 59 | return out; 60 | } 61 | private Set connect() { 62 | return selectMethodByName(getSubclassesOf("java.io.PipedInputStream"), "connect"); 63 | } 64 | 65 | @Override 66 | public boolean seedInApplicationClass() { 67 | return true; 68 | } 69 | 70 | 71 | private Set readMethods() { 72 | return selectMethodByName(getSubclassesOf("java.io.PipedInputStream"), "read"); 73 | } 74 | 75 | 76 | @Override 77 | public Collection>> generate(Unit unit, 78 | Collection calledMethod) { 79 | return generateAtConstructor(unit, calledMethod, initialTrans); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /typestate/typestate/impl/pipedoutputstream/PipedOutputStreamAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.pipedoutputstream; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class PipedOutputStreamAnalysis extends TypestateAnalysis { 9 | 10 | public PipedOutputStreamAnalysis(InfoflowCFG icfg) { 11 | super(new PipedOutputStreamStateMachine(icfg), icfg); 12 | } 13 | 14 | 15 | public PipedOutputStreamAnalysis(InfoflowCFG icfg, IDebugger debugger) { 16 | super(new PipedOutputStreamStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/pipedoutputstream/PipedOutputStreamStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.pipedoutputstream; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.InstanceInvokeExpr; 19 | import soot.jimple.ReturnVoidStmt; 20 | import soot.jimple.Stmt; 21 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 22 | import typestate.TransitionFunction; 23 | import typestate.TypestateChangeFunction; 24 | import typestate.TypestateDomainValue; 25 | import typestate.finiteautomata.MatcherStateMachine; 26 | import typestate.finiteautomata.MatcherTransition; 27 | import typestate.finiteautomata.MatcherTransition.Parameter; 28 | import typestate.finiteautomata.MatcherTransition.Type; 29 | import typestate.finiteautomata.State; 30 | import typestate.finiteautomata.Transition; 31 | 32 | public class PipedOutputStreamStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 33 | 34 | private MatcherTransition initialTrans; 35 | private InfoflowCFG icfg; 36 | 37 | public static enum States implements State { 38 | NONE, INIT, CONNECTED, ERROR; 39 | 40 | @Override 41 | public boolean isErrorState() { 42 | return this == ERROR; 43 | } 44 | 45 | @Override 46 | public boolean isInitialState() { 47 | return this == NONE; 48 | } 49 | } 50 | 51 | PipedOutputStreamStateMachine(InfoflowCFG icfg) { 52 | this.icfg = icfg; 53 | initialTrans = new MatcherTransition(States.NONE, constructors(), Parameter.This, States.INIT, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition( 56 | new MatcherTransition(States.INIT, connect(), Parameter.This, States.CONNECTED, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.INIT, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 58 | addTransition(new MatcherTransition(States.CONNECTED, readMethods(), Parameter.This, States.CONNECTED, Type.OnReturn)); 59 | addTransition(new MatcherTransition(States.ERROR, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 60 | } 61 | 62 | private Set constructors() { 63 | List subclasses = getSubclassesOf("java.io.PipedOutputStream"); 64 | Set out = new HashSet<>(); 65 | for (SootClass c : subclasses) { 66 | for (SootMethod m : c.getMethods()) 67 | if (m.isConstructor() && !m.toString().contains("PipedInputStream")) 68 | out.add(m); 69 | } 70 | return out; 71 | } 72 | private Set connect() { 73 | return selectMethodByName(getSubclassesOf("java.io.PipedOutputStream"), "connect"); 74 | } 75 | 76 | @Override 77 | public boolean seedInApplicationClass() { 78 | return true; 79 | } 80 | 81 | 82 | private Set readMethods() { 83 | return selectMethodByName(getSubclassesOf("java.io.PipedOutputStream"), "write"); 84 | } 85 | 86 | 87 | @Override 88 | public Collection>> generate(Unit unit, 89 | Collection calledMethod) { 90 | return generateAtConstructor(unit, calledMethod, initialTrans); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /typestate/typestate/impl/printstream/PrintStreamAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.printstream; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class PrintStreamAnalysis extends TypestateAnalysis { 9 | 10 | public PrintStreamAnalysis(InfoflowCFG icfg) { 11 | super(new PrintStreamStateMachine(icfg), icfg); 12 | } 13 | 14 | public PrintStreamAnalysis(InfoflowCFG icfg, 15 | IDebugger debugger) { 16 | super(new PrintStreamStateMachine(icfg), icfg, debugger); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /typestate/typestate/impl/printstream/PrintStreamStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.printstream; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.ReturnVoidStmt; 19 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 20 | import typestate.TransitionFunction; 21 | import typestate.TypestateChangeFunction; 22 | import typestate.TypestateDomainValue; 23 | import typestate.finiteautomata.MatcherStateMachine; 24 | import typestate.finiteautomata.MatcherTransition; 25 | import typestate.finiteautomata.MatcherTransition.Parameter; 26 | import typestate.finiteautomata.MatcherTransition.Type; 27 | import typestate.finiteautomata.State; 28 | import typestate.finiteautomata.Transition; 29 | 30 | public class PrintStreamStateMachine extends MatcherStateMachine 31 | implements TypestateChangeFunction { 32 | 33 | private MatcherTransition initialTrans; 34 | private InfoflowCFG icfg; 35 | 36 | public static enum States implements State { 37 | NONE, CLOSED, ERROR; 38 | 39 | @Override 40 | public boolean isErrorState() { 41 | return this == ERROR; 42 | } 43 | 44 | @Override 45 | public boolean isInitialState() { 46 | return this == CLOSED; 47 | } 48 | } 49 | 50 | PrintStreamStateMachine(InfoflowCFG icfg) { 51 | this.icfg = icfg; 52 | initialTrans = new MatcherTransition(States.NONE, closeMethods(),Parameter.This, States.CLOSED, Type.OnReturn); 53 | addTransition(initialTrans); 54 | addTransition( 55 | new MatcherTransition(States.CLOSED, closeMethods(),Parameter.This, States.CLOSED, Type.OnReturn)); 56 | addTransition(new MatcherTransition(States.CLOSED, readMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 57 | } 58 | 59 | private Set closeMethods() { 60 | return selectMethodByName(getSubclassesOf("java.io.PrintStream"), "close"); 61 | } 62 | @Override 63 | public boolean seedInApplicationClass() { 64 | return false; 65 | } 66 | 67 | private Set readMethods() { 68 | List subclasses = getSubclassesOf("java.io.PrintStream"); 69 | Set closeMethods = closeMethods(); 70 | Set out = new HashSet<>(); 71 | for (SootClass c : subclasses) { 72 | for (SootMethod m : c.getMethods()) 73 | if (m.isPublic() && !closeMethods.contains(m) && !m.isStatic()) 74 | out.add(m); 75 | } 76 | return out; 77 | } 78 | 79 | 80 | @Override 81 | public Collection>> generate(Unit unit, 82 | Collection calledMethod) { 83 | return this.generateThisAtAnyCallSitesOf(unit, calledMethod, closeMethods(), initialTrans); 84 | } 85 | 86 | } 87 | 88 | -------------------------------------------------------------------------------- /typestate/typestate/impl/printwriter/PrintWriterAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.printwriter; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class PrintWriterAnalysis extends TypestateAnalysis { 9 | 10 | public PrintWriterAnalysis(InfoflowCFG icfg) { 11 | super(new PrintWriterStateMachine(icfg), icfg); 12 | } 13 | 14 | public PrintWriterAnalysis(InfoflowCFG icfg, IDebugger debugger) { 15 | super(new PrintWriterStateMachine(icfg), icfg, debugger); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/printwriter/PrintWriterStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.printwriter; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 19 | import typestate.TransitionFunction; 20 | import typestate.TypestateChangeFunction; 21 | import typestate.TypestateDomainValue; 22 | import typestate.finiteautomata.MatcherStateMachine; 23 | import typestate.finiteautomata.MatcherTransition; 24 | import typestate.finiteautomata.MatcherTransition.Parameter; 25 | import typestate.finiteautomata.MatcherTransition.Type; 26 | import typestate.finiteautomata.State; 27 | import typestate.finiteautomata.Transition; 28 | 29 | public class PrintWriterStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 30 | 31 | private MatcherTransition initialTrans; 32 | private InfoflowCFG icfg; 33 | 34 | public static enum States implements State { 35 | NONE, CLOSED, ERROR; 36 | 37 | @Override 38 | public boolean isErrorState() { 39 | return this == ERROR; 40 | } 41 | 42 | @Override 43 | public boolean isInitialState() { 44 | return this == CLOSED; 45 | } 46 | } 47 | 48 | PrintWriterStateMachine(InfoflowCFG icfg) { 49 | this.icfg = icfg; 50 | initialTrans = new MatcherTransition(States.NONE, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn); 51 | addTransition(initialTrans); 52 | addTransition( 53 | new MatcherTransition(States.CLOSED, closeMethods(), Parameter.This, States.CLOSED, Type.OnReturn)); 54 | addTransition(new MatcherTransition(States.CLOSED, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 55 | addTransition(new MatcherTransition(States.ERROR, readMethods(), Parameter.This, States.ERROR, Type.OnReturn)); 56 | 57 | } 58 | 59 | private Set closeMethods() { 60 | return selectMethodByName(getSubclassesOf("java.io.PrintWriter"), "close"); 61 | } 62 | 63 | @Override 64 | public boolean seedInApplicationClass() { 65 | return false; 66 | } 67 | 68 | private Set readMethods() { 69 | List subclasses = getSubclassesOf("java.io.PrintWriter"); 70 | Set closeMethods = closeMethods(); 71 | Set out = new HashSet<>(); 72 | for (SootClass c : subclasses) { 73 | for (SootMethod m : c.getMethods()) 74 | if (m.isPublic() && !closeMethods.contains(m) && !m.isStatic()) 75 | out.add(m); 76 | } 77 | return out; 78 | } 79 | 80 | @Override 81 | public Collection>> generate(Unit unit, 82 | Collection calledMethod) { 83 | return generateThisAtAnyCallSitesOf(unit, calledMethod, closeMethods(), initialTrans); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /typestate/typestate/impl/signature/SignatureAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.signature; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class SignatureAnalysis extends TypestateAnalysis { 9 | 10 | public SignatureAnalysis(InfoflowCFG icfg) { 11 | super(new SignatureStateMachine(icfg), icfg); 12 | } 13 | 14 | public SignatureAnalysis(InfoflowCFG icfg, 15 | IDebugger debugger) { 16 | super(new SignatureStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/signature/SignatureStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.signature; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.InstanceInvokeExpr; 19 | import soot.jimple.Stmt; 20 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 21 | import typestate.TransitionFunction; 22 | import typestate.TypestateChangeFunction; 23 | import typestate.TypestateDomainValue; 24 | import typestate.finiteautomata.MatcherStateMachine; 25 | import typestate.finiteautomata.MatcherTransition; 26 | import typestate.finiteautomata.MatcherTransition.Parameter; 27 | import typestate.finiteautomata.MatcherTransition.Type; 28 | import typestate.finiteautomata.State; 29 | import typestate.finiteautomata.Transition; 30 | 31 | public class SignatureStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 32 | 33 | private MatcherTransition initialTrans; 34 | private InfoflowCFG icfg; 35 | 36 | public static enum States implements State { 37 | NONE, UNITIALIZED, SIGN_CHECK, VERIFY_CHECK, ERROR; 38 | 39 | @Override 40 | public boolean isErrorState() { 41 | return this == ERROR; 42 | } 43 | 44 | @Override 45 | public boolean isInitialState() { 46 | return this == UNITIALIZED; 47 | } 48 | } 49 | 50 | SignatureStateMachine(InfoflowCFG icfg) { 51 | this.icfg = icfg; 52 | initialTrans = 53 | new MatcherTransition(States.NONE, constructor(),Parameter.This, States.UNITIALIZED, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition(new MatcherTransition(States.UNITIALIZED, initSign(),Parameter.This, States.SIGN_CHECK, Type.OnReturn)); 56 | addTransition(new MatcherTransition(States.UNITIALIZED, initVerify(),Parameter.This, States.VERIFY_CHECK, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.UNITIALIZED, sign(),Parameter.This, States.ERROR, Type.OnReturn)); 58 | addTransition(new MatcherTransition(States.UNITIALIZED, verify(),Parameter.This, States.ERROR, Type.OnReturn)); 59 | addTransition(new MatcherTransition(States.UNITIALIZED, update(),Parameter.This, States.ERROR, Type.OnReturn)); 60 | 61 | addTransition(new MatcherTransition(States.SIGN_CHECK, initSign(),Parameter.This, States.SIGN_CHECK, Type.OnReturn)); 62 | addTransition(new MatcherTransition(States.SIGN_CHECK, initVerify(),Parameter.This, States.VERIFY_CHECK, Type.OnReturn)); 63 | addTransition(new MatcherTransition(States.SIGN_CHECK, sign(),Parameter.This, States.SIGN_CHECK, Type.OnReturn)); 64 | addTransition(new MatcherTransition(States.SIGN_CHECK, verify(),Parameter.This, States.ERROR, Type.OnReturn)); 65 | addTransition(new MatcherTransition(States.SIGN_CHECK, update(),Parameter.This, States.SIGN_CHECK, Type.OnReturn)); 66 | 67 | addTransition(new MatcherTransition(States.VERIFY_CHECK, initSign(),Parameter.This, States.SIGN_CHECK, Type.OnReturn)); 68 | addTransition(new MatcherTransition(States.VERIFY_CHECK, initVerify(),Parameter.This, States.VERIFY_CHECK, Type.OnReturn)); 69 | addTransition(new MatcherTransition(States.VERIFY_CHECK, sign(),Parameter.This, States.ERROR, Type.OnReturn)); 70 | addTransition(new MatcherTransition(States.VERIFY_CHECK, verify(),Parameter.This, States.VERIFY_CHECK, Type.OnReturn)); 71 | addTransition(new MatcherTransition(States.VERIFY_CHECK, update(),Parameter.This, States.VERIFY_CHECK, Type.OnReturn)); 72 | 73 | addTransition(new MatcherTransition(States.ERROR, initSign(),Parameter.This, States.ERROR, Type.OnReturn)); 74 | addTransition(new MatcherTransition(States.ERROR, initVerify(),Parameter.This, States.ERROR, Type.OnReturn)); 75 | addTransition(new MatcherTransition(States.ERROR, sign(),Parameter.This, States.ERROR, Type.OnReturn)); 76 | addTransition(new MatcherTransition(States.ERROR, verify(),Parameter.This, States.ERROR, Type.OnReturn)); 77 | addTransition(new MatcherTransition(States.ERROR, update(),Parameter.This, States.ERROR, Type.OnReturn)); 78 | } 79 | @Override 80 | public boolean seedInApplicationClass() { 81 | return false; 82 | } 83 | private Set constructor() { 84 | List subclasses = getSubclassesOf("java.security.Signature"); 85 | Set out = new HashSet<>(); 86 | for (SootClass c : subclasses) { 87 | for (SootMethod m : c.getMethods()) 88 | if (m.isPublic() && m.getName().equals("getInstance")) 89 | out.add(m); 90 | } 91 | return out; 92 | } 93 | 94 | private Set verify() { 95 | return selectMethodByName(getSubclassesOf("java.security.Signature"), "verify"); 96 | } 97 | private Set update() { 98 | return selectMethodByName(getSubclassesOf("java.security.Signature"), "update"); 99 | } 100 | private Set sign() { 101 | return selectMethodByName(getSubclassesOf("java.security.Signature"), "sign"); 102 | } 103 | private Set initSign() { 104 | return selectMethodByName(getSubclassesOf("java.security.Signature"), "initSign"); 105 | } 106 | private Set initVerify() { 107 | return selectMethodByName(getSubclassesOf("java.security.Signature"), "initVerify"); 108 | } 109 | 110 | 111 | 112 | @Override 113 | public Collection>> generate(Unit unit, 114 | Collection calledMethod) { 115 | return generateReturnValueOf(unit, calledMethod, initialTrans); 116 | } 117 | 118 | 119 | } 120 | 121 | -------------------------------------------------------------------------------- /typestate/typestate/impl/socket/SocketAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.socket; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class SocketAnalysis extends TypestateAnalysis { 9 | 10 | public SocketAnalysis(InfoflowCFG icfg) { 11 | super(new SocketStateMachine(icfg), icfg); 12 | } 13 | 14 | public SocketAnalysis(InfoflowCFG icfg, 15 | IDebugger debugger) { 16 | super(new SocketStateMachine(icfg), icfg, debugger); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/socket/SocketStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.socket; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | import boomerang.accessgraph.AccessGraph; 11 | import heros.EdgeFunction; 12 | import heros.solver.Pair; 13 | import soot.Local; 14 | import soot.Scene; 15 | import soot.SootClass; 16 | import soot.SootMethod; 17 | import soot.Unit; 18 | import soot.jimple.InstanceInvokeExpr; 19 | import soot.jimple.Stmt; 20 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 21 | import typestate.TransitionFunction; 22 | import typestate.TypestateChangeFunction; 23 | import typestate.TypestateDomainValue; 24 | import typestate.finiteautomata.MatcherStateMachine; 25 | import typestate.finiteautomata.MatcherTransition; 26 | import typestate.finiteautomata.MatcherTransition.Parameter; 27 | import typestate.finiteautomata.MatcherTransition.Type; 28 | import typestate.finiteautomata.State; 29 | import typestate.finiteautomata.Transition; 30 | 31 | public class SocketStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 32 | 33 | private MatcherTransition initialTrans; 34 | private InfoflowCFG icfg; 35 | 36 | public static enum States implements State { 37 | NONE, INIT, CONNECTED, ERROR; 38 | 39 | @Override 40 | public boolean isErrorState() { 41 | return this == ERROR; 42 | } 43 | 44 | @Override 45 | public boolean isInitialState() { 46 | return this == INIT; 47 | } 48 | } 49 | 50 | SocketStateMachine(InfoflowCFG icfg) { 51 | this.icfg = icfg; 52 | initialTrans = 53 | new MatcherTransition(States.NONE, socketConstructor(),Parameter.This, States.INIT, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition(new MatcherTransition(States.INIT, connect(),Parameter.This, States.CONNECTED, Type.OnReturn)); 56 | addTransition(new MatcherTransition(States.INIT, useMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.ERROR, useMethods(),Parameter.This, States.ERROR, Type.OnReturn)); 58 | } 59 | @Override 60 | public boolean seedInApplicationClass() { 61 | return true; 62 | } 63 | private Set socketConstructor() { 64 | List subclasses = getSubclassesOf("java.net.Socket"); 65 | Set out = new HashSet<>(); 66 | for (SootClass c : subclasses) { 67 | for (SootMethod m : c.getMethods()) 68 | if (m.isConstructor()) 69 | out.add(m); 70 | } 71 | return out; 72 | } 73 | 74 | private Set connect() { 75 | return selectMethodByName(getSubclassesOf("java.net.Socket"), "connect"); 76 | } 77 | 78 | 79 | private Set useMethods() { 80 | List subclasses = getSubclassesOf("java.net.Socket"); 81 | Set connectMethod = connect(); 82 | Set out = new HashSet<>(); 83 | for (SootClass c : subclasses) { 84 | for (SootMethod m : c.getMethods()) 85 | if (m.isPublic() && !connectMethod.contains(m) && !m.isStatic()) 86 | out.add(m); 87 | } 88 | return out; 89 | } 90 | 91 | 92 | @Override 93 | public Collection>> generate(Unit unit, 94 | Collection calledMethod) { 95 | return generateAtConstructor(unit, calledMethod, initialTrans); 96 | 97 | } 98 | 99 | 100 | } 101 | 102 | -------------------------------------------------------------------------------- /typestate/typestate/impl/urlconn/URLConnAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.urlconn; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class URLConnAnalysis extends TypestateAnalysis { 9 | 10 | public URLConnAnalysis(InfoflowCFG icfg) { 11 | super(new URLConnStateMachine(icfg), icfg); 12 | } 13 | 14 | public URLConnAnalysis(InfoflowCFG icfg, 15 | IDebugger debugger) { 16 | super(new URLConnStateMachine(icfg), icfg, debugger); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /typestate/typestate/impl/urlconn/URLConnStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.urlconn; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.regex.Pattern; 10 | 11 | import boomerang.accessgraph.AccessGraph; 12 | import heros.EdgeFunction; 13 | import heros.solver.Pair; 14 | import soot.Local; 15 | import soot.Scene; 16 | import soot.SootClass; 17 | import soot.SootMethod; 18 | import soot.Unit; 19 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 20 | import typestate.TransitionFunction; 21 | import typestate.TypestateChangeFunction; 22 | import typestate.TypestateDomainValue; 23 | import typestate.finiteautomata.MatcherStateMachine; 24 | import typestate.finiteautomata.MatcherTransition; 25 | import typestate.finiteautomata.MatcherTransition.Parameter; 26 | import typestate.finiteautomata.MatcherTransition.Type; 27 | import typestate.finiteautomata.State; 28 | import typestate.finiteautomata.Transition; 29 | 30 | public class URLConnStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 31 | 32 | private MatcherTransition initialTrans; 33 | private InfoflowCFG icfg; 34 | 35 | public static enum States implements State { 36 | NONE, INIT, CONNECTED, ERROR; 37 | 38 | @Override 39 | public boolean isErrorState() { 40 | return this == ERROR; 41 | } 42 | 43 | @Override 44 | public boolean isInitialState() { 45 | return this == INIT; 46 | } 47 | } 48 | 49 | URLConnStateMachine(InfoflowCFG icfg) { 50 | this.icfg = icfg; 51 | initialTrans = new MatcherTransition(States.NONE, connect(), Parameter.This, States.CONNECTED, Type.OnReturn); 52 | // addTransition(initialTrans); 53 | addTransition(new MatcherTransition(States.CONNECTED, illegalOpertaion(), Parameter.This, States.ERROR, 54 | Type.OnReturn)); 55 | addTransition( 56 | new MatcherTransition(States.ERROR, illegalOpertaion(), Parameter.This, States.ERROR, Type.OnReturn)); 57 | } 58 | 59 | @Override 60 | public boolean seedInApplicationClass() { 61 | return true; 62 | } 63 | 64 | private Set connect() { 65 | return selectMethodByName(getSubclassesOf("java.net.URLConnection"), "connect"); 66 | } 67 | 68 | private Set illegalOpertaion() { 69 | List subclasses = getSubclassesOf("java.net.URLConnection"); 70 | return selectMethodByName(subclasses, 71 | "setDoInput|setDoOutput|setAllowUserInteraction|setUseCaches|setIfModifiedSince|setRequestProperty|addRequestProperty|getRequestProperty|getRequestProperties"); 72 | } 73 | 74 | 75 | @Override 76 | public Collection>> generate(Unit unit, 77 | Collection calledMethod) { 78 | return this.generateThisAtAnyCallSitesOf(unit, calledMethod, connect(), initialTrans); 79 | // for (Unit isRet : icfg.getSuccsOf(unit)) { 80 | // if (connect().contains(methodOf)) { 81 | // if (icfg.isExitStmt(isRet)) { 82 | // Local thisLocal = methodOf.getActiveBody().getThisLocal(); 83 | // Set>> out = new HashSet<>(); 84 | // out.add(new Pair>( 85 | // new AccessGraph(thisLocal, thisLocal.getType()), new TransitionFunction(initialTrans))); 86 | // return out; 87 | // } 88 | // } 89 | // } 90 | // return Collections.emptySet(); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /typestate/typestate/impl/vector/VectorAnalysis.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.vector; 2 | 3 | import ideal.debug.IDebugger; 4 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 5 | import typestate.TypestateAnalysis; 6 | import typestate.TypestateDomainValue; 7 | 8 | public class VectorAnalysis extends TypestateAnalysis { 9 | 10 | public VectorAnalysis(InfoflowCFG icfg) { 11 | super(new VectorStateMachine(icfg), icfg); 12 | } 13 | 14 | public VectorAnalysis(InfoflowCFG icfg, IDebugger debugger) { 15 | super(new VectorStateMachine(icfg), icfg, debugger); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /typestate/typestate/impl/vector/VectorStateMachine.java: -------------------------------------------------------------------------------- 1 | package typestate.impl.vector; 2 | 3 | import java.util.Collection; 4 | import java.util.Collections; 5 | import java.util.HashSet; 6 | import java.util.LinkedList; 7 | import java.util.List; 8 | import java.util.Set; 9 | import java.util.regex.Pattern; 10 | 11 | import boomerang.accessgraph.AccessGraph; 12 | import heros.EdgeFunction; 13 | import heros.solver.Pair; 14 | import soot.Local; 15 | import soot.Scene; 16 | import soot.SootClass; 17 | import soot.SootMethod; 18 | import soot.Unit; 19 | import soot.jimple.InstanceInvokeExpr; 20 | import soot.jimple.Stmt; 21 | import soot.jimple.infoflow.solver.cfg.InfoflowCFG; 22 | import typestate.TransitionFunction; 23 | import typestate.TypestateChangeFunction; 24 | import typestate.TypestateDomainValue; 25 | import typestate.finiteautomata.MatcherStateMachine; 26 | import typestate.finiteautomata.MatcherTransition; 27 | import typestate.finiteautomata.MatcherTransition.Parameter; 28 | import typestate.finiteautomata.MatcherTransition.Type; 29 | import typestate.finiteautomata.State; 30 | import typestate.finiteautomata.Transition; 31 | 32 | public class VectorStateMachine extends MatcherStateMachine implements TypestateChangeFunction { 33 | 34 | private MatcherTransition initialTrans; 35 | private InfoflowCFG icfg; 36 | 37 | public static enum States implements State { 38 | NONE, INIT, NOT_EMPTY, ACCESSED_EMPTY; 39 | 40 | @Override 41 | public boolean isErrorState() { 42 | return this == ACCESSED_EMPTY; 43 | } 44 | 45 | @Override 46 | public boolean isInitialState() { 47 | return this == INIT; 48 | } 49 | } 50 | 51 | VectorStateMachine(InfoflowCFG icfg) { 52 | this.icfg = icfg; 53 | initialTrans = new MatcherTransition(States.NONE, vectorConstructor(), Parameter.This,States.INIT, Type.OnReturn); 54 | addTransition(initialTrans); 55 | addTransition(new MatcherTransition(States.INIT, addElement(), Parameter.This, States.NOT_EMPTY, Type.OnReturn)); 56 | addTransition(new MatcherTransition(States.INIT, accessElement(), Parameter.This,States.ACCESSED_EMPTY, Type.OnReturn)); 57 | addTransition(new MatcherTransition(States.NOT_EMPTY, removeAllElements(), Parameter.This, States.INIT, Type.OnReturn)); 58 | addTransition(new MatcherTransition(States.INIT, removeAllElements(),Parameter.This, States.INIT, Type.OnReturn)); 59 | addTransition( 60 | new MatcherTransition(States.ACCESSED_EMPTY, accessElement(), Parameter.This,States.ACCESSED_EMPTY, Type.OnReturn)); 61 | } 62 | @Override 63 | public boolean seedInApplicationClass() { 64 | return true; 65 | } 66 | private Set removeAllElements() { 67 | List vectorClasses = getSubclassesOf("java.util.Vector"); 68 | Set selectMethodByName = selectMethodByName(vectorClasses, "removeAllElements"); 69 | return selectMethodByName; 70 | } 71 | 72 | private Set vectorConstructor() { 73 | List subclasses = getSubclassesOf("java.util.Vector"); 74 | Set out = new HashSet<>(); 75 | for (SootClass c : subclasses) { 76 | for (SootMethod m : c.getMethods()) 77 | if (m.isConstructor() 78 | && !m.getSignature().equals("(java.util.Collection)>")) 79 | out.add(m); 80 | } 81 | return out; 82 | } 83 | 84 | private Set addElement() { 85 | List vectorClasses = getSubclassesOf("java.util.Vector"); 86 | Set selectMethodByName = selectMethodByName(vectorClasses, 87 | "add|addAll|addElement|insertElementAt|set|setElementAt"); 88 | return selectMethodByName; 89 | } 90 | 91 | private Set accessElement() { 92 | List vectorClasses = getSubclassesOf("java.util.Vector"); 93 | Set selectMethodByName = selectMethodByName(vectorClasses, 94 | "elementAt|firstElement|lastElement|get"); 95 | return selectMethodByName; 96 | } 97 | 98 | 99 | @Override 100 | public Collection>> generate(Unit unit, 101 | Collection calledMethod) { 102 | boolean matches = false; 103 | for (SootMethod method : calledMethod) { 104 | if (initialTrans.matches(method) && !initialTrans.matches(icfg.getMethodOf(unit))) { 105 | matches = true; 106 | } 107 | } 108 | if (!matches || icfg.getMethodOf(unit).getSignature().equals("()>")) 109 | return Collections.emptySet(); 110 | if (unit instanceof Stmt) { 111 | Stmt stmt = (Stmt) unit; 112 | if (stmt.containsInvokeExpr()) 113 | if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { 114 | InstanceInvokeExpr iie = (InstanceInvokeExpr) stmt.getInvokeExpr(); 115 | if (iie.getBase() instanceof Local) { 116 | Local l = (Local) iie.getBase(); 117 | Set>> out = new HashSet<>(); 118 | out.add(new Pair>( 119 | new AccessGraph(l, l.getType()), new TransitionFunction(initialTrans))); 120 | return out; 121 | } 122 | } 123 | } 124 | return Collections.emptySet(); 125 | } 126 | } 127 | --------------------------------------------------------------------------------