コード例 #1
0
    def _parse_dowhile(self, doWhilestatement, node):

        node_startDoWhile = self._new_node(NodeType.STARTLOOP,
                                           doWhilestatement['src'])
        node_condition = self._new_node(NodeType.IFLOOP,
                                        doWhilestatement['src'])

        if self.is_compact_ast:
            node_condition.add_unparsed_expression(
                doWhilestatement['condition'])
            statement = self._parse_statement(doWhilestatement['body'],
                                              node_condition)
        else:
            children = doWhilestatement[self.get_children('children')]
            # same order in the AST as while
            expression = children[0]
            node_condition.add_unparsed_expression(expression)
            statement = self._parse_statement(children[1], node_condition)

        node_endDoWhile = self._new_node(NodeType.ENDLOOP,
                                         doWhilestatement['src'])

        link_nodes(node, node_startDoWhile)
        # empty block, loop from the start to the condition
        if not node_condition.sons:
            link_nodes(node_startDoWhile, node_condition)
        else:
            link_nodes(node_startDoWhile, node_condition.sons[0])
        link_nodes(statement, node_condition)
        link_nodes(node_condition, node_endDoWhile)
        return node_endDoWhile
コード例 #2
0
ファイル: modifier.py プロジェクト: w1r2p1/slither
 def _parse_statement(self, statement, node):
     name = statement['name']
     if name == 'PlaceholderStatement':
         placeholder_node = self._new_node(NodeType.PLACEHOLDER)
         link_nodes(node, placeholder_node)
         return placeholder_node
     return super(ModifierSolc, self)._parse_statement(statement, node)
コード例 #3
0
ファイル: function.py プロジェクト: ttamna/slither
    def _parse_if(self, ifStatement, node):
        # IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?
        falseStatement = None

        if self.is_compact_ast:
            condition = ifStatement['condition']
            # Note: check if the expression could be directly
            # parsed here
            condition_node = self._new_node(NodeType.IF, ifStatement['src'])
            condition_node.add_unparsed_expression(condition)
            link_nodes(node, condition_node)
            trueStatement = self._parse_statement(ifStatement['trueBody'], condition_node)
            if ifStatement['falseBody']:
                falseStatement = self._parse_statement(ifStatement['falseBody'], condition_node)
        else:
            children = ifStatement[self.get_children('children')]
            condition = children[0]
            # Note: check if the expression could be directly
            # parsed here
            condition_node = self._new_node(NodeType.IF, ifStatement['src'])
            condition_node.add_unparsed_expression(condition)
            link_nodes(node, condition_node)
            trueStatement = self._parse_statement(children[1], condition_node)
            if len(children) == 3:
                falseStatement = self._parse_statement(children[2], condition_node)

        endIf_node = self._new_node(NodeType.ENDIF, ifStatement['src'])
        link_nodes(trueStatement, endIf_node)

        if falseStatement:
            link_nodes(falseStatement, endIf_node)
        else:
            link_nodes(condition_node, endIf_node)
        return endIf_node
コード例 #4
0
ファイル: modifier.py プロジェクト: zeta1999/slither
 def _parse_statement(self, statement: Dict, node: NodeSolc) -> NodeSolc:
     name = statement[self.get_key()]
     if name == "PlaceholderStatement":
         placeholder_node = self._new_node(NodeType.PLACEHOLDER,
                                           statement["src"])
         link_nodes(node.underlying_node, placeholder_node.underlying_node)
         return placeholder_node
     return super(ModifierSolc, self)._parse_statement(statement, node)
コード例 #5
0
 def _parse_statement(
     self, statement: Dict, node: NodeSolc, scope: Union[Scope, "Function"]
 ) -> NodeSolc:
     name = statement[self.get_key()]
     if name == "PlaceholderStatement":
         placeholder_node = self._new_node_id(NodeType.PLACEHOLDER, statement["src"], scope, statement["id"])
         link_nodes(node.underlying_node, placeholder_node.underlying_node)
         return placeholder_node
     return super()._parse_statement(statement, node, scope)
コード例 #6
0
ファイル: functionSolc.py プロジェクト: f0829/slither
    def _parse_variable_definition_init_tuple(self, statement, index, node):
        local_var = LocalVariableInitFromTupleSolc(statement, index)
        #local_var = LocalVariableSolc(statement['children'][0], statement['children'][1::])
        local_var.set_function(self)
        local_var.set_offset(statement['src'])

        self._variables[local_var.name] = local_var
        #        local_var.analyze(self)

        new_node = self._new_node(NodeType.VARIABLE)
        new_node.add_variable_declaration(local_var)
        link_nodes(node, new_node)
        return new_node
