def _parse_returns(self, returns): assert returns[self.get_key()] == 'ParameterList' self.returns_src = SourceMapping() self.returns_src.set_offset(returns['src'], self.contract.slither) if self.is_compact_ast: returns = returns['parameters'] else: returns = returns[self.get_children('children')] for ret in returns: assert ret[self.get_key()] == 'VariableDeclaration' local_var = LocalVariableSolc(ret) local_var.set_function(self) local_var.set_offset(ret['src'], self.contract.slither) local_var.analyze(self) # see https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=storage%20location#data-location if local_var.location == 'default': local_var.set_location('memory') self._add_local_variable(local_var) self._returns.append(local_var)
def _add_param(self, param): local_var = LocalVariableSolc(param) local_var.set_function(self) local_var.set_offset(param['src'], self.contract.slither) local_var.analyze(self) # see https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=storage%20location#data-location if local_var.location == 'default': local_var.set_location('memory') self._add_local_variable(local_var) return local_var
def _parse_returns(self, returns): assert returns['name'] == 'ParameterList' for ret in returns['children']: assert ret['name'] == 'VariableDeclaration' local_var = LocalVariableSolc(ret) local_var.set_function(self) local_var.set_offset(ret['src'], self.contract.slither) local_var.analyze(self) # see https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=storage%20location#data-location if local_var.location == 'default': local_var.set_location('memory') self._variables[local_var.name] = local_var self._returns.append(local_var)
def _parse_params(self, params): assert params[self.get_key()] == 'ParameterList' if self.is_compact_ast: params = params['parameters'] else: params = params[self.get_children('children')] for param in params: assert param[self.get_key()] == 'VariableDeclaration' local_var = LocalVariableSolc(param) local_var.set_function(self) local_var.set_offset(param['src'], self.contract.slither) local_var.analyze(self) # see https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=storage%20location#data-location if local_var.location == 'default': local_var.set_location('memory') self._add_local_variable(local_var) self._parameters.append(local_var)
def _add_param(self, param: Dict) -> LocalVariableSolc: local_var = LocalVariable() local_var.set_offset(param["src"], self._slither_parser.compilation_unit) local_var_parser = LocalVariableSolc(local_var, param) if isinstance(self._custom_error, CustomErrorTopLevel): local_var_parser.analyze(self) else: assert isinstance(self._custom_error, CustomErrorContract) local_var_parser.analyze(self) # see https://solidity.readthedocs.io/en/v0.4.24/types.html?highlight=storage%20location#data-location if local_var.location == "default": local_var.set_location("memory") return local_var_parser
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
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
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