@Override public void caseReturnStmt(ReturnStmt stmt) { //in case of return CONSTANT, we do nothing; unfortunately, this is part of FlowDroid's path if(stmt.getOp() instanceof Constant) return; int index = jimpleDataFlowStatements.indexOf(stmt); AccessPath ap = accessPathPath.get(index); Local local = ap.getPlainValue(); SMTBinding lhs = createNewBindingForValue(local); addValueBindingToVariableDeclaration(local, lhs); if(!hasBindingForValue(stmt.getOp())) throw new RuntimeException("There has to be a tainted value"); SMTBinding rhs = getLatestBindingForValue(stmt.getOp()); SMTSimpleAssignment simpleAss = new SMTSimpleAssignment(lhs, new SMTBindingValue(rhs)); SMTAssertStatement assertStmt = new SMTAssertStatement(simpleAss); addAssertStmtToAllPrograms(assertStmt); }
private ResultSourceInfo findDataFlowPathForSink(Stmt sinkStmt, Local sinkLokal, List<ResultSourceInfo> allDataFlows) { for(ResultSourceInfo singleFlow : allDataFlows){ Stmt[] statements = singleFlow.getPath(); AccessPath[] accessPath = singleFlow.getPathAccessPaths(); for(int i = 0; i < statements.length; i++) { Stmt currentStmt = statements[i]; if(currentStmt == sinkStmt) { if(accessPath[i].getPlainValue() == sinkLokal) return singleFlow; } else if(currentStmt instanceof AssignStmt) { AssignStmt assignStmt = (AssignStmt)currentStmt; Value lhs = assignStmt.getLeftOp(); if(lhs == sinkLokal) return singleFlow; } } } return null; }
/** * Checks whether the given access path matches the given definition * @param sourceAccessPath The access path to check * @param apt The definition against which to check the access path * @return True if the given access path matches the given definition, * otherwise false */ private boolean accessPathMatches(AccessPath sourceAccessPath, AccessPathTuple apt) { // If the source or sink definitions does not specify any fields, it // always matches if (apt.getFields() == null || apt.getFields().length == 0 || sourceAccessPath == null) return true; for (int i = 0; i < apt.getFields().length; i++) { // If a.b.c.* is our defined sink and a.b is tainted, this is not a // leak. If a.b.* is tainted, it is. if (i >= sourceAccessPath.getFieldCount()) return sourceAccessPath.getTaintSubFields(); // Compare the fields if (!sourceAccessPath.getFields()[i].getName().equals(apt.getFields()[i])) return false; } return true; }
/** * Gets whether two values may potentially point to the same runtime object * @param val1 The first value * @param val2 The second value * @return True if the two values may potentially point to the same runtime * object, otherwise false */ public boolean mayAlias(Value val1, Value val2) { // What cannot be represented in an access path cannot alias if (!AccessPath.canContainValue(val1) || !AccessPath.canContainValue(val2)) return false; // Constants can never alias if (val1 instanceof Constant || val2 instanceof Constant) return false; // If the two values are equal, they alias by definition if (val1 == val2) return true; // If we have an interactive aliasing algorithm, we check that as well if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(new AccessPath(val1, false), new AccessPath(val2, false)); return false; }
@Override public void computeAliasTaints(Abstraction d1, Stmt src, Value targetValue, Set<Abstraction> taintSet, SootMethod method, Abstraction newAbs) { // Use global aliasing Value baseValue = ((InstanceFieldRef) targetValue).getBase(); Set<AccessPath> aliases = methodToAliases.getUnchecked(method).get (new AccessPath(baseValue, true)); if (aliases != null) for (AccessPath ap : aliases) { Abstraction aliasAbs = newAbs.deriveNewAbstraction( ap.merge(newAbs.getAccessPath()), null); if (taintSet.add(aliasAbs)) // We have found a new alias. This new base object may however yet // again alias with something, so we need to check again if (ap.isInstanceFieldRef()) { InstanceFieldRef aliasBaseVal = Jimple.v().newInstanceFieldRef (ap.getPlainValue(), ap.getFirstField().makeRef()); computeAliasTaints(d1, src, aliasBaseVal, taintSet, method, aliasAbs); } } }
@Override public Set<Abstraction> getTaintsForMethod(Stmt stmt, Abstraction d1, Abstraction taintedPath) { // Compute the tainted access paths Set<AccessPath> aps = getTaintsForMethodInternal(stmt, taintedPath.getAccessPath()); if (aps == null || aps.isEmpty()) return null; // Convert the access paths into full abstractions Set<Abstraction> res = new HashSet<Abstraction>(aps.size()); for (AccessPath ap : aps) if (ap == taintedPath.getAccessPath()) res.add(taintedPath); else res.add(taintedPath.deriveNewAbstraction(ap, stmt)); return res; }
@Override public boolean isExclusiveInternal(Stmt stmt, AccessPath taintedPath) { SootMethod method = stmt.getInvokeExpr().getMethod(); // Do we have an entry for at least one entry in the given class? if (hasWrappedMethodsForClass(method.getDeclaringClass(), true, true, true)) return true; // In aggressive mode, we always taint the return value if the base // object is tainted. if (aggressiveMode && stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iiExpr.getBase().equals(taintedPath.getPlainValue())) return true; } final MethodWrapType wrapType = methodWrapCache.getUnchecked(method); return wrapType != MethodWrapType.NotRegistered; }
@Override public boolean isExclusiveInternal(Stmt stmt, AccessPath taintedPath) { assert stmt.containsInvokeExpr(); // We are exclusive if the base object is tainted if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (taintedPath.getPlainValue().equals(iiExpr.getBase())) return true; } // If one parameter is tainted, we are exclusive as well for (Value param : stmt.getInvokeExpr().getArgs()) if (taintedPath.getPlainValue().equals(param)) return true; return false; }
@Override public boolean isSink(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg, AccessPath ap) { // Check whether values returned by the current method are to be // considered as sinks if (this.returnTaintMethods != null && sCallSite instanceof ReturnStmt && this.returnTaintMethods.contains(cfg.getMethodOf(sCallSite).getSignature())) return true; // Check whether the callee is a sink if (this.sinks != null && sCallSite.containsInvokeExpr() && this.sinks.contains(sCallSite.getInvokeExpr().getMethod().getSignature())) return true; return false; }
@Override public void computeAliasTaints(Abstraction d1, Stmt src, Value targetValue, Set<Abstraction> taintSet, SootMethod method, Abstraction newAbs) { // If we don't have an alias set for this method yet, we compute it if (!globalAliases.containsRow(method)) computeGlobalAliases(method); // Use global aliasing Value baseValue = ((InstanceFieldRef) targetValue).getBase(); Set<AccessPath> aliases = globalAliases.get(method, new AccessPath( baseValue)); if (aliases != null) for (AccessPath ap : aliases) { Abstraction aliasAbs = newAbs.deriveNewAbstraction( ap.merge(newAbs.getAccessPath()), src); taintSet.add(aliasAbs); } }
@Override public Set<AccessPath> getTaintsForMethod(Stmt stmt, AccessPath taintedPath) { // method add + added element is tainted -> whole list is tainted if(stmt.getInvokeExpr().getMethod().getSubSignature().equals("boolean add(java.lang.Object)")) if (taintedPath.getPlainValue().equals(stmt.getInvokeExpr().getArg(0))) return Collections.singleton(new AccessPath(((InstanceInvokeExpr) stmt.getInvokeExprBox().getValue()).getBase())); // method get + whole list is tainted -> returned element is tainted if(stmt.getInvokeExpr().getMethod().getSubSignature().equals("java.lang.Object get(int)")) if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (taintedPath.getPlainValue().equals(iiExpr.getBase())) if(stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp())); } // For the moment, we don't implement static taints on wrappers. Pass it on // not to break anything if(taintedPath.isStaticFieldRef()) return Collections.singleton(taintedPath); return Collections.emptySet(); }
@Override public Set<AccessPath> getTaintsForMethod(Stmt stmt, AccessPath taintedPath) { assert stmt.containsInvokeExpr(); // For the moment, we don't implement static taints on wrappers. Pass it on // not to break anything if(taintedPath.isStaticFieldRef()) return Collections.singleton(taintedPath); if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); // If the base object is tainted, the return value is always tainted if (taintedPath.getPlainValue().equals(iiExpr.getBase())) if (stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp())); } // If one of the parameters is tainted, the return value is tainted, too for (Value param : stmt.getInvokeExpr().getArgs()) if (taintedPath.getPlainValue().equals(param)) if (stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp())); return Collections.emptySet(); }
/** * Gets whether two values may potentially point to the same runtime object * @param field1 The first value * @param field2 The second value * @return True if the two values may potentially point to the same runtime * object, otherwise false */ private boolean mayAlias(Value val1, Value val2) { // What cannot be represented in an access path cannot alias if (!AccessPath.canContainValue(val1) || !AccessPath.canContainValue(val2)) return false; // If the two values are equal, they alias by definition if (val1.equals(val2)) return true; // If we have an interactive aliasing algorithm, we check that as well if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(new AccessPath(val1), new AccessPath(val2)); return false; }
public JimpleStmtVisitorImpl(Set<SourceSinkDefinition> sources, List<Stmt> jimpleDataFlowStatements, List<AccessPath> accessPathPath, Set<Unit> targetUnits, IInfoflowCFG cfg, Table<List<Stmt>, Stmt, List<List<String>>> splitAPIElementInfos) { this.exprVisitor = new JimpleExprVisitorImpl(sources, this); this.jimpleDataFlowStatements = jimpleDataFlowStatements; this.accessPathPath = accessPathPath; this.targetUnits = targetUnits; this.cfg = cfg; this.splitAPIElementInfos = splitAPIElementInfos; this.smtPrograms = new HashSet<SMTProgram>(); //initial adding of a single SMTProgram currentSMTProgram = new SMTProgram(); smtPrograms.add(currentSMTProgram); }
public AccessPath getCorrectAccessPathForStmt(Stmt stmt) { for (int i = 0; i < this.jimpleDataFlowStatements.size(); i++) { if (this.jimpleDataFlowStatements.get(i) == stmt) return this.accessPathPath.get(i); } throw new RuntimeException("There should be a statement in the data flow path"); }
@Override public void caseStaticInvokeExpr(StaticInvokeExpr v) { //just propagate the taint value of previous statement Stmt prevStmt = stmtVisitor.getPreviousDataFlowPathElement(currentStatement); if(prevStmt == null) throw new RuntimeException("there is no previous statement"); else { //create an assignment between the incoming taint-value and the //assigned taint-value inside the method SMTBinding bindingPrevStmt = stmtVisitor.getBindingForTaintedValue(prevStmt); //if there is no taint-tracking involved, we do not have to create an SMT formula if(bindingPrevStmt == null) return; AccessPath accessPath = stmtVisitor.getCorrectAccessPathForStmt(currentStatement); Local identityStmtTaintValue = accessPath.getPlainValue(); SMTBinding bindingCurentStmt = stmtVisitor.getLatestBindingForValue(identityStmtTaintValue); if(bindingCurentStmt == null) { bindingCurentStmt = stmtVisitor.createNewBindingForValue(identityStmtTaintValue); stmtVisitor.addValueBindingToVariableDeclaration(identityStmtTaintValue, bindingCurentStmt); } if(bindingCurentStmt != bindingPrevStmt) { SMTSimpleAssignment simpleAssignForTaintProp = new SMTSimpleAssignment(bindingCurentStmt, new SMTBindingValue(bindingPrevStmt)); SMTAssertStatement simpleAssignAssert = new SMTAssertStatement(simpleAssignForTaintProp); stmtVisitor.addAssertStmtToAllPrograms(simpleAssignAssert); } this.result = bindingCurentStmt; } }
/** * Creates an access path from an access path definition object * @param baseVal The base for the new access path * @param apt The definition from which to create the new access path * @return The newly created access path */ private AccessPath getAccessPathFromDef(Value baseVal, AccessPathTuple apt) { if (baseVal.getType() instanceof PrimType || apt.getFields() == null || apt.getFields().length == 0) return new AccessPath(baseVal, true); SootClass baseClass = ((RefType) baseVal.getType()).getSootClass(); SootField[] fields = new SootField[apt.getFields().length]; for (int i = 0; i < fields.length; i++) fields[i] = baseClass.getFieldByName(apt.getFields()[i]); return new AccessPath(baseVal, fields, true); }
/** * Gets the points-to-set for the given access path * @param accessPath The access path for which to get the points-to-set * @return The points-to-set for the given access path */ private PointsToSet getPointsToSet(AccessPath accessPath) { if (accessPath.isLocal()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getPlainValue()); else if (accessPath.isInstanceFieldRef()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getPlainValue(), accessPath.getFirstField()); else if (accessPath.isStaticFieldRef()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getFirstField()); else throw new RuntimeException("Unexepected access path type"); }
/** * Gets whether an access path can point to the same runtime object as another * or to an object reachable through the other * @param taintedAP The access path that is tainted * @param referencedAP The access path that is accessed * @return The access path that actually matched if the access paths alias. * In the simplest case, this is the given tainted access path. * When using recursive access paths, it can however also be a base * expansion. If the given access paths do not alias, null is returned. */ public AccessPath mayAlias(AccessPath taintedAP, AccessPath referencedAP) { // Check whether the access paths are directly equal if (taintedAP.equals(referencedAP)) return taintedAP; // Ask an interactive aliasing strategy if we have one // TODO /* if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(taintedAP, referencedAP); */ if (taintedAP.isInstanceFieldRef() || taintedAP.isLocal()) { // For instance field references, the base must match if (taintedAP.getPlainValue() != referencedAP.getPlainValue()) return null; // Shortcut: If we have no fields and the base matches, we're done if (referencedAP.getFieldCount() == 0) return taintedAP; // If the referenced AP is not an instance field reference, we're done if (!referencedAP.isInstanceFieldRef()) return null; } // If one reference is static, the other one must be static as well if (taintedAP.isStaticFieldRef()) if (!referencedAP.isStaticFieldRef()) return null; // Match the bases return getReferencedAPBase(taintedAP, referencedAP.getFields()); }
/** * Computes the global non-flow-sensitive alias information for the given * method * @param method The method for which to compute the alias information */ private Map<AccessPath, Set<AccessPath>> computeGlobalAliases(SootMethod method) { Map<AccessPath, Set<AccessPath>> res = new HashMap<AccessPath, Set<AccessPath>>(); // Find the aliases for (Unit u : method.getActiveBody().getUnits()) { if (!(u instanceof AssignStmt)) continue; final AssignStmt assign = (AssignStmt) u; // Aliases can only be generated on the heap if (!(assign.getLeftOp() instanceof FieldRef && (assign.getRightOp() instanceof FieldRef || assign.getRightOp() instanceof Local))) if (!(assign.getRightOp() instanceof FieldRef && (assign.getLeftOp() instanceof FieldRef || assign.getLeftOp() instanceof Local))) continue; final AccessPath apLeft = new AccessPath(assign.getLeftOp(), true); final AccessPath apRight = new AccessPath(assign.getRightOp(), true); Set<AccessPath> mapLeft = res.get(apLeft); if (mapLeft == null) { mapLeft = new HashSet<AccessPath>(); res.put(apLeft, mapLeft); } mapLeft.add(apRight); Set<AccessPath> mapRight = res.get(apRight); if (mapRight == null) { mapRight = new HashSet<AccessPath>(); res.put(apRight, mapRight); } mapLeft.add(apLeft); } return res; }
/** * Explicitly handles String.getChars() which does not really fit our * declarative model * @param invokeExpr The invocation of String.getChars() * @param taintedPath The tainted access path * @return The set of new taints to pass on in the taint propagation */ private Set<AccessPath> handleStringGetChars(InvokeExpr invokeExpr, AccessPath taintedPath) { // If the base object is tainted, the third argument gets tainted as // well if (((InstanceInvokeExpr) invokeExpr).getBase() == taintedPath.getPlainValue()) return new TwoElementSet<AccessPath>(taintedPath, new AccessPath( invokeExpr.getArg(2), true)); return Collections.singleton(taintedPath); }
@Override public Set<AccessPath> getTaintsForMethodInternal(Stmt stmt, AccessPath taintedPath) { assert stmt.containsInvokeExpr(); // For the moment, we don't implement static taints on wrappers. Pass it on // not to break anything if(taintedPath.isStaticFieldRef()) return Collections.singleton(taintedPath); if (stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); // If the base object is tainted, the return value is always tainted if (taintedPath.getPlainValue().equals(iiExpr.getBase())) if (stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp(), taintedPath.getTaintSubFields())); } // If one of the parameters is tainted, the return value is tainted, too for (Value param : stmt.getInvokeExpr().getArgs()) if (taintedPath.getPlainValue().equals(param)) if (stmt instanceof JAssignStmt) return Collections.singleton(new AccessPath(((JAssignStmt)stmt).getLeftOp(), taintedPath.getTaintSubFields())); return Collections.emptySet(); }
protected boolean hasCompatibleTypesForCall(AccessPath apBase, SootClass dest) { if (!enableTypeChecking) return true; // Cannot invoke a method on a primitive type if (apBase.getBaseType() instanceof PrimType) return false; // Cannot invoke a method on an array if (apBase.getBaseType() instanceof ArrayType) return dest.getName().equals("java.lang.Object"); return Scene.v().getOrMakeFastHierarchy().canStoreType(apBase.getBaseType(), dest.getType()) || Scene.v().getOrMakeFastHierarchy().canStoreType(dest.getType(), apBase.getBaseType()); }
@Override public boolean isSink(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg, AccessPath ap) { assert sCallSite != null; return sCallSite.containsInvokeExpr() && isSinkMethod(sCallSite.getInvokeExpr().getMethod()); }
public void addResult(AccessPath sink, Stmt sinkStmt, AccessPath source, Stmt sourceStmt, Object userData, List<Stmt> propagationPath) { this.addResult(new ResultSinkInfo(sink, sinkStmt), new ResultSourceInfo(source, sourceStmt, userData, propagationPath)); }
public ResultSourceInfo(AccessPath source, Stmt context) { assert source != null; this.accessPath = source; this.source = context; this.userData = null; this.path = null; }
public ResultSourceInfo(AccessPath source, Stmt context, Object userData, List<Stmt> path) { assert source != null; this.accessPath = source; this.source = context; this.userData = userData; this.path = path; }
@Override public boolean isSink(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg, AccessPath ap) { if (!sCallSite.containsInvokeExpr()) return false; SootMethod target = sCallSite.getInvokeExpr().getMethod(); if (target.getSignature().equals(sink)) return true; if (target.getSignature().equals(sinkAP) && sCallSite.getInvokeExpr().getArgCount() > 0 && ap.getPlainValue() == sCallSite.getInvokeExpr().getArg(0)) return true; return false; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret")) { AccessPath ap = new AccessPath(((DefinitionStmt) sCallSite).getLeftOp(), true); return new SourceInfo(ap); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && (sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret") || (sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret2")))) { AccessPath ap = new AccessPath(((DefinitionStmt) sCallSite).getLeftOp(), true); return new SourceInfo(ap); } return null; }
@Override public SourceInfo getSourceInfo(Stmt sCallSite, InterproceduralCFG<Unit, SootMethod> cfg) { if (sCallSite.containsInvokeExpr() && sCallSite instanceof DefinitionStmt && sCallSite.getInvokeExpr().getMethod().getName().equals("getSecret")) { AccessPath ap = new AccessPath(((DefinitionStmt) sCallSite).getLeftOp(), false); return new SourceInfo(ap); } return null; }
/** * Gets the points-to-set for the given access path * @param accessPath The access path for which to get the points-to-set * @return The points-to-set for the given access path */ private PointsToSet getPointsToSet(AccessPath accessPath) { if (accessPath.isLocal()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getPlainLocal()); else if (accessPath.isInstanceFieldRef()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getPlainLocal(), accessPath.getFirstField()); else if (accessPath.isStaticFieldRef()) return Scene.v().getPointsToAnalysis().reachingObjects(accessPath.getFirstField()); else throw new RuntimeException("Unexepected access path type"); }
@Override public Set<AccessPath> getTaintsForMethod(Stmt stmt, AccessPath taintedPath) { Set<AccessPath> resList = new HashSet<AccessPath>(); for (ITaintPropagationWrapper w : this.wrappers) resList.addAll(w.getTaintsForMethod(stmt, taintedPath)); return new HashSet<AccessPath>(resList); }
@Override public boolean isExclusiveInternal(Stmt stmt, AccessPath taintedPath) { for (ITaintPropagationWrapper w : this.wrappers) if (w.isExclusive(stmt, taintedPath)) return true; return false; }
@Override public boolean isExclusive(Stmt stmt, AccessPath taintedPath) { if (isExclusiveInternal(stmt, taintedPath)) { wrapperHits.incrementAndGet(); return true; } else { wrapperMisses.incrementAndGet(); return false; } }
@Override public boolean isExclusiveInternal(Stmt stmt, AccessPath taintedPath) { SootMethod method = stmt.getInvokeExpr().getMethod(); // In aggressive mode, we always taint the return value if the base // object is tainted. if (aggressiveMode && stmt.getInvokeExpr() instanceof InstanceInvokeExpr) { InstanceInvokeExpr iiExpr = (InstanceInvokeExpr) stmt.getInvokeExpr(); if (iiExpr.getBase().equals(taintedPath.getPlainValue())) return true; } return hasMethodsForClass(method.getDeclaringClass()); }
/** * Gets whether two fields may potentially point to the same runtime object * @param field1 The first field * @param field2 The second field * @return True if the two fields may potentially point to the same runtime * object, otherwise false */ private boolean mayAlias(SootField field1, SootField field2) { if (field1.equals(field2)) return true; if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(new AccessPath(field1), new AccessPath(field2)); return false; }
/** * Gets whether two access paths may potentially point to the same runtime object * @param ap1 The first access path * @param ap2 The second access path * @return True if the two access paths may potentially point to the same runtime * object, otherwise false */ private boolean mayAlias(AccessPath ap1, AccessPath ap2) { if (ap1.equals(ap2)) return true; if (aliasingStrategy.isInteractive()) return aliasingStrategy.mayAlias(ap1, ap2); return false; }
private static ResultSourceInfo mergeDataFlowsIntoSingleDataFlow(Stmt statementToEnrich, ResultSourceInfo originalPath, ResultSourceInfo pathToMerge) { List<Stmt> pathStmts = new ArrayList<Stmt>(Arrays.asList(originalPath.getPath())); List<AccessPath> accessPaths = new ArrayList<AccessPath>(Arrays.asList(originalPath.getPathAccessPaths())); List<Stmt> pathToMergeStmts = new ArrayList<Stmt>(Arrays.asList(pathToMerge.getPath())); List<AccessPath> pathToMergeAccessPaths = new ArrayList<AccessPath>(Arrays.asList(pathToMerge.getPathAccessPaths())); int index = pathStmts.indexOf(statementToEnrich); // if(index < 0) // throw new RuntimeException("Woops, there is something wonkey here"); // // for(int i = 0; i < pathToMergeStmts.size(); i++) { // pathStmts.add(index, pathToMergeStmts.get(i)); // accessPaths.add(index, pathToMergeAccessPaths.get(i)); // index +=1; // } List<Pair<Stmt,AccessPath>> dataToMerge = new ArrayList<Pair<Stmt,AccessPath>>(); int position; for(position = 0; position < pathToMergeStmts.size(); position++) { if(pathStmts.contains(pathToMergeStmts.get(position)) && !dataToMerge.isEmpty()) { int indexToInsertBefore = pathStmts.indexOf(pathToMergeStmts.get(position)); indexToInsertBefore -= 1; // for(Pair<Stmt,AccessPath> pair : dataToMerge) { // pathStmts.add(indexToInsertBefore, pair.getFirst()); // accessPaths.add(indexToInsertBefore, pair.getSecond()); // ++indexToInsertBefore; // } } else if(!pathStmts.contains(pathToMergeStmts.get(position))) { dataToMerge.add(new Pair<Stmt,AccessPath>(pathToMergeStmts.get(position), pathToMergeAccessPaths.get(position))); } } if(!dataToMerge.isEmpty()) { for(Pair<Stmt,AccessPath> pair : dataToMerge) { pathStmts.add(index, pair.getFirst()); accessPaths.add(index, pair.getSecond()); ++index; } } return new ResultSourceInfo(accessPaths.get(0), pathStmts.get(0), null, pathStmts, accessPaths); }