コード例 #7
0
    def _parse_variable_definition_init_tuple(self, statement, index, node):
        local_var = LocalVariableInitFromTupleSolc(statement, index)
        #local_var = LocalVariableSolc(statement[self.get_children('children')][0], statement[self.get_children('children')][1::])
        local_var.set_function(self)
        local_var.set_offset(statement['src'], self.contract.slither)

        self._add_local_variable(local_var)
        #        local_var.analyze(self)

        new_node = self._new_node(NodeType.VARIABLE, statement['src'])
        new_node.add_variable_declaration(local_var)
        link_nodes(node, new_node)
        return new_node
コード例 #8
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def _parse_if(self, ifStatement, node):
        # IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )?

        children = ifStatement['children']
        condition_node = self._new_node(NodeType.IF)
        #condition = parse_expression(children[0], self)
        condition = children[0]
        condition_node.add_unparsed_expression(condition)

        link_nodes(node, condition_node)

        trueStatement = self._parse_statement(children[1], condition_node)

        endIf_node = self._new_node(NodeType.ENDIF)
        link_nodes(trueStatement, endIf_node)

        if len(children) == 3:
            falseStatement = self._parse_statement(children[2], condition_node)

            link_nodes(falseStatement, endIf_node)

        else:
            link_nodes(condition_node, endIf_node)

        return endIf_node
コード例 #9
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def split_ternary_node(self, node, condition, true_expr, false_expr):
        condition_node = self._new_node(NodeType.IF)
        condition_node.add_expression(condition)
        condition_node.analyze_expressions(self)

        true_node = self._new_node(node.type)
        true_node.add_expression(true_expr)
        true_node.analyze_expressions(self)

        false_node = self._new_node(node.type)
        false_node.add_expression(false_expr)
        false_node.analyze_expressions(self)

        endif_node = self._new_node(NodeType.ENDIF)

        for father in node.fathers:
            father.remove_son(node)
            father.add_son(condition_node)
            condition_node.add_father(father)

        for son in node.sons:
            son.remove_father(node)
            son.add_father(endif_node)
            endif_node.add_son(son)

        link_nodes(condition_node, true_node)
        link_nodes(condition_node, false_node)

        link_nodes(true_node, endif_node)
        link_nodes(false_node, endif_node)

        self._nodes = [n for n in self._nodes if n.node_id != node.node_id]
コード例 #10
0
    def _parse_while(self, whileStatement, node):
        # WhileStatement = 'while' '(' Expression ')' Statement

        node_startWhile = self._new_node(NodeType.STARTLOOP,
                                         whileStatement['src'])
        node_condition = self._new_node(NodeType.IFLOOP, whileStatement['src'])

        if self.is_compact_ast:
            node_condition.add_unparsed_expression(whileStatement['condition'])
            statement = self._parse_statement(whileStatement['body'],
                                              node_condition)
        else:
            children = whileStatement[self.get_children('children')]
            expression = children[0]
            node_condition.add_unparsed_expression(expression)
            statement = self._parse_statement(children[1], node_condition)

        node_endWhile = self._new_node(NodeType.ENDLOOP, whileStatement['src'])

        link_nodes(node, node_startWhile)
        link_nodes(node_startWhile, node_condition)
        link_nodes(statement, node_condition)
        link_nodes(node_condition, node_endWhile)

        return node_endWhile
コード例 #11
0
    def _parse_while(self, whileStatement, node):
        # WhileStatement = 'while' '(' Expression ')' Statement

        node_startWhile = self._new_node(NodeType.STARTLOOP, whileStatement['src'])

        if self.is_compact_ast:
            node_condition = self._new_node(NodeType.IFLOOP, whileStatement['condition']['src'])
            node_condition.add_unparsed_expression(whileStatement['condition'])
            statement = self._parse_statement(whileStatement['body'], node_condition)
            # print('yufeng hack while....', whileStatement['body'])
            stmt_number = 0
            for stmt in whileStatement['body']['statements']:
                stmt_number = stmt_number + self.count_stmts(stmt)
                # print('nodeType:', stmt['nodeType'], stmt['expression'], ('kind' in stmt['expression']))
            
            print('find out a while-loop---: ', stmt_number)
        else:
            children = whileStatement[self.get_children('children')]
            expression = children[0]
            node_condition = self._new_node(NodeType.IFLOOP, expression['src'])
            node_condition.add_unparsed_expression(expression)
            statement = self._parse_statement(children[1], node_condition)

        node_endWhile = self._new_node(NodeType.ENDLOOP, whileStatement['src'])

        link_nodes(node, node_startWhile)
        link_nodes(node_startWhile, node_condition)
        link_nodes(statement, node_condition)
        link_nodes(node_condition, node_endWhile)

        return node_endWhile
コード例 #12
0
ファイル: function.py プロジェクト: wangke0809/slither
    def _parse_try_catch(self, statement, node):
        externalCall = statement.get('externalCall', None)

        if externalCall is None:
            raise ParsingError('Try/Catch not correctly parsed by Slither %s' %
                               statement)

        new_node = self._new_node(NodeType.TRY, statement['src'])
        new_node.add_unparsed_expression(externalCall)
        link_nodes(node, new_node)
        node = new_node

        for clause in statement.get('clauses', []):
            self._parse_catch(clause, node)
        return node
