diff --git a/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java b/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java index c50c1cf3..f1003325 100644 --- a/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java +++ b/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java @@ -7,7 +7,7 @@ import soot.jimple.InvokeStmt; import soot.jimple.StaticFieldRef; -import java.util.*; +import java.util.Objects; /** * Information wee keep while traversing @@ -99,4 +99,9 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(local, stmt); } + + @Override + public String toString() { + return "DataFlowAbstraction{ " + stmt + "}"; + } } diff --git a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java index 0fb32b01..87120cc9 100644 --- a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java +++ b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java @@ -9,10 +9,13 @@ import br.unb.cic.exceptions.ValueNotHandledException; import soot.*; import soot.jimple.*; +import soot.jimple.internal.JAssignStmt; +import soot.jimple.internal.JimpleLocal; import soot.jimple.toolkits.callgraph.CallGraph; import soot.jimple.toolkits.callgraph.Edge; import soot.toolkits.scalar.ArraySparseSet; import soot.toolkits.scalar.FlowSet; +import soot.util.Chain; import java.util.*; import java.util.logging.Level; @@ -59,28 +62,16 @@ public Set getConflicts() { @Override protected void internalTransform(String s, Map map) { - long tempoInicial = System.currentTimeMillis(); + long startTime = System.currentTimeMillis(); List methods = Scene.v().getEntryPoints(); methods.forEach(sootMethod -> traverse(new ArraySparseSet<>(), sootMethod, Statement.Type.IN_BETWEEN)); Set conflictsFilter = filterConflicts(getConflicts()); - conflictsFilter.forEach(conflict -> logger.log(Level.INFO, conflict.toStringAbstract())); - logger.log(Level.INFO, () -> String.format("%s", "CONFLICTS: " + conflictsFilter)); - long tempoFinal = System.currentTimeMillis(); - System.out.println("Tempo de execução de: " + ((tempoFinal - tempoInicial) / 1000d) + "s"); - - /* left.forEach(dataFlowAbstraction -> { - String leftStmt = String.format("%s", "LEFT: " + dataFlowAbstraction.getStmt()); - logger.log(Level.INFO, leftStmt); - }); - - right.forEach(dataFlowAbstraction -> { - String rightStmt = String.format("%s", "RIGHT: " + dataFlowAbstraction.getStmt()); - logger.log(Level.INFO, rightStmt); - }); */ + long finalTime = System.currentTimeMillis(); + System.out.println("Runtime: " + ((finalTime - startTime) / 1000d) + "s"); } public void configureEntryPoints() { @@ -121,9 +112,13 @@ private Set filterConflicts(Set conflictsResults) { } for (Conflict conflict : conflictsResults) { for (Conflict filter : conflictsFilter) { - if ((!conflict.getSourceTraversedLine().get(0).equals(filter.getSourceTraversedLine().get(0))) && (!conflict.getSinkTraversedLine().get(0).equals(filter.getSinkTraversedLine().get(0)))) { - conflictsFilter.add(conflict); + if (!conflict.getSourceTraversedLine().isEmpty() && !conflict.getSinkTraversedLine().isEmpty()) { + if ((!conflict.getSourceTraversedLine().get(0).equals(filter.getSourceTraversedLine().get(0))) + && (!conflict.getSinkTraversedLine().get(0).equals(filter.getSinkTraversedLine().get(0)))) { + conflictsFilter.add(conflict); + } } + } } return conflictsFilter; @@ -141,7 +136,7 @@ private Set filterConflicts(Set conflictsResults) { private FlowSet traverse(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag) { - if (this.traversedMethods.contains(sootMethod) || this.traversedMethods.size() > 10 || sootMethod.isPhantom()) { + if (this.traversedMethods.contains(sootMethod) || this.traversedMethods.size() > 2 || sootMethod.isPhantom()) { return in; } @@ -151,6 +146,7 @@ private FlowSet traverse(FlowSet in, S Body body = definition.retrieveActiveBodySafely(sootMethod); if (body != null) { + handleConstructor(in, sootMethod, flowChangeTag); for (Unit unit : body.getUnits()) { TraversedLine traversedLine = new TraversedLine(sootMethod, unit.getJavaSourceStartLineNumber()); @@ -169,6 +165,42 @@ private FlowSet traverse(FlowSet in, S return in; } + private void handleConstructor(FlowSet in, SootMethod sootMethod, + Statement.Type flowChangeTag) { + if (sootMethod.isConstructor()) { + Chain sootFieldsInClass = sootMethod.getDeclaringClass().getFields(); + + sootFieldsInClass.forEach(sootField -> { + trasformFieldsIntoStatements(in, sootMethod, flowChangeTag, sootField); + }); + } + } + + private void trasformFieldsIntoStatements(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag, SootField sootField) { + String declaringClassShortName = sootField.getDeclaringClass().getShortName(); + String formatName = + declaringClassShortName.substring(0, 1).toLowerCase() + declaringClassShortName.substring(1); + + JimpleLocal base = new JimpleLocal(formatName, RefType.v(sootField.getDeclaringClass())); + SootFieldRef fieldRef = Scene.v().makeFieldRef(sootField.getDeclaringClass(), + sootField.getName(), sootField.getType(), sootField.isStatic()); + + Value value = getValue(base, fieldRef); + Unit unit = new JAssignStmt(value, NullConstant.v()); + createAndAddStmt(in, sootMethod, flowChangeTag, unit); + + } + + private Value getValue(JimpleLocal base, SootFieldRef fieldRef) { + Value value; + if (fieldRef.isStatic()) { + value = Jimple.v().newStaticFieldRef(fieldRef); + } else { + value = Jimple.v().newInstanceFieldRef(base, fieldRef); + } + return value; + } + private FlowSet runAnalysisWithTaggedUnit(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag, Unit unit) { return runAnalysis(in, sootMethod, flowChangeTag, unit, true); @@ -207,10 +239,7 @@ private FlowSet runAnalysis(FlowSet in separeteAbstraction(in); if (tagged) { - Statement stmt = getStatementAssociatedWithUnit(sootMethod, unit, flowChangeTag); - stmt.setTraversedLine(new ArrayList<>(this.stacktraceList)); - // logger.log(Level.INFO, () -> String.format("%s", "stmt: " + stmt.toString())); - gen(in, stmt); + createAndAddStmt(in, sootMethod, flowChangeTag, unit); } else { kill(in, unit); } @@ -239,6 +268,12 @@ In this case, this condition will be executed for the call to the foo() method a return in; } + private void createAndAddStmt(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag, Unit unit) { + Statement stmt = getStatementAssociatedWithUnit(sootMethod, unit, flowChangeTag); + stmt.setTraversedLine(new ArrayList<>(this.stacktraceList)); + gen(in, stmt); + } + private void separeteAbstraction(FlowSet in) { in.forEach(item -> { if (item.getStmt().isLefAndRightStatement()) { @@ -269,11 +304,16 @@ private FlowSet executeCallGraph(FlowSet flowSetUnion = new ArraySparseSet<>(); for (FlowSet flowSet : flowSetList) { flowSetUnion.union(flowSet); } + if (flowSetUnion.isEmpty()) { + return in; + } + return flowSetUnion; } @@ -348,11 +388,6 @@ private void removeAll(ValueBox valueBox, FlowSet rightOrLe rightOrLeftList.forEach(dataFlowAbstraction -> { try { if (containsValue(dataFlowAbstraction, valueBox.getValue())) { - rightOrLeftList.forEach(dt -> { - if (dt.getStmt().getSourceCodeLineNumber().equals(dataFlowAbstraction.getStmt().getSourceCodeLineNumber())) { - rightOrLeftList.remove(dt); - } - }); rightOrLeftList.remove(dataFlowAbstraction); } } catch (ValueNotHandledException e) { @@ -363,7 +398,7 @@ private void removeAll(ValueBox valueBox, FlowSet rightOrLe private boolean containsValue(DataFlowAbstraction dataFlowAbstraction, Value value) throws ValueNotHandledException { if (dataFlowAbstraction.getValue() instanceof InstanceFieldRef && value instanceof InstanceFieldRef) { - return ((InstanceFieldRef) dataFlowAbstraction.getValue()).getFieldRef().equals(((InstanceFieldRef) value).getFieldRef()); + return ((InstanceFieldRef) dataFlowAbstraction.getValue()).getFieldRef().getSignature().equals(((InstanceFieldRef) value).getFieldRef().getSignature()); } if (dataFlowAbstraction.getValue() instanceof Local && value instanceof Local) { return dataFlowAbstraction.getValue().equals(value); @@ -372,7 +407,7 @@ private boolean containsValue(DataFlowAbstraction dataFlowAbstraction, Value val return dataFlowAbstraction.getValue().equals(value); } if (dataFlowAbstraction.getValue() instanceof StaticFieldRef && value instanceof StaticFieldRef) { - return ((StaticFieldRef) dataFlowAbstraction.getValue()).getField().getName().equals(((StaticFieldRef) value).getField().getName()); + return ((StaticFieldRef) dataFlowAbstraction.getValue()).getFieldRef().getSignature().equals(((StaticFieldRef) value).getFieldRef().getSignature()); } if (!dataFlowAbstraction.getValue().getClass().equals(value.getClass())) { return false; diff --git a/src/main/java/br/unb/cic/analysis/model/Conflict.java b/src/main/java/br/unb/cic/analysis/model/Conflict.java index fcedbbcf..d73c1e8c 100644 --- a/src/main/java/br/unb/cic/analysis/model/Conflict.java +++ b/src/main/java/br/unb/cic/analysis/model/Conflict.java @@ -110,11 +110,17 @@ public int hashCode() { public String toStringAbstract() { - return String.format("source(%s, %s, %d, %s, %s) => sink(%s, %s, %d, %s, %s)", sourceTraversedLine.get(0).getSootClass(), - sourceTraversedLine.get(0).getSootMethod(), sourceTraversedLine.get(0).getLineNumber(), sourceUnit, + if (!sourceTraversedLine.isEmpty() && !sinkTraversedLine.isEmpty()) { + return String.format("source(%s, %s, %d, %s, %s) => sink(%s, %s, %d, %s, %s)", sourceTraversedLine.get(0).getSootClass(), + sourceTraversedLine.get(0).getSootMethod(), sourceTraversedLine.get(0).getLineNumber(), sourceUnit, + sourceTraversedLine, + sinkTraversedLine.get(0).getSootClass(), sinkTraversedLine.get(0).getSootMethod(), + sinkTraversedLine.get(0).getLineNumber(), sinkUnit, sinkTraversedLine); + } + return String.format("source(%s, %s) => sink(%s, %s)", sourceUnit, sourceTraversedLine, - sinkTraversedLine.get(0).getSootClass(), sinkTraversedLine.get(0).getSootMethod(), - sinkTraversedLine.get(0).getLineNumber(), sinkUnit, sinkTraversedLine); + sinkUnit, sinkTraversedLine); + }