package tools.argumentTainter; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import neo4j.readWriteDB.Neo4JDBInterface; import neo4j.traversals.readWriteDB.Traversals; import org.neo4j.graphdb.DynamicRelationshipType; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.RelationshipType; import udg.useDefAnalysis.ASTDefUseAnalyzer; import udg.useDefGraph.ReadWriteDbASTProvider; import udg.useDefGraph.UseOrDef; import databaseNodes.EdgeTypes; import ddg.DefUseCFG.DefUseCFG; public class DefUseCFGPatcher { List<DefUseLink> newlyAddedLinks = new LinkedList<DefUseLink>(); DefUseCFG defUseCFG; ASTDefUseAnalyzer astDefUseAnalyzer = new ASTDefUseAnalyzer(); public class DefUseLink { public DefUseLink(String aSymbol, Long aStatementId, boolean aIsDef) { symbol = aSymbol; statement = aStatementId; isDef = aIsDef; } public String symbol; public long statement; public boolean isDef; } static final Map<String, Object> EMPTY_PROPERTIES = new HashMap<String, Object>(); public void setSourceToPatch(String sourceToPatch, int argToPatch) { astDefUseAnalyzer.addTaintSource(sourceToPatch, argToPatch); } public Collection<DefUseLink> getDefUseLinksToAdd() { return newlyAddedLinks; } public void patchDefUseCFG(DefUseCFG defUseCFG, Collection<Node> statementsToPatch) { this.defUseCFG = defUseCFG; newlyAddedLinks.clear(); for (Node statement : statementsToPatch) { if(statement == null) continue; long statementId = statement.getId(); Node node = Traversals.getASTForStatement(statement); ReadWriteDbASTProvider astProvider = new ReadWriteDbASTProvider(); astProvider.setNodeId(node.getId()); Collection<UseOrDef> newDefs = astDefUseAnalyzer .analyzeAST(astProvider); Collection<Object> oldDefs = defUseCFG .getSymbolsDefinedBy(statementId); updateDefsToAdd(oldDefs, newDefs, statementId); } } private void updateDefsToAdd(Collection<Object> oldDefs, Collection<UseOrDef> newDefs, Long statementId) { for (UseOrDef newDef : newDefs) { if (oldDefs.contains(newDef.symbol)) continue; if (!newDef.isDef) continue; DefUseLink e = new DefUseLink(newDef.symbol, statementId, newDef.isDef); // add to newlyAddedLinks newlyAddedLinks.add(e); defUseCFG.addSymbolDefined(statementId, newDef.symbol); // Add def-links from AST nodes to symbols long nodeId = ((ReadWriteDbASTProvider) newDef.astProvider) .getNodeId(); if (statementId != nodeId) { DefUseLink e2 = new DefUseLink(newDef.symbol, nodeId, newDef.isDef); newlyAddedLinks.add(e2); defUseCFG.addSymbolDefined(nodeId, newDef.symbol); } } } public void writeChangesToDatabase() { if (defUseCFG == null) { System.out.println("defUseCFG is null"); return; } for (DefUseLink link : newlyAddedLinks) { Long fromId = link.statement; Long toId = (Long) defUseCFG.getIdForSymbol(link.symbol); if (toId == null) { Map<String, Object> properties = new HashMap<String, Object>(); Node statementNode = Neo4JDBInterface.getNodeById(link.statement); properties.put("functionId", statementNode.getProperty("functionId")); properties.put("type", "Symbol"); properties.put("code", link.symbol); Node symbolNode = Neo4JDBInterface.addNode(properties); toId = (Long) symbolNode.getId(); } RelationshipType relType = DynamicRelationshipType .withName(EdgeTypes.DEF); Neo4JDBInterface.addRelationship(fromId, toId, relType, null); } } }