コード例 #13
0
    def _parse_catch(self, statement, node):
        block = statement.get('block', None)
        if block is None:
            raise ParsingError('Catch not correctly parsed by Slither %s' %
                               statement)
        try_node = self._new_node(NodeType.CATCH, statement['src'])
        link_nodes(node, try_node)

        if self.is_compact_ast:
            params = statement['parameters']
        else:
            params = statement[self.get_children('children')]

        for param in params.get('parameters', []):
            assert param[self.get_key()] == 'VariableDeclaration'
            self._add_param(param)

        return self._parse_statement(block, try_node)
コード例 #14
0
 def _parse_modifier(self, modifier):
     m = parse_expression(modifier, self)
     self._expression_modifiers.append(m)
     for m in ExportValues(m).result():
         if isinstance(m, Function):
             entry_point = self._new_node(NodeType.OTHER_ENTRYPOINT, modifier['src'])
             node = self._new_node(NodeType.EXPRESSION, modifier['src'])
             node.add_unparsed_expression(modifier)
             link_nodes(entry_point, node)
             self._modifiers.append(ModifierStatements(modifier=m,
                                                       entry_point=entry_point,
                                                       nodes=[entry_point, node]))
         elif isinstance(m, Contract):
             entry_point = self._new_node(NodeType.OTHER_ENTRYPOINT, modifier['src'])
             node = self._new_node(NodeType.EXPRESSION, modifier['src'])
             node.add_unparsed_expression(modifier)
             link_nodes(entry_point, node)
             self._explicit_base_constructor_calls.append(ModifierStatements(modifier=m,
                                                                             entry_point=entry_point,
                                                                             nodes=[entry_point, node]))
コード例 #15
0
ファイル: function.py プロジェクト: ttamna/slither
    def split_ternary_node(self, node, condition, true_expr, false_expr):
        condition_node = self._new_node(NodeType.IF, node.source_mapping)
        condition_node.add_expression(condition)
        condition_node.analyze_expressions(self)

        if node.type == NodeType.VARIABLE:
            condition_node.add_variable_declaration(node.variable_declaration)

        true_node = self._new_node(NodeType.EXPRESSION, node.source_mapping)
        if node.type == NodeType.VARIABLE:
            assert isinstance(true_expr, AssignmentOperation)
            #true_expr = true_expr.expression_right
        elif node.type == NodeType.RETURN:
            true_node.type = NodeType.RETURN
        true_node.add_expression(true_expr)
        true_node.analyze_expressions(self)

        false_node = self._new_node(NodeType.EXPRESSION, node.source_mapping)
        if node.type == NodeType.VARIABLE:
            assert isinstance(false_expr, AssignmentOperation)
        elif node.type == NodeType.RETURN:
            false_node.type = NodeType.RETURN
            #false_expr = false_expr.expression_right
        false_node.add_expression(false_expr)
        false_node.analyze_expressions(self)

        endif_node = self._new_node(NodeType.ENDIF, node.source_mapping)

        for father in node.fathers:
            father.remove_son(node)
            father.add_son(condition_node)
            condition_node.add_father(father)

        for son in node.sons:
            son.remove_father(node)
            son.add_father(endif_node)
            endif_node.add_son(son)

        link_nodes(condition_node, true_node)
        link_nodes(condition_node, false_node)


        if not true_node.type in [NodeType.THROW, NodeType.RETURN]:
           link_nodes(true_node, endif_node)
        if not false_node.type in [NodeType.THROW, NodeType.RETURN]:
            link_nodes(false_node, endif_node)

        self._nodes = [n for n in self._nodes if n.node_id != node.node_id]
コード例 #16
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def _parse_dowhile(self, doWhilestatement, node):
        children = doWhilestatement['children']

        node_startDoWhile = self._new_node(NodeType.STARTLOOP)

        # same order in the AST as while
        node_condition = self._new_node(NodeType.IFLOOP)
        #expression = parse_expression(children[0], self)
        expression = children[0]
        node_condition.add_unparsed_expression(expression)

        statement = self._parse_statement(children[1], node_condition)
        node_endDoWhile = self._new_node(NodeType.ENDLOOP)

        link_nodes(node, node_startDoWhile)
        link_nodes(node_startDoWhile, node_condition)
        link_nodes(statement, node_condition)
        link_nodes(node_condition, node_endDoWhile)

        return node_endDoWhile
コード例 #17
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def _parse_while(self, whileStatement, node):
        # WhileStatement = 'while' '(' Expression ')' Statement

        children = whileStatement['children']

        node_startWhile = self._new_node(NodeType.STARTLOOP)

        node_condition = self._new_node(NodeType.IFLOOP)
        #expression = parse_expression(children[0], self)
        expression = children[0]
        node_condition.add_unparsed_expression(expression)

        statement = self._parse_statement(children[1], node_condition)

        node_endWhile = self._new_node(NodeType.ENDLOOP)

        link_nodes(node, node_startWhile)
        link_nodes(node_startWhile, node_condition)
        link_nodes(statement, node_condition)
        link_nodes(node_condition, node_endWhile)

        return node_endWhile
