Skip to content

Commit 16d9c66

Browse files
committed
Fix path appending from cache
1 parent e22318a commit 16d9c66

2 files changed

Lines changed: 26 additions & 46 deletions

File tree

soot-infoflow/src/soot/jimple/infoflow/data/SourceContextAndPath.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package soot.jimple.infoflow.data;
22

3-
import java.util.ArrayList;
4-
import java.util.Collections;
5-
import java.util.Iterator;
6-
import java.util.List;
3+
import java.util.*;
74

85
import heros.solver.Pair;
96
import soot.jimple.Stmt;
@@ -90,19 +87,19 @@ public SourceContextAndPath extendPath(SourceContextAndPath other) {
9087
if (this.path == null || other.path == null || other.path.size() <= this.path.size())
9188
return null;
9289

93-
ArrayList<Abstraction> buf = new ArrayList<>(other.path.size() - this.path.size());
90+
Stack<Abstraction> pathStack = new Stack<>();
9491
Abstraction lastAbs = this.getLastAbstraction();
9592
boolean foundCommonAbs = false;
9693

9794
// Collect all additional abstractions on the cached path
9895
Iterator<Abstraction> pathIt = other.path.reverseIterator();
9996
while (pathIt.hasNext()) {
10097
Abstraction next = pathIt.next();
101-
if (next == lastAbs) {
98+
if (next == lastAbs || (next.neighbors != null && next.neighbors.contains(lastAbs))) {
10299
foundCommonAbs = true;
103100
break;
104101
}
105-
buf.add(next);
102+
pathStack.push(next);
106103
}
107104

108105
// If the paths do not have a common abstraction, there's probably something wrong...
@@ -111,15 +108,15 @@ public SourceContextAndPath extendPath(SourceContextAndPath other) {
111108

112109
// Append the additional abstractions to the new taint propagation path
113110
SourceContextAndPath extendedScap = clone();
114-
for (Abstraction abs : buf)
115-
extendedScap.path.add(abs);
111+
while (!pathStack.isEmpty())
112+
extendedScap.path.add(pathStack.pop());
116113

117114
int newCallStackCapacity = other.getCallStackSize() - this.getCallStackSize();
118115
// Sanity Check: The callStack of other should always be larger than the one of this
119116
if (newCallStackCapacity < 0)
120117
return null;
121118
if (newCallStackCapacity > 0) {
122-
ArrayList<Stmt> callStackBuf = new ArrayList<>(newCallStackCapacity);
119+
Stack<Stmt> callStackBuf = new Stack<>();
123120
Stmt topStmt = this.callStack == null ? null : this.callStack.getLast();
124121

125122
// Collect all additional statements on the call stack...
@@ -128,15 +125,15 @@ public SourceContextAndPath extendPath(SourceContextAndPath other) {
128125
Stmt next = callStackIt.next();
129126
if (next == topStmt)
130127
break;
131-
callStackBuf.add(next);
128+
callStackBuf.push(next);
132129
}
133130

134131
if (callStackBuf.size() > 0) {
135132
if (extendedScap.callStack == null)
136133
extendedScap.callStack = new ExtensibleList<>();
137134
// ...and append them.
138-
for (Stmt stmt : callStackBuf)
139-
extendedScap.callStack.add(stmt);
135+
while (!callStackBuf.isEmpty())
136+
extendedScap.callStack.add(callStackBuf.pop());
140137
}
141138
}
142139

soot-infoflow/src/soot/jimple/infoflow/data/pathBuilders/ContextSensitivePathBuilder.java

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ public class ContextSensitivePathBuilder extends ConcurrentAbstractionPathBuilde
3333
protected ConcurrentIdentityHashMultiMap<Abstraction, SourceContextAndPath> pathCache = new ConcurrentIdentityHashMultiMap<>();
3434

3535
// Set holds all paths that reach an already cached subpath
36-
protected ConcurrentHashSet<Pair<SourceContextAndPath, SourceContextAndPath>> deferredPaths = new ConcurrentHashSet<>();
36+
protected ConcurrentHashSet<SourceContextAndPath> deferredPaths = new ConcurrentHashSet<>();
37+
// Set holds all paths that reach a source
38+
protected ConcurrentHashSet<SourceContextAndPath> sourceReachingScaps = new ConcurrentHashSet<>();
3739

3840
/**
3941
* Creates a new instance of the {@link ContextSensitivePathBuilder} class
@@ -78,12 +80,6 @@ public void run() {
7880
final Set<SourceContextAndPath> paths = pathCache.get(abstraction);
7981
Abstraction pred = abstraction.getPredecessor();
8082

81-
// Skip abstractions that don't contain any new information. This might
82-
// be the case when a turn unit was added to the abstraction.
83-
while (pred != null && pred.getCurrentStmt() == null && pred.getCorrespondingCallSite() == null) {
84-
pred = pred.getPredecessor();
85-
}
86-
8783
if (pred != null && paths != null) {
8884
for (SourceContextAndPath scap : paths) {
8985
// Process the predecessor
@@ -110,7 +106,7 @@ private void processAndQueue(Abstraction pred, SourceContextAndPath scap) {
110106
case CACHED:
111107
// In case we already know the subpath, we do append the path after the path
112108
// builder terminated
113-
deferredPaths.add(new Pair<>(scap, p.getScap()));
109+
deferredPaths.add(scap);
114110
break;
115111
case INFEASIBLE_OR_MAX_PATHS_REACHED:
116112
// Nothing to do
@@ -128,7 +124,8 @@ private ProcessingResult processPredecessor(SourceContextAndPath scap, Abstracti
128124
if (extendedScap == null)
129125
return ProcessingResult.INFEASIBLE_OR_MAX_PATHS_REACHED();
130126

131-
checkForSource(pred, extendedScap);
127+
if (checkForSource(pred, extendedScap))
128+
sourceReachingScaps.add(extendedScap);
132129
return pathCache.put(pred, extendedScap) ? ProcessingResult.NEW()
133130
: ProcessingResult.CACHED(extendedScap);
134131
}
@@ -176,7 +173,8 @@ private ProcessingResult processPredecessor(SourceContextAndPath scap, Abstracti
176173
}
177174

178175
// Add the new path
179-
checkForSource(pred, extendedScap);
176+
if (checkForSource(pred, extendedScap))
177+
sourceReachingScaps.add(extendedScap);
180178

181179
final int maxPaths = config.getPathConfiguration().getMaxPathsPerAbstraction();
182180
if (maxPaths > 0) {
@@ -289,27 +287,14 @@ public void computeTaintPaths(Set<AbstractionAtSink> res) {
289287
}
290288

291289
/**
292-
* Uses the cached path to extend the current path
293-
*
294-
* @param scap SourceContextAndPath of the current abstraction
295-
* @param cachedScap cached SourceContextAndPath to extend scap
290+
* Tries to fill up deferred paths toward a source.
296291
*/
297-
protected void buildFullPathFromCache(SourceContextAndPath scap, SourceContextAndPath cachedScap) {
298-
// Try to extend scap with cachedScap
299-
Stack<Pair<SourceContextAndPath, SourceContextAndPath>> workStack = new Stack<>();
300-
workStack.push(new Pair<>(scap, cachedScap));
301-
while (!workStack.isEmpty()) {
302-
Pair<SourceContextAndPath, SourceContextAndPath> p = workStack.pop();
303-
scap = p.getO1();
304-
cachedScap = p.getO2();
305-
306-
SourceContextAndPath extendedScap = scap.extendPath(cachedScap);
307-
if (extendedScap != null) {
308-
Abstraction last = extendedScap.getLastAbstraction();
309-
// Try to build the path further using the cache if we didn't reach a source
310-
if (!checkForSource(last, extendedScap))
311-
for (SourceContextAndPath preds : pathCache.get(last.getPredecessor()))
312-
workStack.push(new Pair<>(extendedScap, preds));
292+
protected void buildPathsFromCache() {
293+
for (SourceContextAndPath deferredScap : deferredPaths) {
294+
for (SourceContextAndPath sourceScap : sourceReachingScaps) {
295+
SourceContextAndPath fullScap = deferredScap.extendPath(sourceScap);
296+
if (fullScap != null)
297+
checkForSource(fullScap.getLastAbstraction(), fullScap);
313298
}
314299
}
315300
}
@@ -318,9 +303,7 @@ protected void buildFullPathFromCache(SourceContextAndPath scap, SourceContextAn
318303
* Method that is called when the taint paths have been computed
319304
*/
320305
protected void onTaintPathsComputed() {
321-
for (Pair<SourceContextAndPath, SourceContextAndPath> deferredPair : deferredPaths) {
322-
buildFullPathFromCache(deferredPair.getO1(), deferredPair.getO2());
323-
}
306+
buildPathsFromCache();
324307
}
325308

326309
/**

0 commit comments

Comments
 (0)