Skip to content

Commit ed319ee

Browse files
authored
Merge pull request #553 from MarcMil/fix-stackoverflow
Fix stack overflow in buildFullPathFromCache
2 parents 27b642d + bea24d8 commit ed319ee

1 file changed

Lines changed: 35 additions & 24 deletions

File tree

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

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.HashSet;
44
import java.util.Set;
5+
import java.util.Stack;
56
import java.util.concurrent.PriorityBlockingQueue;
67
import java.util.concurrent.ThreadFactory;
78
import java.util.concurrent.TimeUnit;
@@ -60,7 +61,6 @@ public Thread newThread(Runnable r) {
6061
return executor;
6162
}
6263

63-
6464
/**
6565
* Task for tracking back the path from sink to source.
6666
*
@@ -96,27 +96,29 @@ public void run() {
9696
private void processAndQueue(Abstraction pred, SourceContextAndPath scap) {
9797
// Skip abstractions that don't contain any new information. This might
9898
// be the case when a turn unit was added to the abstraction.
99-
if (pred.getCorrespondingCallSite() == null && pred.getCurrentStmt() == null && pred.getTurnUnit() != null) {
99+
if (pred.getCorrespondingCallSite() == null && pred.getCurrentStmt() == null
100+
&& pred.getTurnUnit() != null) {
100101
processAndQueue(pred.getPredecessor(), scap);
101102
return;
102103
}
103104

104105
ProcessingResult p = processPredecessor(scap, pred);
105106
switch (p.getResult()) {
106-
case NEW:
107-
// Schedule the predecessor
108-
assert pathCache.containsKey(pred);
109-
scheduleDependentTask(new SourceFindingTask(pred));
110-
break;
111-
case CACHED:
112-
// In case we already know the subpath, we do append the path after the path builder terminated
113-
deferredPaths.add(new Pair<>(scap, p.getScap()));
114-
break;
115-
case INFEASIBLE_OR_MAX_PATHS_REACHED:
116-
// Nothing to do
117-
break;
118-
default:
119-
assert false;
107+
case NEW:
108+
// Schedule the predecessor
109+
assert pathCache.containsKey(pred);
110+
scheduleDependentTask(new SourceFindingTask(pred));
111+
break;
112+
case CACHED:
113+
// In case we already know the subpath, we do append the path after the path
114+
// builder terminated
115+
deferredPaths.add(new Pair<>(scap, p.getScap()));
116+
break;
117+
case INFEASIBLE_OR_MAX_PATHS_REACHED:
118+
// Nothing to do
119+
break;
120+
default:
121+
assert false;
120122
}
121123
}
122124

@@ -129,7 +131,8 @@ private ProcessingResult processPredecessor(SourceContextAndPath scap, Abstracti
129131
return ProcessingResult.INFEASIBLE_OR_MAX_PATHS_REACHED();
130132

131133
checkForSource(pred, extendedScap);
132-
return pathCache.put(pred, extendedScap) ? ProcessingResult.NEW() : ProcessingResult.CACHED(extendedScap);
134+
return pathCache.put(pred, extendedScap) ? ProcessingResult.NEW()
135+
: ProcessingResult.CACHED(extendedScap);
133136
}
134137

135138
// If we enter a method, we put it on the stack
@@ -295,13 +298,21 @@ public void computeTaintPaths(Set<AbstractionAtSink> res) {
295298
*/
296299
protected void buildFullPathFromCache(SourceContextAndPath scap, SourceContextAndPath cachedScap) {
297300
// Try to extend scap with cachedScap
298-
SourceContextAndPath extendedScap = scap.extendPath(cachedScap);
299-
if (extendedScap != null) {
300-
Abstraction last = extendedScap.getLastAbstraction();
301-
// Try to build the path further using the cache if we didn't reach a source
302-
if (!checkForSource(last, extendedScap))
303-
for (SourceContextAndPath preds : pathCache.get(last.getPredecessor()))
304-
buildFullPathFromCache(extendedScap, preds);
301+
Stack<Pair<SourceContextAndPath, SourceContextAndPath>> workStack = new Stack<>();
302+
workStack.push(new Pair<>(scap, cachedScap));
303+
while (!workStack.isEmpty()) {
304+
Pair<SourceContextAndPath, SourceContextAndPath> p = workStack.pop();
305+
scap = p.getO1();
306+
cachedScap = p.getO2();
307+
308+
SourceContextAndPath extendedScap = scap.extendPath(cachedScap);
309+
if (extendedScap != null) {
310+
Abstraction last = extendedScap.getLastAbstraction();
311+
// Try to build the path further using the cache if we didn't reach a source
312+
if (!checkForSource(last, extendedScap))
313+
for (SourceContextAndPath preds : pathCache.get(last.getPredecessor()))
314+
workStack.push(new Pair<>(extendedScap, preds));
315+
}
305316
}
306317
}
307318

0 commit comments

Comments
 (0)