コード例 #18
0
    def split_ternary_node(self, node, condition, true_expr, false_expr):
        condition_node = self._new_node(NodeType.IF, node.source_mapping)
        condition_node.add_expression(condition)
        condition_node.analyze_expressions(self)

        true_node = self._new_node(node.type, node.source_mapping)
        if node.type == NodeType.VARIABLE:
            true_node.add_variable_declaration(node.variable_declaration)
        true_node.add_expression(true_expr)
        true_node.analyze_expressions(self)

        false_node = self._new_node(node.type, node.source_mapping)
        if node.type == NodeType.VARIABLE:
            false_node.add_variable_declaration(node.variable_declaration)
        false_node.add_expression(false_expr)
        false_node.analyze_expressions(self)

        endif_node = self._new_node(NodeType.ENDIF, node.source_mapping)

        for father in node.fathers:
            father.remove_son(node)
            father.add_son(condition_node)
            condition_node.add_father(father)

        for son in node.sons:
            son.remove_father(node)
            son.add_father(endif_node)
            endif_node.add_son(son)

        link_nodes(condition_node, true_node)
        link_nodes(condition_node, false_node)


        if not true_node.type in [NodeType.THROW, NodeType.RETURN]:
           link_nodes(true_node, endif_node)
        if not false_node.type in [NodeType.THROW, NodeType.RETURN]:
            link_nodes(false_node, endif_node)

        self._nodes = [n for n in self._nodes if n.node_id != node.node_id]
コード例 #19
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def _parse_variable_definition(self, statement, node):
        #assert len(statement['children']) == 1
        # if there is, parse default value
        #assert not 'attributes' in statement 

        try:
            local_var = LocalVariableSolc(statement)
            #local_var = LocalVariableSolc(statement['children'][0], statement['children'][1::])
            local_var.set_function(self)
            local_var.set_offset(statement['src'], self.contract.slither)

            self._variables[local_var.name] = local_var
            #local_var.analyze(self)

            new_node = self._new_node(NodeType.VARIABLE)
            new_node.add_variable_declaration(local_var)
            link_nodes(node, new_node)
            return new_node
        except MultipleVariablesDeclaration:
            # Custom handling of var (a,b) = .. style declaration
            # We split the variabledeclaration in multiple declarations
            count = 0
            children = statement['children']
            child = children[0]
            while child['name'] == 'VariableDeclaration':
                count = count +1
                child = children[count]

            assert len(children) == (count + 1)
            tuple_vars = children[count]


            variables_declaration = children[0:count]
            i = 0
            new_node = node
            if tuple_vars['name'] == 'TupleExpression':
                assert len(tuple_vars['children']) == count
                for variable in variables_declaration:
                    init = tuple_vars['children'][i]
                    src = variable['src']
                    i= i+1
                    # Create a fake statement to be consistent
                    new_statement = {'name':'VariableDefinitionStatement',
                                     'src': src,
                                     'children':[variable, init]}

                    new_node = self._parse_variable_definition(new_statement, new_node)
            else:
                # If we have
                # var (a, b) = f()
                # we can split in multiple declarations, keep the init value and use LocalVariableSolc
                # We use LocalVariableInitFromTupleSolc class 
                assert tuple_vars['name'] in ['FunctionCall', 'Conditional']
                for variable in variables_declaration:
                    src = variable['src']
                    i= i+1
                    # Create a fake statement to be consistent
                    new_statement = {'name':'VariableDefinitionStatement',
                                     'src': src,
                                     'children':[variable, tuple_vars]}

                    new_node = self._parse_variable_definition_init_tuple(new_statement, i, new_node)
            return new_node
コード例 #20
0
    def _parse_for_compact_ast(self, statement, node):
        body = statement['body']
        init_expression = statement['initializationExpression']
        condition = statement['condition']
        loop_expression = statement['loopExpression']
        stmt_number = 0
        for stmt in body['statements']:
            stmt_number = stmt_number + self.count_stmts(stmt)
        
        print('find out a for-loop---: ', stmt_number)

        node_startLoop = self._new_node(NodeType.STARTLOOP, statement['src'])
        node_endLoop = self._new_node(NodeType.ENDLOOP, statement['src'])

        if init_expression:
            node_init_expression = self._parse_statement(init_expression, node)
            link_nodes(node_init_expression, node_startLoop)
        else:
            link_nodes(node, node_startLoop)

        if condition:
            node_condition = self._new_node(NodeType.IFLOOP, condition['src'])
            node_condition.add_unparsed_expression(condition)
            link_nodes(node_startLoop, node_condition)
            link_nodes(node_condition, node_endLoop)
        else:
            node_condition = node_startLoop

        node_body = self._parse_statement(body, node_condition)

        if loop_expression:
            node_LoopExpression = self._parse_statement(loop_expression, node_body)
            link_nodes(node_LoopExpression, node_condition)
        else:
            link_nodes(node_body, node_condition)

        if not condition:
            if not loop_expression:
                # TODO: fix case where loop has no expression
                link_nodes(node_startLoop, node_endLoop)
            else:
                link_nodes(node_LoopExpression, node_endLoop)

        return node_endLoop
