Package dk.brics.string.intermediate.operations

Source Code of dk.brics.string.intermediate.operations.FlowGraphNodeCreator

package dk.brics.string.intermediate.operations;

import java.util.HashMap;
import java.util.Map;

import dk.brics.automaton.Automaton;
import dk.brics.string.flow.AssignmentNode;
import dk.brics.string.flow.FlowGraph;
import dk.brics.string.flow.Node;
import dk.brics.string.flow.operations.FlowGraph2Grammar;
import dk.brics.string.intermediate.Application;
import dk.brics.string.intermediate.ArrayAddAll;
import dk.brics.string.intermediate.ArrayAssignment;
import dk.brics.string.intermediate.ArrayCorrupt;
import dk.brics.string.intermediate.ArrayFromArray;
import dk.brics.string.intermediate.ArrayNew;
import dk.brics.string.intermediate.ArrayWriteArray;
import dk.brics.string.intermediate.ArrayWriteElement;
import dk.brics.string.intermediate.AssertAliases;
import dk.brics.string.intermediate.AssertBinaryOp;
import dk.brics.string.intermediate.AssertUnaryOp;
import dk.brics.string.intermediate.BasicBinaryOp;
import dk.brics.string.intermediate.BasicUnaryOp;
import dk.brics.string.intermediate.Call;
import dk.brics.string.intermediate.Catch;
import dk.brics.string.intermediate.ExceptionalReturn;
import dk.brics.string.intermediate.Field;
import dk.brics.string.intermediate.FieldAssignment;
import dk.brics.string.intermediate.FieldReference;
import dk.brics.string.intermediate.Hotspot;
import dk.brics.string.intermediate.Method;
import dk.brics.string.intermediate.MethodHead;
import dk.brics.string.intermediate.Nop;
import dk.brics.string.intermediate.ObjectAssignment;
import dk.brics.string.intermediate.ObjectCorrupt;
import dk.brics.string.intermediate.PrimitiveAssignment;
import dk.brics.string.intermediate.PrimitiveFromArray;
import dk.brics.string.intermediate.PrimitiveInit;
import dk.brics.string.intermediate.Return;
import dk.brics.string.intermediate.Statement;
import dk.brics.string.intermediate.StatementVisitor;
import dk.brics.string.intermediate.StringAssignment;
import dk.brics.string.intermediate.StringBufferAppend;
import dk.brics.string.intermediate.StringBufferAppendChar;
import dk.brics.string.intermediate.StringBufferAssignment;
import dk.brics.string.intermediate.StringBufferBinaryOp;
import dk.brics.string.intermediate.StringBufferCorrupt;
import dk.brics.string.intermediate.StringBufferInit;
import dk.brics.string.intermediate.StringBufferPrepend;
import dk.brics.string.intermediate.StringBufferUnaryOp;
import dk.brics.string.intermediate.StringConcat;
import dk.brics.string.intermediate.StringFromArray;
import dk.brics.string.intermediate.StringFromStringBuffer;
import dk.brics.string.intermediate.StringInit;
import dk.brics.string.intermediate.Variable;
import dk.brics.string.stringoperations.Basic;

/**
* Translates a set of methods into a flow graph with no edges.
* For every statement, a node is created for each potentially defined variable.
* Edges are added by a {@link dk.brics.string.intermediate.operations.FlowGraphEdgeCreator}.
*
* @see FlowGraph2Grammar
*/
public class FlowGraphNodeCreator implements StatementVisitor {

    private FlowGraph g;

    /**
     * All nodes for each statement.
     */
    private Map<Statement, Map<Variable, Node>> map;
   
    private Map<Field, AssignmentNode> fieldNodes;

    /**
     * Main node for each statement.
     */
    private Map<Statement, Node> trans_map;

    private AliasAnalysis aa;

    private DefinesVisitor dv;

    private DefinesVisitor dva;

    private Automaton empty = Basic.makeNoString();

    /**
     * Language for variables that are considered corrupt. By default this
     * will be the language containing all strings.
     */
    private Automaton corruptAutomaton = Basic.makeAnyString();

