foss-vuln-tracker/repoman/src/main/java/it/unitn/repoman/core/slicers/tainters/ForwardTainterPessimist.java

120 lines
4.7 KiB
Java

package it.unitn.repoman.core.slicers.tainters;
import it.unitn.repoman.core.lang.traversals.generic.ConditionTraversal;
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class ForwardTainterPessimist extends ForwardTainter {
public ForwardTainterPessimist(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
super(collectables, seeds);
}
@Override
protected void initSeed(ParserRuleContext stmt) {
this.taintedStatements.add(stmt);
ParserRuleContext scope = wrapper.getContainer(stmt);
ParseTree defVar = wrapper.getDefinedVar(stmt);
if (defVar != null) {
this.taints.addTaintedVariable(scope, defVar);
}
/*
* THIS SHOULD NOT HAPPEN IN AN "EFFECT-FREE" SLICE!
* taint ref. variables in a method call as well */
if (wrapper.isMethodCall(stmt)) {
for (ParseTree var : wrapper.getReferencedVars(stmt)) {
this.taints.addTaintedVariable(scope, var);
}
}
// if the seed is a conditional statement or a return statement, take all inner statements
else if (wrapper.isConditionalExpression(stmt)) {
this.taintedStatements.addAll(taintConditionalExpression(stmt));
// and taint all variables within the condition
Set<ParseTree> vars = wrapper.getReferencedVars(stmt);
for (ParseTree var : vars) {
taints.addTaintedVariable(scope, var);
}
}
}
@Override
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
for (ParserRuleContext collectable: this.collectables) {
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
// do nothing if a statement is already collected
if (taintedStatements.contains(collectable)) {
if (wrapper.isMethodCall(collectable)) {
for (ParseTree var : wrapper.getReferencedVars(collectable)) {
this.taints.addTaintedVariable(collectableScope, var);
}
}
continue;
}
if (collectableScope.equals(taintedScope) && wrapper.precedes(taintedStmt, collectable)) {
Set<String> taintedVars = this.taints.getVariableNames(collectableScope);
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
MethodCallTraversal t = wrapper.getMethodCallTraversal(collectable);
if (t.isMethodCall()) {
List<ParseTree> vars = t.getParams();
boolean tainted = false;
for (ParseTree var : vars) {
if (taintedVars.contains(var.getText())) {
tainted = true;
break;
}
}
if (tainted) {
for (ParseTree var : vars) {
taints.addTaintedVariable(collectableScope, var);
}
}
}
for (ParseTree referencedVar : referencedVars) {
if (taintedVars.contains(referencedVar.getText())) {
elementsToAdd.add(collectable);
ParseTree definedVar = wrapper.getDefinedVar(collectable);
if (definedVar != null) {
taints.addTaintedVariable(collectableScope, definedVar);
}
}
}
}
}
Set<ParserRuleContext> taintedInnerStatements = new HashSet<>();
for (ParserRuleContext ctx : elementsToAdd) {
if (wrapper.isConditionalExpression(ctx)) {
taintedInnerStatements.addAll(taintInnerStatements(ctx));
}
}
elementsToAdd.addAll(taintedInnerStatements);
return elementsToAdd;
}
@Override
protected Set<ParserRuleContext> taintInnerStatements(ParserRuleContext cnd) {
Set<ParserRuleContext> addedStmts = new HashSet<>();
ConditionTraversal t = new ConditionTraversal(cnd);
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
ParseTree defVar = wrapper.getDefinedVar(innerStmt);
if (defVar != null) {
taints.addTaintedVariable(wrapper.getContainer(innerStmt), defVar);
}
addedStmts.add(innerStmt);
}
return addedStmts;
}
}