コード例 #21
0
    def _parse_statement(self, statement, node):
        """

        Return:
            node
        """
        # Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement |
        #            ( DoWhileStatement | PlaceholderStatement | Continue | Break | Return |
        #                          Throw | EmitStatement | SimpleStatement ) ';'
        # SimpleStatement = VariableDefinition | ExpressionStatement

        name = statement[self.get_key()]
        # SimpleStatement = VariableDefinition | ExpressionStatement
        if name == 'IfStatement':
            node = self._parse_if(statement, node)
        elif name == 'WhileStatement':
            node = self._parse_while(statement, node)
        elif name == 'ForStatement':
            node = self._parse_for(statement, node)
        elif name == 'Block':
            node = self._parse_block(statement, node)
        elif name == 'InlineAssembly':
            break_node = self._new_node(NodeType.ASSEMBLY, statement['src'])
            self._contains_assembly = True
            link_nodes(node, break_node)
            node = break_node
        elif name == 'DoWhileStatement':
            node = self._parse_dowhile(statement, node)
        # For Continue / Break / Return / Throw
        # The is fixed later
        elif name == 'Continue':
            continue_node = self._new_node(NodeType.CONTINUE, statement['src'])
            link_nodes(node, continue_node)
            node = continue_node
        elif name == 'Break':
            break_node = self._new_node(NodeType.BREAK, statement['src'])
            link_nodes(node, break_node)
            node = break_node
        elif name == 'Return':
            return_node = self._new_node(NodeType.RETURN, statement['src'])
            link_nodes(node, return_node)
            if self.is_compact_ast:
                if statement['expression']:
                    return_node.add_unparsed_expression(
                        statement['expression'])
            else:
                if self.get_children('children') in statement and statement[
                        self.get_children('children')]:
                    assert len(statement[self.get_children('children')]) == 1
                    expression = statement[self.get_children('children')][0]
                    return_node.add_unparsed_expression(expression)
            node = return_node
        elif name == 'Throw':
            throw_node = self._new_node(NodeType.THROW, statement['src'])
            link_nodes(node, throw_node)
            node = throw_node
        elif name == 'EmitStatement':
            #expression = parse_expression(statement[self.get_children('children')][0], self)
            if self.is_compact_ast:
                expression = statement['eventCall']
            else:
                expression = statement[self.get_children('children')][0]
            new_node = self._new_node(NodeType.EXPRESSION, statement['src'])
            new_node.add_unparsed_expression(expression)
            link_nodes(node, new_node)
            node = new_node
        elif name in [
                'VariableDefinitionStatement', 'VariableDeclarationStatement'
        ]:
            node = self._parse_variable_definition(statement, node)
        elif name == 'ExpressionStatement':
            #assert len(statement[self.get_children('expression')]) == 1
            #assert not 'attributes' in statement
            #expression = parse_expression(statement[self.get_children('children')][0], self)
            if self.is_compact_ast:
                expression = statement[self.get_children('expression')]
            else:
                expression = statement[self.get_children('expression')][0]
            new_node = self._new_node(NodeType.EXPRESSION, statement['src'])
            new_node.add_unparsed_expression(expression)
            link_nodes(node, new_node)
            node = new_node
        else:
            logger.error('Statement not parsed %s' % name)
            exit(-1)

        return node