    /**
     * Current statement.
     */
    private Statement s;

    /**
     * Current defined variable.
     */
    private Variable v;
   
    private OperationAssertionAnalysis ass;
   
    /**
     * Creates nodes in the flow graph, using the set of all strings as the value for
     * all corrupt values.
     * @param app the intermediate representation
     * @param aa alias analysis of the intermediate representation
     */
    public FlowGraphNodeCreator(Application app, AliasAnalysis aa, OperationAssertionAnalysis ass) {
      this(app, aa, Basic.makeAnyString(), ass);
    }
   
    /**
     * Creates nodes in the flow graph, using a specified language as the value for
     * all corrupt values.
     * @param app the intermediate representation
     * @param aa alias analysis of the intermediate representation
     * @param corruptAutomaton language to use for all corrupt variables
     */
    public FlowGraphNodeCreator(Application app, AliasAnalysis aa, Automaton corruptAutomaton, OperationAssertionAnalysis ass) {
        this.aa = aa;
        this.ass = ass;
        this.corruptAutomaton = corruptAutomaton;
        dv = new DefinesVisitor();
        dva = new DefinesVisitor(aa);
        g = new FlowGraph();
        map = new HashMap<Statement, Map<Variable, Node>>();
        fieldNodes = new HashMap<Field, AssignmentNode>();
        trans_map = new HashMap<Statement, Node>();

        for (Method m : app.getMethods()) {
            for (Statement st : m.getStatements()) {
                s = st;
                map.put(s, new HashMap<Variable, Node>());
                for (Variable vi : dva.definedVars(s)) {
                    v = vi;
                    s.visitBy(this); // visit each defined variable (including aliases) for each statement
                    if (dv.defines(s, v)) {
                        trans_map.put(s, map.get(s).get(v));
                    }
                    if (vi.isTaint()) {
                        Node n = map.get(s).get(v);
                        if (n != null) {
                            n.setTaint(true);
                        }
                    }
                }
            }
        }

        for (Map<Variable, Node> vmap : map.values()) {
            for (Variable v : vmap.keySet()) { // TODO: inefficient, use entrySet iterator instead
                Node n = vmap.get(v);
                n.setTaint(v.isTaint());
            }
        }
       
        // create field nodes
        for (Field field : app.getFields()) {
            fieldNodes.put(field, g.addAssignmentNode());
        }
    }

    public Map<Field, AssignmentNode> getFieldNodes() {
        return fieldNodes;
    }

    /**
     * Returns the graph being constructed.
     */
    public FlowGraph getGraph() {
        return g;
    }

    /**
     * Returns map containing all nodes for each statement.
     */
    public Map<Statement, Map<Variable, Node>> getMap() {
        return map;
    }

    /**
     * Returns map containing main node for each statement.
     */
    public Map<Statement, Node> getTranslationMap() {
        return trans_map;
    }

    private void addNode(Node n) {
        map.get(s).put(v, n);
    }
   
    public void visitPrimitiveAssignment(PrimitiveAssignment s) {
        addNode(g.addAssignmentNode());
    }
    public void visitPrimitiveInit(PrimitiveInit s) {
        addNode(g.addInitializationNode(s.regexp));
    }
    public void visitStringBufferAppendChar(StringBufferAppendChar s) {
        addNode(g.addConcatenationNode());
    }
    public void visitBasicUnaryOp(BasicUnaryOp s) {
        addNode(g.addUnaryNode(s.op));
    }
    public void visitBasicBinaryOp(BasicBinaryOp s) {
        addNode(g.addBinaryNode(s.op));
    }
    public void visitAssertBinaryOp(AssertBinaryOp s) {
        if (ass.isAssertionValid(s)) {
            addNode(g.addBinaryNode(s.op));
        } else {
            addNode(g.addAssignmentNode());
        }
    }
    public void visitAssertUnaryOp(AssertUnaryOp s) {
        if (ass.isAssertionValid(s)) {
            addNode(g.addUnaryNode(s.op));
        } else {
            addNode(g.addAssignmentNode());
        }
    }
    public void visitAssertAliases(AssertAliases s) {
    }
   
