diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..692f4aa1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +dist: trusty + +language: java + +jdk: + - oraclejdk8 diff --git a/README.md b/README.md old mode 100755 new mode 100644 index 4f398ccc..001dc7a0 --- a/README.md +++ b/README.md @@ -27,9 +27,7 @@ Current supported algorithms: To build the project, you will need Maven and Java 8 (or higher). -First, build and install the [svfa-scala](https://github.com/rbonifacio/svfa-scala) library. - -After that, run the following commands: +Clone the repository and than run the following commmand. ```SHELL mvn clean install -DskipTests diff --git a/pom.xml b/pom.xml index f0abc49e..079099e2 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,26 @@ 4.0.0 br.unb.cic soot-analysis - 0.0.5 + 0.0.6 + + + + spgroup + SPG Maven Repository (fork of the soot project) + https://maven.pkg.github.com/spgroup/soot/ + + + rbonifacio + Temporary repository for the SVFA library + https://maven.pkg.github.com/rbonifacio/svfa-scala/ + + + br.unb.cic svfa-scala_2.12 - 0.0.4-SNAPSHOT + 0.0.5 org.jgrapht 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 bc3665af..d3bd9190 100644 --- a/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java +++ b/src/main/java/br/unb/cic/analysis/df/DataFlowAbstraction.java @@ -2,6 +2,7 @@ import br.unb.cic.analysis.model.Statement; import soot.Local; +import soot.jimple.internal.JInstanceFieldRef; import java.util.Objects; @@ -12,6 +13,7 @@ public class DataFlowAbstraction { private Local local; + private JInstanceFieldRef localInstanceField; private Statement stmt; public DataFlowAbstraction(Local local, Statement stmt) { @@ -19,10 +21,19 @@ public DataFlowAbstraction(Local local, Statement stmt) { this.stmt = stmt; } + public DataFlowAbstraction(JInstanceFieldRef localInstanceField, Statement stmt) { + this.localInstanceField = localInstanceField; + this.stmt = stmt; + } + public Local getLocal() { return local; } + public JInstanceFieldRef getJInstanceFieldRef() { + return localInstanceField; + } + public Statement getStmt() { return stmt; } diff --git a/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysis.java b/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysis.java new file mode 100644 index 00000000..9ed49c53 --- /dev/null +++ b/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysis.java @@ -0,0 +1,143 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.model.Conflict; +import br.unb.cic.analysis.model.Statement; +import soot.Body; +import soot.Local; +import soot.Unit; +import soot.ValueBox; +import soot.jimple.internal.JArrayRef; +import soot.jimple.internal.JInstanceFieldRef; +import soot.toolkits.scalar.ArraySparseSet; +import soot.toolkits.scalar.FlowSet; + +import java.util.ArrayList; +import java.util.List; + +public class OverridingAssignmentAnalysis extends ReachDefinitionAnalysis { + + /** + * Constructor of the DataFlowAnalysis class. + *

+ * According to the SOOT architecture, the constructor for a + * flow analysis must receive as an argument a graph, set up + * essential information and call the doAnalysis method of the + * super class. + * + * @param definition a set of conflict definitions. + */ + public OverridingAssignmentAnalysis(Body methodBody, AbstractMergeConflictDefinition definition) { + super(methodBody, definition); + } + + @Override + protected FlowSet gen(Unit u, FlowSet in) { + FlowSet res = new ArraySparseSet<>(); + if (isSourceStatement(u) || isSinkStatement(u)) { + u.getUseAndDefBoxes().stream().filter(v -> v.getValue() instanceof Local).forEach(v -> { + Statement stmt = isSourceStatement(u) ? findSourceStatement(u) : findSinkStatement(u); + res.add(new DataFlowAbstraction((Local) v.getValue(), stmt)); + }); + } else if (u.getDefBoxes().size() > 0) { + + u.getDefBoxes().stream().filter(v -> v.getValue() instanceof Local).forEach(v -> { + String localName = getLocalName((Local) v.getValue()); + + for (DataFlowAbstraction defsIn: in){ + String defInName = getLocalName(defsIn.getLocal()); + //if u not in IN, then add it + if (!defInName.equals(localName)){ + res.add(new DataFlowAbstraction(defsIn.getLocal(), defsIn.getStmt())); //update an element in IN + break; //Do not necessary check others elements + } + } + }); + } + return res; + } + + + @Override + protected void detectConflict(FlowSet in, Unit u){ + if (!(isSinkStatement(u) || isSourceStatement(u))){ + return; + } + List left = new ArrayList<>(); + List right = new ArrayList<>(); + + u.getUseAndDefBoxes().stream().filter(v -> v.getValue() instanceof Local).forEach(v -> { + String localName = getLocalName((Local) v.getValue()); + for (DataFlowAbstraction filterIn: in){ + String inName = getLocalName(filterIn.getLocal()); + + if (filterIn.getStmt().getType().equals(Statement.Type.SOURCE) && inName.equals(localName)){ + left.add(filterIn); + }else if (filterIn.getStmt().getType().equals(Statement.Type.SINK) && inName.equals(localName)){ + right.add(filterIn); + } + } + }); + + if(isSinkStatement(u)) { + checkConflicts(u, left); + }else if (isSourceStatement(u)){ + checkConflicts(u, right); + } + } + + protected void checkConflicts(Unit u, List statements){ + for (DataFlowAbstraction statement : statements) { + if (statementEquals(statement, u)) { + Conflict c = new Conflict(statement.getStmt(), findStatement(u)); + Collector.instance().addConflict(c); + } + } + } + + @Override + protected void flowThrough(FlowSet in, Unit u, FlowSet out) { + detectConflict(in, u); + FlowSet temp = new ArraySparseSet<>(); + + FlowSet killSet = new ArraySparseSet<>(); + for(DataFlowAbstraction item : in) { + if (statementEquals(item, u)){ + killSet.add(item); + } + } + in.difference(killSet, temp); + temp.union(gen(u, in), out); + } + + private String getLocalName(Local local){ + return local.getName().split("#")[0]; + } + + private boolean statementEquals(DataFlowAbstraction statement, Unit u){ + + String statementName = getLocalName(statement.getLocal()); + for (ValueBox local : u.getDefBoxes()) { + String localName = ""; + for (ValueBox field : statement.getStmt().getUnit().getDefBoxes()) { + if (local.getValue() instanceof JInstanceFieldRef) { + statementName = field.getValue().toString(); + localName = local.getValue().toString(); + }else if (local.getValue() instanceof JArrayRef) { + if (!(isSinkStatement(u) || isSourceStatement(u))){ + return false; + } + statementName = ((field.getValue()) instanceof JArrayRef) + ? (((JArrayRef) field.getValue()).getBaseBox().getValue()).toString() + : field.getValue().toString(); + localName = (((JArrayRef) local.getValue()).getBaseBox().getValue()).toString(); + } + } + if (localName.equals("") && local.getValue() instanceof Local) { + localName = getLocalName((Local) local.getValue()); + } + return statementName.contains(localName); + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentFieldsRefAnalysis.java b/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentFieldsRefAnalysis.java new file mode 100644 index 00000000..68beb64b --- /dev/null +++ b/src/main/java/br/unb/cic/analysis/df/OverridingAssignmentFieldsRefAnalysis.java @@ -0,0 +1,332 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.model.Conflict; +import br.unb.cic.analysis.model.KeyAndFlowHash; +import br.unb.cic.analysis.model.Statement; +import soot.Body; +import soot.Unit; +import soot.ValueBox; +import soot.jimple.internal.JInstanceFieldRef; +import soot.toolkits.scalar.ArraySparseSet; +import soot.toolkits.scalar.FlowSet; + +import java.util.*; + +public class OverridingAssignmentFieldsRefAnalysis extends ReachDefinitionAnalysis { + + /** + * Constructor of the DataFlowAnalysis class. + *

+ * According to the SOOT architecture, the constructor for a + * flow analysis must receive as an argument a graph, set up + * essential information and call the doAnalysis method of the + * super class. + * + * @param definition a set of conflict definitions. + */ + public OverridingAssignmentFieldsRefAnalysis(Body methodBody, AbstractMergeConflictDefinition definition) { + super(methodBody, definition); + } + + @Override + protected FlowSet gen(Unit u, FlowSet in) { + FlowSet res = new ArraySparseSet<>(); + //Add JInstanceFieldRefs values in abstraction + if (isSourceStatement(u) || isSinkStatement(u)) { + u.getUseAndDefBoxes().stream().filter(v -> v.getValue() instanceof JInstanceFieldRef).forEach(v -> { + Statement stmt = isSourceStatement(u) ? findSourceStatement(u) : findSinkStatement(u); + res.add(new DataFlowAbstraction((JInstanceFieldRef) v.getValue(), stmt)); + }); + }else if (u.getDefBoxes().size() > 0) { + u.getUseAndDefBoxes().stream().filter(v -> v.getValue() instanceof JInstanceFieldRef).forEach(v -> { + res.add(new DataFlowAbstraction((JInstanceFieldRef) v.getValue(), getStatementBase(u))); + }); + } + return res; + } + + @Override + protected void flowThrough(FlowSet in, Unit u, FlowSet out) { + detectConflict(in, u); + //if IN has base elements, remove them + FlowSet temp = difference(in, baseStatementIsIn(in, u)); + temp.union(gen(u, in), out); + } + + //Make the difference between two FLOWSETs in relation to Statements + private FlowSet difference(FlowSet in, FlowSet out){ + FlowSet returnedFlowSet = new ArraySparseSet<>(); + for (DataFlowAbstraction dataIn: in){ + boolean notEquals = true; + for (DataFlowAbstraction dataOut: out){ + if (dataIn.getStmt().toString().equals(dataOut.getStmt().toString())) { + notEquals = false; + } + } + //Add the elements that not are in OUT + if (notEquals){ + returnedFlowSet.add(dataIn); + } + } + return returnedFlowSet; + } + + @Override + protected void detectConflict(FlowSet in, Unit u){ + if (!(isSinkStatement(u) || isSourceStatement(u)) || in.size()==0 || u.getDefBoxes().size()==0){ + return ; + } + + //Create the objects with your statement type + KeyAndFlowHash leftObject = getKeyAndFlows(in, Statement.Type.SOURCE); + KeyAndFlowHash rightObject = getKeyAndFlows(in, Statement.Type.SINK); + + List initialKeyLeft = leftObject.getKeys(); + List initialKeyRight = rightObject.getKeys(); + + if (isSourceStatement(u)){ + initialKeyLeft = getKey(u); + } + + if (isSinkStatement(u)){ + initialKeyRight = getKey(u); + } + + List generatedLeftList = new ArrayList<>(); + List generatedRightList = new ArrayList<>(); + + //If the initial key is not empty, then, there is a possible conflict + if (!initialKeyLeft.isEmpty()){ + for (String key: initialKeyLeft){ + generatedLeftList.add((getKeyAndElementsOfHashAndFlowList(key, leftObject.getHash(), leftObject.getFlow()))); + } + } + if (!initialKeyRight.isEmpty()){ + for (String key: initialKeyRight){ + generatedRightList.add((getKeyAndElementsOfHashAndFlowList(key, rightObject.getHash(), rightObject.getFlow()))); + } + } + + checkConflicts(generatedLeftList, generatedRightList, u); + } + + //Return a list with the keys of a Unit + private List getKey(Unit u){ + List initialKey = new ArrayList<>(); + for (ValueBox v: u.getDefBoxes()){ + if (v.getValue() instanceof JInstanceFieldRef){ + initialKey.add(v.getValue().toString()); + } + } + return initialKey; + } + + private void checkConflicts(List generatedLeftList, List generatedRightList, Unit u) { + for (KeyAndFlowHash left: generatedLeftList){ + for (KeyAndFlowHash right: generatedRightList){ + if(left.getUniqueKey().equals(right.getUniqueKey())){ + Statement stmt = null; + //Get the statement of the left or right flow + if (isSourceStatement(u)){ + stmt = getStatement(right); + }else if (isSinkStatement(u)){ + stmt = getStatement(left); + } + Conflict c = new Conflict(stmt, findStatement(u)); + Collector.instance().addConflict(c); + } + } + } + } + + //Return the statement of a data flow abstraction + private Statement getStatement(KeyAndFlowHash statement){ + Iterator data = statement.getFlow().iterator(); + while (data.hasNext()){ + return data.next().getStmt(); + } + return null; + } + + //Returns the final key and elements of a hash with its flow list + private KeyAndFlowHash getKeyAndElementsOfHashAndFlowList(String nextKey, Set> hash, FlowSet flow){ + List> auxValuesHashMap = new ArrayList<>(); + List> listFlowRemoved = new ArrayList<>(); + auxValuesHashMap.addAll(hash); + KeyAndFlowHash elements = new KeyAndFlowHash(nextKey, flow); + + //If nextKey not contain $stack is because simple key + if (!(nextKey.contains("$stack"))){ + return elements; + } + + JInstanceFieldRef currentField = null; + + //The second position is the field called + String currentUniqueKey = "<"+nextKey.split(".<")[1]; + + //The first key comes before ".<" if you have a stack as a substring + nextKey = nextKey.split(".<")[0]; + boolean isNextKey = true; + while(auxValuesHashMap.size()>0 && isNextKey) { + isNextKey = false; + for (HashMap auxMap : hash) { + for (String mapKey : auxMap.keySet()) { + if (mapKey.equals(nextKey)) { + currentField = auxMap.get(mapKey); + listFlowRemoved.add(auxMap); + isNextKey = true; + auxValuesHashMap.remove(auxMap); + } + } + if (isNextKey) { + break; + } + } + + if (!isNextKey) { + currentUniqueKey = nextKey + (currentUniqueKey.equals("") ? "" : ".") + currentUniqueKey; + } else{ + currentUniqueKey = currentField.getFieldRef().toString() + (currentUniqueKey.equals("") ? "" : ".") + currentUniqueKey; + nextKey = currentField.getBase().toString(); //Update the nextKey and repeat until the condition + } + } + //If auxValuesHasMap is equal to zero, there is a next key and currentField is not null, then it is the starting field of the object + if (!(currentField==null) && (isNextKey)){ + currentUniqueKey = nextKey + (currentUniqueKey.equals("") ? "" : ".") + currentUniqueKey; + } + + //Update key and flow + elements.setUniqueKey(currentUniqueKey); + if (!flow.isEmpty()) { + //Remove all the elements equals in listFlowRemoved and flow + elements.setFlow(removeFlowSet(listFlowRemoved, flow)); + } + return elements; + } + + //Checks which elements have to be removed from the flowSet according with a HasMap + private FlowSet removeFlowSet(List> listFLowRemoved, FlowSet flow){ + FlowSet flowSetReturn = new ArraySparseSet<>(); + + for (HashMap map : listFLowRemoved){ + for (String mapKey : map.keySet()) { + for(DataFlowAbstraction data: flow) { + if (map.get(mapKey).toString().equals(data.getJInstanceFieldRef().toString())) { + String def = ""; + for (ValueBox i: data.getStmt().getUnit().getDefBoxes()){ + def = i.getValue().toString(); + } + if (def.equals(mapKey)) { + flowSetReturn.add(data); + } + } + } + } + } + return flowSetReturn; + } + + //If ref field is null, then is a key definition of getDefUseBox() + private boolean isJInstanceFieldRef(JInstanceFieldRef ref){ + return ref==null; + } + + //if IN has base elements, remove them + private FlowSet baseStatementIsIn(FlowSet in, Unit u) { + + if ((isSinkStatement(u) || isSourceStatement(u))) { + return new ArraySparseSet<>(); + } + + KeyAndFlowHash leftObject = getKeyAndFlows(in, Statement.Type.SOURCE); + KeyAndFlowHash rightObject = getKeyAndFlows(in, Statement.Type.SINK); + KeyAndFlowHash baseObject = getKeyAndFlows(in, Statement.Type.IN_BETWEEN); + + List initialKeyLeft = leftObject.getKeys(); + List initialKeyRight = rightObject.getKeys(); + + String initialKeyBase = ""; + + if (u.getDefBoxes().size() > 0) { + for (ValueBox v : u.getDefBoxes()) { + if (v.getValue() instanceof JInstanceFieldRef) { + initialKeyBase = v.getValue().toString(); + } + } + } + FlowSet flowSetReturn = new ArraySparseSet<>(); + + if (!initialKeyRight.isEmpty()) { + flowSetReturn = returnedFlow(initialKeyBase, baseObject.getHash(), baseObject.getFlow(), initialKeyRight, rightObject.getHash(), rightObject.getFlow()); + } + if (!initialKeyLeft.isEmpty()){ + for (DataFlowAbstraction flow : returnedFlow(initialKeyBase, baseObject.getHash(), baseObject.getFlow(), initialKeyLeft, leftObject.getHash(), leftObject.getFlow())){ + flowSetReturn.add(flow); + } + return flowSetReturn; + } + + return flowSetReturn; + } + + //Returns the flows from two equals getKeyAndElementsOfHashAndFlowList, left ou right with base statement + private FlowSet returnedFlow(String initialKeyBase, Set> hashBase, FlowSet baseFlow, + List comparedInitialKey, Set> comparedHashMap, FlowSet comparedFlow){ + + FlowSet flowSetReturn = new ArraySparseSet<>(); + FlowSet initialFlow = newInitialFlow(); + String generatedBase = ""; + if (initialKeyBase != "") { + generatedBase = (getKeyAndElementsOfHashAndFlowList(initialKeyBase, hashBase, initialFlow)).getUniqueKey(); + } + + for (String key : comparedInitialKey) { + String left = (getKeyAndElementsOfHashAndFlowList(key, comparedHashMap, initialFlow)).getUniqueKey(); + if (left.equals(generatedBase)) { + for (DataFlowAbstraction flow : getKeyAndElementsOfHashAndFlowList(initialKeyBase, hashBase, baseFlow).getFlow()) { + flowSetReturn.add(flow); + } + + for (DataFlowAbstraction flow : getKeyAndElementsOfHashAndFlowList(key, comparedHashMap, comparedFlow).getFlow()) { + flowSetReturn.add(flow); + } + return flowSetReturn; + } + } + return flowSetReturn; + + } + + //Returns the final key and the flow of the IN elements + private KeyAndFlowHash getKeyAndFlows(FlowSet in, Statement.Type statementType){ + + List initialKey = new ArrayList<>(); + FlowSet flow = new ArraySparseSet<>(); + Set> returnedHashMap = new HashSet<>(); + + for (DataFlowAbstraction filterIn : in) { + HashMap auxHashMap = new HashMap<>(); + StringBuilder strKey = new StringBuilder(); + for (ValueBox valueBoxKey : filterIn.getStmt().getUnit().getDefBoxes()) { + strKey.append(valueBoxKey.getValue().toString()); + } + JInstanceFieldRef currentFieldRef = null; + for (ValueBox catchRef : filterIn.getStmt().getUnit().getUseBoxes()) { + if (catchRef.getValue() instanceof JInstanceFieldRef) { + currentFieldRef = (JInstanceFieldRef) catchRef.getValue(); + auxHashMap.put(strKey.toString(), currentFieldRef); + } + } + if (filterIn.getStmt().getType().equals(statementType)) { + if (auxHashMap.size() != 0) returnedHashMap.add(auxHashMap); + flow.add(filterIn); + if (isJInstanceFieldRef(currentFieldRef)) { + initialKey.add(strKey.toString()); + } + } + } + return new KeyAndFlowHash(initialKey, flow, returnedHashMap); + } +} \ No newline at end of file diff --git a/src/main/java/br/unb/cic/analysis/df/ReachDefinitionAnalysis.java b/src/main/java/br/unb/cic/analysis/df/ReachDefinitionAnalysis.java old mode 100755 new mode 100644 index 729e5762..51cb8bb0 --- a/src/main/java/br/unb/cic/analysis/df/ReachDefinitionAnalysis.java +++ b/src/main/java/br/unb/cic/analysis/df/ReachDefinitionAnalysis.java @@ -14,7 +14,7 @@ import soot.Unit; import soot.ValueBox; import soot.jimple.internal.JArrayRef; -import soot.toolkits.graph.DirectedGraph; +import soot.jimple.internal.JInstanceFieldRef; import soot.toolkits.graph.ExceptionalUnitGraph; import soot.toolkits.scalar.ArraySparseSet; import soot.toolkits.scalar.FlowSet; @@ -81,7 +81,7 @@ protected void flowThrough(FlowSet in, Unit u, FlowSet kill(Unit u) { + protected FlowSet kill(Unit u) { FlowSet res = new ArraySparseSet<>(); for(Local local: getDefVariables(u)) { @@ -163,6 +163,15 @@ protected Statement findStatement(Unit d) { .setSourceCodeLineNumber(d.getJavaSourceStartLineNumber()).build(); } + protected Statement getStatementBase(Unit d) { + return Statement.builder() + .setClass(methodBody.getMethod().getDeclaringClass()) + .setMethod(methodBody.getMethod()) + .setType(Statement.Type.IN_BETWEEN) + .setUnit(d) + .setSourceCodeLineNumber(d.getJavaSourceStartLineNumber()).build(); + } + protected boolean isSourceStatement(Unit d) { return definition.getSourceStatements().stream().map(s -> s.getUnit()).collect(Collectors.toList()).contains(d); } @@ -196,6 +205,10 @@ protected List getDefVariables(Unit u) { JArrayRef ref = (JArrayRef) v.getValue(); localDefs.add((Local) ref.getBaseBox().getValue()); } + else if (v.getValue() instanceof JInstanceFieldRef) { + JInstanceFieldRef ref = (JInstanceFieldRef) v.getValue(); + localDefs.add((Local) ref.getBaseBox().getValue()); + } } return localDefs; } diff --git a/src/main/java/br/unb/cic/analysis/model/KeyAndFlowHash.java b/src/main/java/br/unb/cic/analysis/model/KeyAndFlowHash.java new file mode 100644 index 00000000..58220d47 --- /dev/null +++ b/src/main/java/br/unb/cic/analysis/model/KeyAndFlowHash.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.model; + +import br.unb.cic.analysis.df.DataFlowAbstraction; +import soot.jimple.internal.JInstanceFieldRef; +import soot.toolkits.scalar.FlowSet; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +public class KeyAndFlowHash { + + private String uniqueKey; + private List keys; + private FlowSet flow; + private Set> hash; + + public KeyAndFlowHash(){ + } + + + public KeyAndFlowHash(String uniqueKey, FlowSet flow){ + this.uniqueKey = uniqueKey; + this.flow = flow; + } + + public KeyAndFlowHash(List keys, FlowSet flow, Set> hash){ + this.keys = keys; + this.flow = flow; + this.hash = hash; + } + public List getKeys(){ + return this.keys; + } + + public String getUniqueKey(){ + return this.uniqueKey; + } + + public void setUniqueKey(String uniqueKey){ + this.uniqueKey = uniqueKey; + } + + public FlowSet getFlow(){ + return this.flow; + } + + public Set> getHash(){ + return this.hash; + } + + public void setKeys(List keys) { + this.keys = keys; + } + + public void setFlow(FlowSet flow) { + this.flow = flow; + } + + public void setHash(Set> hash) { + this.hash = hash; + } + +} diff --git a/src/main/java/br/unb/cic/analysis/svfa/SVFAAnalysis.java b/src/main/java/br/unb/cic/analysis/svfa/SVFAAnalysis.java index fd0e6d04..ee1e7f0a 100644 --- a/src/main/java/br/unb/cic/analysis/svfa/SVFAAnalysis.java +++ b/src/main/java/br/unb/cic/analysis/svfa/SVFAAnalysis.java @@ -31,6 +31,12 @@ public String sootClassPath() { return ""; } + @Override + public List getIncludeList() { + String[] array = new String[0]; + return JavaConverters.asScalaBuffer(Arrays.asList(array)).toList(); + } + @Override public List applicationClassPath() { String[] array = cp.split(":"); diff --git a/src/test/java/br/unb/cic/analysis/df/ArrayTaintedAnalysisOneConflictIndirectTest.java b/src/test/java/br/unb/cic/analysis/df/ArrayTaintedAnalysisOneConflictIndirectTest.java new file mode 100644 index 00000000..fea26879 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/ArrayTaintedAnalysisOneConflictIndirectTest.java @@ -0,0 +1,63 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ArrayTaintedAnalysisOneConflictIndirectTest { + + private TaintedAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(8); //source 1 + res.put("br.unb.cic.analysis.samples.ArrayIndirectDataFlowSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //sink 1 + lines.add(12); //sink 2 + res.put("br.unb.cic.analysis.samples.ArrayIndirectDataFlowSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new TaintedAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.ArrayIndirectDataFlowSample"; + + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(2, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysCompleteOverlayConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysCompleteOverlayConflictTest.java new file mode 100644 index 00000000..311d8551 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysCompleteOverlayConflictTest.java @@ -0,0 +1,63 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisArraysCompleteOverlayConflictTest { + + private OverridingAssignmentAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentArraysCompleteOverlaySample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(7); //right + lines.add(13); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentArraysCompleteOverlaySample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentArraysCompleteOverlaySample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysConflictTest.java new file mode 100644 index 00000000..a2450aae --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisArraysConflictTest.java @@ -0,0 +1,62 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisArraysConflictTest { + + private OverridingAssignmentAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(8); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentArraysSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentArraysSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentArraysSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisLocalVariablesConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisLocalVariablesConflictTest.java new file mode 100644 index 00000000..76acc869 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisLocalVariablesConflictTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisLocalVariablesConflictTest { + + private OverridingAssignmentAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(8); //left + lines.add(11); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentLocalVariablesSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(9); //right + lines.add(12); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentLocalVariablesSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentLocalVariablesSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectArraysConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectArraysConflictTest.java new file mode 100644 index 00000000..e13a4ce7 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectArraysConflictTest.java @@ -0,0 +1,63 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectArraysConflictTest { + + private OverridingAssignmentAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(19); + lines.add(21); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectArraysSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(22); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectArraysSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectArraysSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldOneConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldOneConflictTest.java new file mode 100644 index 00000000..b0dc206a --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldOneConflictTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectOneFieldOneConflictTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldOneConflictSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldOneConflictSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldOneConflictSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldTwoConflictsTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldTwoConflictsTest.java new file mode 100644 index 00000000..951ea32e --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldTwoConflictsTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectOneFieldTwoConflictsTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldTwoConflictsSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldTwoConflictsSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldTwoConflictsSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(2, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldZeroConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldZeroConflictTest.java new file mode 100644 index 00000000..47a9d7d8 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectOneFieldZeroConflictTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectOneFieldZeroConflictTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(14); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldZeroConflictSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(15); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldZeroConflictSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectOneFieldZeroConflictSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(0, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsOneConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsOneConflictTest.java new file mode 100644 index 00000000..c2bf4084 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsOneConflictTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectThreeFieldsOneConflictTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsOneConflictSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsOneConflictSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsOneConflictSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsTwoConflictsTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsTwoConflictsTest.java new file mode 100644 index 00000000..3021e092 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectThreeFieldsTwoConflictsTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectThreeFieldsTwoConflictsTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsTwoConflictsSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsTwoConflictsSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectThreeFieldsTwoConflictsSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(2, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldOneConflictTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldOneConflictTest.java new file mode 100644 index 00000000..4fd41f66 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldOneConflictTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectTwoFieldOneConflictTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsOneConflictSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsOneConflictSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsOneConflictSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldTwoConflictsTest.java b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldTwoConflictsTest.java new file mode 100644 index 00000000..3cdb1f6f --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/OverridingAssignmentAnalysisObjectTwoFieldTwoConflictsTest.java @@ -0,0 +1,64 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import br.unb.cic.analysis.SootWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OverridingAssignmentAnalysisObjectTwoFieldTwoConflictsTest { + + private OverridingAssignmentFieldsRefAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(10); //left + lines.add(13); //left + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsTwoConflictsSample", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); //right + lines.add(14); //right + res.put("br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsTwoConflictsSample", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.oneConflict", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new OverridingAssignmentFieldsRefAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.OverridingAssignmentObjectTwoFieldsTwoConflictsSample"; + PhaseOptions.v().setPhaseOption("jb", "use-original-names:true"); + + SootWrapper.builder().withClassPath(cp).addClass(targetClass).build().execute(); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(2, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementConfluentTest.java b/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementConfluentTest.java new file mode 100644 index 00000000..5828d15f --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementConfluentTest.java @@ -0,0 +1,63 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; +import soot.options.Options; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SourceSinkVariableAttributionWithAutoIncrementConfluentTest { + + private ConfluentAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(9); + res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); + res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.confluence", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new ConfluentAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement"; + + Options.v().setPhaseOption("jb", "optimize:false"); + + Main.main(new String[] {"-w", "-allow-phantom-refs", "-f", "J", "-keep-line-number", "-cp", cp, targetClass}); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(0, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementTaintedConfluentTest.java b/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementTaintedConfluentTest.java new file mode 100644 index 00000000..8fd2ae72 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/df/SourceSinkVariableAttributionWithAutoIncrementTaintedConfluentTest.java @@ -0,0 +1,63 @@ +package br.unb.cic.analysis.df; + +import br.unb.cic.analysis.AbstractMergeConflictDefinition; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import soot.*; +import soot.options.Options; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class SourceSinkVariableAttributionWithAutoIncrementTaintedConfluentTest { + + private ConfluentTaintedAnalysis analysis; + + @Before + public void configure() { + G.reset(); + Collector.instance().clear(); + + AbstractMergeConflictDefinition definition = new AbstractMergeConflictDefinition() { + @Override + protected Map> sourceDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(9); + res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement", lines); + return res; + } + + @Override + protected Map> sinkDefinitions() { + Map> res = new HashMap<>(); + List lines = new ArrayList<>(); + lines.add(11); + res.put("br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement", lines); + return res; + } + }; + + PackManager.v().getPack("jtp").add( + new Transform("jtp.confluence", new BodyTransformer() { + @Override + protected void internalTransform(Body body, String phaseName, Map options) { + analysis = new ConfluentTaintedAnalysis(body, definition); + } + })); + String cp = "target/test-classes"; + String targetClass = "br.unb.cic.analysis.samples.SourceSinkVariableAttributionWithAutoIncrement"; + + Options.v().setPhaseOption("jb", "optimize:false"); + + Main.main(new String[] {"-w", "-allow-phantom-refs", "-f", "J", "-keep-line-number", "-cp", cp, targetClass}); + } + + @Test + public void testDataFlowAnalysisExpectingOneConflict() { + Assert.assertEquals(1, analysis.getConflicts().size()); + } +} diff --git a/src/test/java/br/unb/cic/analysis/samples/ArrayIndirectDataFlowSample.java b/src/test/java/br/unb/cic/analysis/samples/ArrayIndirectDataFlowSample.java new file mode 100644 index 00000000..5d86b2d3 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/ArrayIndirectDataFlowSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class ArrayIndirectDataFlowSample { + + public static void main(String[] args) { + int[] arr = {0,0,0,0,0}; + + arr[4] = 10; //source 1 + + int b = arr[3]; //sink 1 + + System.out.println(b); //sink 2 + + } + +} diff --git a/src/test/java/br/unb/cic/analysis/samples/Employee.java b/src/test/java/br/unb/cic/analysis/samples/Employee.java index 502d5f4c..4cee5763 100644 --- a/src/test/java/br/unb/cic/analysis/samples/Employee.java +++ b/src/test/java/br/unb/cic/analysis/samples/Employee.java @@ -1,6 +1,7 @@ package br.unb.cic.analysis.samples; class Employee { + public String name = "Name"; public int salary = 20; @@ -8,4 +9,21 @@ public Employee(String n, int s) { this.name = n; this.salary = s; } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getSalary() { + return salary; + } + + public void setSalary(int salary) { + this.salary = salary; + } + } diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysCompleteOverlaySample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysCompleteOverlaySample.java new file mode 100644 index 00000000..04a90ed3 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysCompleteOverlaySample.java @@ -0,0 +1,17 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentArraysCompleteOverlaySample { + + public static void main(String[] args) { + + int[] aux = {1, 2, 3, 4, 5}; //right + int[] arr = {0,0,0,0,0}; + + arr[4] = 10; //left + arr[5] = 10; + + arr = aux; //right + + System.out.println(arr[5]); + } +} diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysSample.java new file mode 100644 index 00000000..0c021990 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentArraysSample.java @@ -0,0 +1,14 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentArraysSample { + + public static void main(String[] args) { + int[] arr = {0,0,0,0,0}; + + arr[4] = 10; //left + arr[5] = 10; + arr[3] = 3; //right + + System.out.println(arr[5]); + } +} diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance.java new file mode 100644 index 00000000..5dca9c05 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance.java @@ -0,0 +1,10 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentInstance { + + public int a; + public int b; + + public OverridingAssignmentInstance(){} + +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance2.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance2.java new file mode 100644 index 00000000..de660f20 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentInstance2.java @@ -0,0 +1,10 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentInstance2 { + + public OverridingAssignmentInstance a; + public OverridingAssignmentInstance b; + + public OverridingAssignmentInstance2(){} + +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentLocalVariablesSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentLocalVariablesSample.java new file mode 100644 index 00000000..ca43f15a --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentLocalVariablesSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentLocalVariablesSample { + + public static void main(String[] args) { + int x=0, y=0, w=1, z=3; + + x = 3; // left + y = 3; // right + x = x+1; //x = 3;// base + y = 3; // left + x = 21; // right + + System.out.println(x); + } +} diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectArraysSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectArraysSample.java new file mode 100644 index 00000000..bd7e5f43 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectArraysSample.java @@ -0,0 +1,26 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectArraysSample { + + public static void main(String[] args) { + Employee employee0 = new Employee("Name", 0); + Employee employee1 = new Employee("Name", 1); + Employee employee2 = new Employee("Name", 2); + + Employee[] arr = { + employee0, employee1, employee2 + }; + + Employee[] aux = { + employee0, employee1, employee2 + }; + + employee0.setName("Name1"); + arr[0] = employee0; //left + arr[1] = new Employee("Name1", 1); + aux = arr; //left + aux[1] = new Employee("Name", 1); //right + + System.out.println(arr); + } +} diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldOneConflictSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldOneConflictSample.java new file mode 100644 index 00000000..cba2658c --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldOneConflictSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectOneFieldOneConflictSample { + public int a; + public int b; + + public static void main(String[] args) { + OverridingAssignmentObjectOneFieldOneConflictSample instance = new OverridingAssignmentObjectOneFieldOneConflictSample(); + + instance.b = instance.b + 3; // left + instance.a = 3; // right + instance.a = instance.b+3; // base + instance.a = 4; //left + instance.b = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldTwoConflictsSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldTwoConflictsSample.java new file mode 100644 index 00000000..f44766c6 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldTwoConflictsSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectOneFieldTwoConflictsSample { + public int a; + public int b; + + public static void main(String[] args) { + OverridingAssignmentObjectOneFieldTwoConflictsSample instanceLocal = new OverridingAssignmentObjectOneFieldTwoConflictsSample(); + + instanceLocal.b = instanceLocal.b + 3; // left + instanceLocal.a = 3; // right + + instanceLocal.a = 4; //left + instanceLocal.b = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldZeroConflictSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldZeroConflictSample.java new file mode 100644 index 00000000..105b4141 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectOneFieldZeroConflictSample.java @@ -0,0 +1,17 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectOneFieldZeroConflictSample { + public int a; + public int b; + + public static void main(String[] args) { + OverridingAssignmentObjectOneFieldZeroConflictSample instanceLocal = new OverridingAssignmentObjectOneFieldZeroConflictSample(); + + instanceLocal.b = instanceLocal.b + 3; // left + instanceLocal.a = 3; // right + instanceLocal.a = instanceLocal.b+3; // base + instanceLocal.b = instanceLocal.b+3; // base + instanceLocal.a = 4; //left + instanceLocal.b = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsOneConflictSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsOneConflictSample.java new file mode 100644 index 00000000..a0d98f43 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsOneConflictSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectThreeFieldsOneConflictSample { + public OverridingAssignmentInstance2 a; + public OverridingAssignmentInstance2 b; + + public static void main(String[] args) { + OverridingAssignmentObjectThreeFieldsOneConflictSample instanceLocal = new OverridingAssignmentObjectThreeFieldsOneConflictSample(); + + instanceLocal.b.a.a = instanceLocal.b.a.a + 3; // left + instanceLocal.b.a.b = 3; // right in {instanceLocal.b.a.a, instanceLocal.b.a.b } + instanceLocal.b.a.a = 7; // base + instanceLocal.b.a.b = 4; //left + instanceLocal.b.a.a = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsTwoConflictsSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsTwoConflictsSample.java new file mode 100644 index 00000000..3f4ec253 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectThreeFieldsTwoConflictsSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectThreeFieldsTwoConflictsSample { + public OverridingAssignmentInstance2 a; + public OverridingAssignmentInstance2 b; + + public static void main(String[] args) { + OverridingAssignmentObjectThreeFieldsTwoConflictsSample instanceLocal = new OverridingAssignmentObjectThreeFieldsTwoConflictsSample(); + + instanceLocal.b.a.a = instanceLocal.b.a.a + 3; // left + instanceLocal.b.a.b = 3; // right in {instanceLocal.b.a.a, instanceLocal.b.a.b } + + instanceLocal.b.a.b = 4; //left + instanceLocal.b.a.a = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsOneConflictSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsOneConflictSample.java new file mode 100644 index 00000000..4c942794 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsOneConflictSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectTwoFieldsOneConflictSample { + public OverridingAssignmentInstance a; + public OverridingAssignmentInstance b; + + public static void main(String[] args) { + OverridingAssignmentObjectTwoFieldsOneConflictSample instanceLocal = new OverridingAssignmentObjectTwoFieldsOneConflictSample(); + + instanceLocal.b.a = instanceLocal.b.a + 3; // left + instanceLocal.b.b = 3; // right + instanceLocal.b.b = instanceLocal.b.a+3; // base + instanceLocal.b.b = 4; //left + instanceLocal.b.a = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsTwoConflictsSample.java b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsTwoConflictsSample.java new file mode 100644 index 00000000..62ab3e88 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/OverridingAssignmentObjectTwoFieldsTwoConflictsSample.java @@ -0,0 +1,16 @@ +package br.unb.cic.analysis.samples; + +public class OverridingAssignmentObjectTwoFieldsTwoConflictsSample { + public OverridingAssignmentInstance a; + public OverridingAssignmentInstance b; + + public static void main(String[] args) { + OverridingAssignmentObjectTwoFieldsTwoConflictsSample $stack = new OverridingAssignmentObjectTwoFieldsTwoConflictsSample(); + + $stack.b.a = $stack.b.a + 3; // left + $stack.b.b = 3; // right + + $stack.b.b = 4; //left + $stack.b.a = 4; //right + } +} \ No newline at end of file diff --git a/src/test/java/br/unb/cic/analysis/samples/SourceSinkVariableAttributionWithAutoIncrement.java b/src/test/java/br/unb/cic/analysis/samples/SourceSinkVariableAttributionWithAutoIncrement.java new file mode 100644 index 00000000..e72ef425 --- /dev/null +++ b/src/test/java/br/unb/cic/analysis/samples/SourceSinkVariableAttributionWithAutoIncrement.java @@ -0,0 +1,19 @@ +package br.unb.cic.analysis.samples; + +public class SourceSinkVariableAttributionWithAutoIncrement { + public void foo() { + int x = 0; + int y = 0; + int z = 10; + + x = 10; //left + x++; // base + y = z+2; //right + + addThese(x, y); //Confluence Line + + } + private int addThese(int a0, int a1){ + return a0 + a1; + } +}