コード例 #22
0
ファイル: function.py プロジェクト: samparsky/slither
    def _parse_variable_definition(self, statement, node):
        #assert len(statement['children']) == 1
        # if there is, parse default value
        #assert not 'attributes' in statement

        try:
            local_var = LocalVariableSolc(statement)
            #local_var = LocalVariableSolc(statement['children'][0], statement['children'][1::])
            local_var.set_function(self)
            local_var.set_offset(statement['src'], self.contract.slither)

            self._variables[local_var.name] = local_var
            #local_var.analyze(self)

            new_node = self._new_node(NodeType.VARIABLE)
            new_node.add_variable_declaration(local_var)
            link_nodes(node, new_node)
            return new_node
        except MultipleVariablesDeclaration:
            # Custom handling of var (a,b) = .. style declaration
            count = 0
            children = statement['children']
            child = children[0]
            while child['name'] == 'VariableDeclaration':
                count = count + 1
                child = children[count]

            assert len(children) == (count + 1)
            tuple_vars = children[count]

            variables_declaration = children[0:count]
            i = 0
            new_node = node
            if tuple_vars['name'] == 'TupleExpression':
                assert len(tuple_vars['children']) == count
                for variable in variables_declaration:
                    init = tuple_vars['children'][i]
                    src = variable['src']
                    i = i + 1
                    # Create a fake statement to be consistent
                    new_statement = {
                        'name': 'VariableDefinitionStatement',
                        'src': src,
                        'children': [variable, init]
                    }

                    new_node = self._parse_variable_definition(
                        new_statement, new_node)
            else:
                # If we have
                # var (a, b) = f()
                # we can split in multiple declarations, without init
                # Then we craft one expression that does not assignment
                assert tuple_vars['name'] in ['FunctionCall', 'Conditional']
                variables = []
                for variable in variables_declaration:
                    src = variable['src']
                    i = i + 1
                    # Create a fake statement to be consistent
                    new_statement = {
                        'name': 'VariableDefinitionStatement',
                        'src': src,
                        'children': [variable]
                    }
                    variables.append(variable)

                    new_node = self._parse_variable_definition_init_tuple(
                        new_statement, i, new_node)
                var_identifiers = []
                # craft of the expression doing the assignement
                for v in variables:
                    identifier = {
                        'name': 'Identifier',
                        'src': v['src'],
                        'attributes': {
                            'value': v['attributes']['name'],
                            'type': v['attributes']['type']
                        }
                    }
                    var_identifiers.append(identifier)

                expression = {
                    'name':
                    'Assignment',
                    'src':
                    statement['src'],
                    'attributes': {
                        'operator': '=',
                        'type': 'tuple()'
                    },
                    'children': [{
                        'name': 'TupleExpression',
                        'src': statement['src'],
                        'children': var_identifiers
                    }, tuple_vars]
                }
                node = new_node
                new_node = self._new_node(NodeType.EXPRESSION)
                new_node.add_unparsed_expression(expression)
                link_nodes(node, new_node)

            return new_node
コード例 #23
0
    def _parse_variable_definition(self, statement, node):
        try:
            local_var = LocalVariableSolc(statement)
            local_var.set_function(self)
            local_var.set_offset(statement['src'], self.contract.slither)

            self._add_local_variable(local_var)
            #local_var.analyze(self)

            new_node = self._new_node(NodeType.VARIABLE, statement['src'])
            new_node.add_variable_declaration(local_var)
            link_nodes(node, new_node)
            return new_node
        except MultipleVariablesDeclaration:
            # Custom handling of var (a,b) = .. style declaration
            if self.is_compact_ast:
                variables = statement['declarations']
                count = len(variables)

                if statement['initialValue']['nodeType'] == 'TupleExpression':
                    inits = statement['initialValue']['components']
                    i = 0
                    new_node = node
                    for variable in variables:
                        init = inits[i]
                        src = variable['src']
                        i = i + 1

                        new_statement = {
                            'nodeType': 'VariableDefinitionStatement',
                            'src': src,
                            'declarations': [variable],
                            'initialValue': init
                        }
                        new_node = self._parse_variable_definition(
                            new_statement, new_node)

                else:
                    # If we have
                    # var (a, b) = f()
                    # we can split in multiple declarations, without init
                    # Then we craft one expression that does the assignment
                    variables = []
                    i = 0
                    new_node = node
                    for variable in statement['declarations']:
                        i = i + 1
                        if variable:
                            src = variable['src']
                            # Create a fake statement to be consistent
                            new_statement = {
                                'nodeType': 'VariableDefinitionStatement',
                                'src': src,
                                'declarations': [variable]
                            }
                            variables.append(variable)

                            new_node = self._parse_variable_definition_init_tuple(
                                new_statement, i, new_node)

                    var_identifiers = []
                    # craft of the expression doing the assignement
                    for v in variables:
                        identifier = {
                            'nodeType': 'Identifier',
                            'src': v['src'],
                            'name': v['name'],
                            'typeDescriptions': {
                                'typeString':
                                v['typeDescriptions']['typeString']
                            }
                        }
                        var_identifiers.append(identifier)

                    tuple_expression = {
                        'nodeType': 'TupleExpression',
                        'src': statement['src'],
                        'components': var_identifiers
                    }

                    expression = {
                        'nodeType': 'Assignment',
                        'src': statement['src'],
                        'operator': '=',
                        'type': 'tuple()',
                        'leftHandSide': tuple_expression,
                        'rightHandSide': statement['initialValue'],
                        'typeDescriptions': {
                            'typeString': 'tuple()'
                        }
                    }
                    node = new_node
                    new_node = self._new_node(NodeType.EXPRESSION,
                                              statement['src'])
                    new_node.add_unparsed_expression(expression)
                    link_nodes(node, new_node)

            else:
                count = 0
                children = statement[self.get_children('children')]
                child = children[0]
                while child[self.get_key()] == 'VariableDeclaration':
                    count = count + 1
                    child = children[count]

                assert len(children) == (count + 1)
                tuple_vars = children[count]

                variables_declaration = children[0:count]
                i = 0
                new_node = node
                if tuple_vars[self.get_key()] == 'TupleExpression':
                    assert len(
                        tuple_vars[self.get_children('children')]) == count
                    for variable in variables_declaration:
                        init = tuple_vars[self.get_children('children')][i]
                        src = variable['src']
                        i = i + 1
                        # Create a fake statement to be consistent
                        new_statement = {
                            self.get_key(): 'VariableDefinitionStatement',
                            'src': src,
                            self.get_children('children'): [variable, init]
                        }

                        new_node = self._parse_variable_definition(
                            new_statement, new_node)
                else:
                    # If we have
                    # var (a, b) = f()
                    # we can split in multiple declarations, without init
                    # Then we craft one expression that does the assignment
                    assert tuple_vars[self.get_key()] in [
                        'FunctionCall', 'Conditional'
                    ]
                    variables = []
                    for variable in variables_declaration:
                        src = variable['src']
                        i = i + 1
                        # Create a fake statement to be consistent
                        new_statement = {
                            self.get_key(): 'VariableDefinitionStatement',
                            'src': src,
                            self.get_children('children'): [variable]
                        }
                        variables.append(variable)

                        new_node = self._parse_variable_definition_init_tuple(
                            new_statement, i, new_node)
                    var_identifiers = []
                    # craft of the expression doing the assignement
                    for v in variables:
                        identifier = {
                            self.get_key(): 'Identifier',
                            'src': v['src'],
                            'attributes': {
                                'value': v['attributes'][self.get_key()],
                                'type': v['attributes']['type']
                            }
                        }
                        var_identifiers.append(identifier)

                    expression = {
                        self.get_key():
                        'Assignment',
                        'src':
                        statement['src'],
                        'attributes': {
                            'operator': '=',
                            'type': 'tuple()'
                        },
                        self.get_children('children'): [{
                            self.get_key():
                            'TupleExpression',
                            'src':
                            statement['src'],
                            self.get_children('children'):
                            var_identifiers
                        }, tuple_vars]
                    }
                    node = new_node
                    new_node = self._new_node(NodeType.EXPRESSION,
                                              statement['src'])
                    new_node.add_unparsed_expression(expression)
                    link_nodes(node, new_node)

            return new_node