    public void visitArrayAssignment(ArrayAssignment s) {
        addNode(g.addAssignmentNode());
    }

    public void visitArrayCorrupt(ArrayCorrupt s) {
        addNode(g.addInitializationNode(corruptAutomaton));
    }
   
    public void visitArrayAddAll(ArrayAddAll s) {
        addNode(g.addAssignmentNode());
    }

    public void visitArrayFromArray(ArrayFromArray s) {
        addNode(g.addAssignmentNode());
    }

    public void visitArrayNew(ArrayNew s) {
        addNode(g.addInitializationNode(empty));
    }

    public void visitArrayWriteArray(ArrayWriteArray s) {
        addNode(g.addAssignmentNode());
    }

    public void visitArrayWriteElement(ArrayWriteElement s) {
        addNode(g.addAssignmentNode());
    }

    public void visitCall(Call s) {
        addNode(g.addAssignmentNode());
    }

    public void visitMethodHead(MethodHead s) {
        addNode(g.addAssignmentNode());
    }

    public void visitNop(Nop s) {
    }

    public void visitReturn(Return s) {
    }

    public void visitStringAssignment(StringAssignment s) {
        addNode(g.addAssignmentNode());
    }

    public void visitStringBufferAppend(StringBufferAppend s) {
        addNode(g.addConcatenationNode());
    }

    public void visitStringBufferAssignment(StringBufferAssignment s) {
        addNode(g.addAssignmentNode());
    }

    public void visitStringBufferBinaryOp(StringBufferBinaryOp s) {
        addNode(g.addBinaryNode(s.op));
    }

    public void visitStringBufferCorrupt(StringBufferCorrupt s) {
        addNode(g.addInitializationNode(corruptAutomaton));
    }

    public void visitStringBufferInit(StringBufferInit s) {
        addNode(g.addAssignmentNode());
    }

    public void visitStringBufferPrepend(StringBufferPrepend s) {
        addNode(g.addConcatenationNode());
    }

    public void visitStringBufferUnaryOp(StringBufferUnaryOp s) {
        addNode(g.addUnaryNode(s.op));
    }

    public void visitStringConcat(StringConcat s) {
        addNode(g.addConcatenationNode());
    }

    public void visitStringFromArray(StringFromArray s) {
        if (aa.getInfoBefore(s).isCorrupt(s.from)) {
            addNode(g.addInitializationNode(corruptAutomaton));
        } else {
            addNode(g.addAssignmentNode());
        }
    }
    public void visitPrimitiveFromArray(PrimitiveFromArray s) {
        if (aa.getInfoBefore(s).isCorrupt(s.from)) {
            addNode(g.addInitializationNode(Automaton.makeAnyChar()));
        } else {
            addNode(g.addAssignmentNode());
        }
    }

    public void visitStringFromStringBuffer(StringFromStringBuffer s) {
        if (aa.getInfoBefore(s).isCorrupt(s.from)) {
            addNode(g.addInitializationNode(corruptAutomaton));
        } else {
            addNode(g.addAssignmentNode());
        }
    }

    public void visitStringInit(StringInit s) {
        addNode(g.addInitializationNode(s.regexp));
    }
   
  public void visitObjectAssignment(ObjectAssignment s) {
    addNode(g.addAssignmentNode());
  }
 
  public void visitObjectCorrupt(ObjectCorrupt s) {
    addNode(g.addInitializationNode(corruptAutomaton));
  }
 
  public void visitHotspot(Hotspot s) {
    addNode(g.addAssignmentNode());
  }
 
  public void visitFieldAssignment(FieldAssignment s) {
    addNode(g.addAssignmentNode());
  }
 
  public void visitFieldReference(FieldReference s) {
    addNode(g.addAssignmentNode());
  }
 
  public void visitCatch(Catch s) {
    addNode(g.addAssignmentNode());
  }
  public void visitExceptionalReturn(ExceptionalReturn s) {
    addNode(g.addAssignmentNode());
  }
}
TOP

Related Classes of dk.brics.string.intermediate.operations.FlowGraphNodeCreator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.