def enter_function_call(self, ctx): if self.do_not_parse != 0: return self.reset_tracking() func = self.unparse_node(ctx) cn = CodeNode(self.get_location(ctx.lineno), func) cn.set_vars(self.get_tracked_vars()) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) cn.set_node_type(FunctionCall) self.set_exit_nodes(self.add_node(cn))
def enter_echo(self, ctx): if self.do_not_parse == 0: self.reset_tracking() self.stmt_funcs.add('echo') if all( self.is_tainted(x) == Tainted.NOT_TAINTED for x in ctx.nodes): tainted = Tainted.NOT_TAINTED else: tainted = Tainted.MAYBE_TAINTED cn = CodeNode(self.get_location(ctx.lineno), 'echo', 'echo %s' % ''.join(self.unparse_node(x) for x in ctx.nodes), tainted=tainted) cn.set_vars(self.get_tracked_vars()) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) self.set_exit_nodes(self.add_node(cn)) self.do_not_parse += 1
def get_graph(self): if len(self.exit_nodes) > 1: empty = CodeNode(("", -1), 'empty') self.add_node(empty) for cn in [ x for x in self.G.nodes_iter() if x.get_node_type() == FunctionCall ]: func_id = self.generate_func_id(cn.get_stmt()) if func_id in self.functions: (start_node, end_node) = self.functions[func_id] self.add_edge(cn, start_node) self.add_edge(end_node, cn) change = True # Calculate inset and outset for Reaching Definitions while change: change = False for n in self.G.nodes_iter(): n.inset = reduce(lambda x, y: x | y, [0] + [x.outset for x in self.G.predecessors(n)]) old_outset = n.outset n.outset = n.gen | (n.inset & ~n.kill) if old_outset != n.outset: change = True return self.G
def enter_while(self, ctx): if self.do_not_parse != 0: return self.reset_tracking() # Get the expression between the parenthesis expr = self.unparse_node(ctx.expr) if isinstance(ctx.expr, Assignment): # We found an assignment in the expression assign = self.unparse_node(ctx.expr.node) tainted = self.is_tainted(ctx.expr.node) else: assign = None tainted = Tainted.MAYBE_TAINTED cn = self.add_node( CodeNode(self.get_location(ctx.lineno), 'while', text='while (%s)' % expr, assign=assign, tainted=tainted)) cn.set_vars(self.get_tracked_vars()) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) self.while_nodes.append(cn) self.set_exit_nodes(cn)
def enter_foreach(self, ctx): if self.do_not_parse != 0: return n = self.add_node(CodeNode(self.get_location(ctx.lineno), 'foreach')) self.for_nodes.append(n) self.set_exit_nodes(n)
def enter_do_while(self, ctx): if self.do_not_parse != 0: return n = self.add_node(CodeNode(self.get_location(ctx.lineno), 'do')) self.do_nodes.append(n) self.set_exit_nodes(n)
def enter_return(self, ctx): if self.do_not_parse == 0: cn = self.add_node( CodeNode(self.get_location(ctx.lineno), 'return', self.unparse_node(ctx))) cn.set_vars(self.get_tracked_vars()) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) self.do_not_parse += 1
def enter_for(self, ctx): if self.do_not_parse != 0: return # TODO: Figure out how to get the expression out n = self.add_node(CodeNode(self.get_location(ctx.lineno), 'for', 'for')) self.for_nodes.append(n) self.set_exit_nodes(n)
def exit_foreach(self, ctx): if self.do_not_parse != 0: return foreach_node = self.for_nodes.pop() if len(self.exit_nodes) > 1: self.set_exit_nodes(self.add_node(CodeNode(("", -1), 'empty'))) # TODO if len(self.exit_nodes) > 0: self.add_edge(self.exit_nodes[0], foreach_node)
def enter_if(self, ctx): if self.do_not_parse != 0: return self.reset_tracking() expr = self.unparse_node(ctx.expr) cn = None assign = None if isinstance(ctx.expr, BinaryOp): if isinstance(ctx.expr.left, Assignment): assign = self.unparse_node(ctx.expr.left.node) cn = self.add_node( CodeNode(self.get_location(ctx.lineno), 'if', 'if (%s)' % expr, assign=assign)) elif isinstance(ctx.expr.right, Assignment): assign = self.unparse_node(ctx.expr.right.node) cn = self.add_node( CodeNode(self.get_location(ctx.lineno), 'if', 'if (%s)' % expr, assign=assign)) if cn is None: cn = self.add_node( CodeNode(self.get_location(ctx.lineno), 'if', 'if (%s)' % expr)) cn.set_vars(self.get_tracked_vars() - {assign}) cn.set_funcs(self.get_tracked_funcs()) self.if_nodes.append((cn, False)) self.set_exit_nodes(cn)
def exit_while(self, ctx): if self.do_not_parse != 0: return while_node = self.while_nodes.pop() if len(self.exit_nodes) > 1: self.set_exit_nodes(self.add_node(CodeNode(("", -1), 'empty'))) # TODO if len(self.exit_nodes) > 0: self.add_edge(self.exit_nodes[0], while_node) self.add_exit_node(while_node)
def enter_assign_op(self, ctx): if self.do_not_parse != 0: return self.reset_tracking() expr = self.unparse_node(ctx) assign = self.unparse_node(ctx.left) cn = CodeNode(self.get_location(ctx.lineno), 'expression', assign=assign, text=expr, tainted=self.is_tainted(ctx.right)) cn.set_vars(self.get_tracked_vars() - {assign}) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) self.set_exit_nodes(self.add_node(cn))
def exit_do_while(self, ctx): if self.do_not_parse != 0: return self.reset_tracking() # Get the expression between the parenthesis expr = self.unparse_node(ctx.expr) do_node = self.do_nodes.pop() cn = CodeNode(self.get_location(ctx.lineno), 'while', 'while (%s)' % expr) cn.set_vars(self.get_tracked_vars()) cn.set_funcs(self.get_tracked_funcs()) cn.set_consts(self.get_tracked_consts()) self.set_exit_nodes(self.add_node(cn)) self.add_edge(self.exit_nodes[0], do_node)