コード例 #24
0
    def _parse_for(self, statement, node):
        # ForStatement = 'for' '(' (SimpleStatement)? ';' (Expression)? ';' (ExpressionStatement)? ')' Statement

        # the handling of loop in the legacy ast is too complex
        # to integrate the comapct ast
        # its cleaner to do it separately
        if self.is_compact_ast:
            return self._parse_for_compact_ast(statement, node)

        hasInitExession = True
        hasCondition = True
        hasLoopExpression = True

        # Old solc version do not prevent in the attributes
        # if the loop has a init value /condition or expression
        # There is no way to determine that for(a;;) and for(;a;) are different with old solc
        if 'attributes' in statement:
            attributes = statement['attributes']
            if 'initializationExpression' in statement:
                if not statement['initializationExpression']:
                    hasInitExession = False
            elif 'initializationExpression' in attributes:
                if not attributes['initializationExpression']:
                    hasInitExession = False

            if 'condition' in statement:
                if not statement['condition']:
                    hasCondition = False
            elif 'condition' in attributes:
                if not attributes['condition']:
                    hasCondition = False

            if 'loopExpression' in statement:
                if not statement['loopExpression']:
                    hasLoopExpression = False
            elif 'loopExpression' in attributes:
                if not attributes['loopExpression']:
                    hasLoopExpression = False

        node_startLoop = self._new_node(NodeType.STARTLOOP, statement['src'])
        node_endLoop = self._new_node(NodeType.ENDLOOP, statement['src'])

        children = statement[self.get_children('children')]

        if hasInitExession:
            if len(children) >= 2:
                if children[0][self.get_key()] in [
                        'VariableDefinitionStatement',
                        'VariableDeclarationStatement', 'ExpressionStatement'
                ]:
                    node_initExpression = self._parse_statement(
                        children[0], node)
                    link_nodes(node_initExpression, node_startLoop)
                else:
                    hasInitExession = False
            else:
                hasInitExession = False

        if not hasInitExession:
            link_nodes(node, node_startLoop)
        node_condition = node_startLoop

        if hasCondition:
            if hasInitExession and len(children) >= 2:
                candidate = children[1]
            else:
                candidate = children[0]
            if candidate[self.get_key()] not in [
                    'VariableDefinitionStatement',
                    'VariableDeclarationStatement', 'ExpressionStatement'
            ]:
                node_condition = self._new_node(NodeType.IFLOOP,
                                                statement['src'])
                #expression = parse_expression(candidate, self)
                expression = candidate
                node_condition.add_unparsed_expression(expression)
                link_nodes(node_startLoop, node_condition)
                link_nodes(node_condition, node_endLoop)
                hasCondition = True
            else:
                hasCondition = False

        node_statement = self._parse_statement(children[-1], node_condition)

        node_LoopExpression = node_statement
        if hasLoopExpression:
            if len(children) > 2:
                if children[-2][self.get_key()] == 'ExpressionStatement':
                    node_LoopExpression = self._parse_statement(
                        children[-2], node_statement)
            if not hasCondition:
                link_nodes(node_LoopExpression, node_endLoop)

        if not hasCondition and not hasLoopExpression:
            link_nodes(node, node_endLoop)

        link_nodes(node_LoopExpression, node_condition)

        return node_endLoop
コード例 #25
0
    def _parse_for_compact_ast(self, statement, node):
        body = statement['body']
        init_expression = statement['initializationExpression']
        condition = statement['condition']
        loop_expression = statement['loopExpression']

        node_startLoop = self._new_node(NodeType.STARTLOOP, statement['src'])
        node_endLoop = self._new_node(NodeType.ENDLOOP, statement['src'])

        if init_expression:
            node_init_expression = self._parse_statement(init_expression, node)
            link_nodes(node_init_expression, node_startLoop)
        else:
            link_nodes(node, node_startLoop)

        if condition:
            node_condition = self._new_node(NodeType.IFLOOP, statement['src'])
            node_condition.add_unparsed_expression(condition)
            link_nodes(node_startLoop, node_condition)
            link_nodes(node_condition, node_endLoop)
        else:
            node_condition = node_startLoop

        node_body = self._parse_statement(body, node_condition)

        if loop_expression:
            node_LoopExpression = self._parse_statement(
                loop_expression, node_body)
            link_nodes(node_LoopExpression, node_condition)
        else:
            link_nodes(node_body, node_condition)

        if not condition:
            if not loop_expression:
                # TODO: fix case where loop has no expression
                link_nodes(node_startLoop, node_endLoop)
            else:
                link_nodes(node_LoopExpression, node_endLoop)

        return node_endLoop
コード例 #26
0
ファイル: function.py プロジェクト: wangke0809/slither
 def _fix_catch(self, node, end_node):
     if not node.sons:
         link_nodes(node, end_node)
     else:
         for son in node.sons:
             self._fix_catch(son, end_node)
コード例 #27
0
ファイル: function.py プロジェクト: w1r2p1/slither
    def _parse_for(self, statement, node):
        # ForStatement = 'for' '(' (SimpleStatement)? ';' (Expression)? ';' (ExpressionStatement)? ')' Statement

        hasInitExession = True
        hasCondition = True
        hasLoopExpression = True

        # Old solc version do not prevent in the attributes
        # if the loop has a init value /condition or expression
        # There is no way to determine that for(a;;) and for(;a;) are different with old solc
        if 'attributes' in statement:
            if 'initializationExpression' in statement:
                if not statement['initializationExpression']:
                    hasInitExession = False
            if 'condition' in statement:
                if not statement['condition']:
                    hasCondition = False
            if 'loopExpression' in statement:
                if not statement['loopExpression']:
                    hasLoopExpression = False


        node_startLoop = self._new_node(NodeType.STARTLOOP)
        node_endLoop = self._new_node(NodeType.ENDLOOP)

        children = statement['children']

        if hasInitExession:
            if len(children) >= 2:
                if children[0]['name'] in ['VariableDefinitionStatement',
                                           'VariableDeclarationStatement',
                                           'ExpressionStatement']:
                    node_initExpression = self._parse_statement(children[0], node)
                    link_nodes(node_initExpression, node_startLoop)
                else:
                    hasInitExession = False
            else:
                hasInitExession = False

        if not hasInitExession:
            link_nodes(node, node_startLoop)
        node_condition = node_startLoop

        if hasCondition:
            if hasInitExession and len(children) >= 2:
                candidate = children[1]
            else:
                candidate = children[0]
            if candidate['name'] not in ['VariableDefinitionStatement',
                                         'VariableDeclarationStatement',
                                         'ExpressionStatement']:
                node_condition = self._new_node(NodeType.IFLOOP)
                #expression = parse_expression(candidate, self)
                expression = candidate
                node_condition.add_unparsed_expression(expression)
                link_nodes(node_startLoop, node_condition)
                link_nodes(node_condition, node_endLoop)
                hasCondition = True
            else:
                hasCondition = False


        node_statement = self._parse_statement(children[-1], node_condition)

        node_LoopExpression = node_statement
        if hasLoopExpression:
            if len(children) > 2:
                if children[-2]['name'] == 'ExpressionStatement':
                    node_LoopExpression = self._parse_statement(children[-2], node_statement)

        link_nodes(node_LoopExpression, node_startLoop)

        return node_endLoop
コード例 #28
0
ファイル: parse_yul.py プロジェクト: unhash-security/slither
def link_underlying_nodes(node1: YulNode, node2: YulNode):
    link_nodes(node1.underlying_node, node2.underlying_node)