From 82a5461ed94a62549beb89800f04a2a868ad6f8c Mon Sep 17 00:00:00 2001 From: Josselin Date: Fri, 26 Oct 2018 19:54:59 +0100 Subject: [PATCH] More strict rules on variable type --- slither/core/variables/variable.py | 6 +++++- slither/slithir/convert.py | 9 ++++++--- slither/slithir/operations/binary.py | 3 ++- slither/slithir/variables/tuple.py | 5 +++++ slither/solc_parsing/expressions/expression_parsing.py | 10 +++++----- 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/slither/core/variables/variable.py b/slither/core/variables/variable.py index 64373b33a..d4e218173 100644 --- a/slither/core/variables/variable.py +++ b/slither/core/variables/variable.py @@ -3,7 +3,8 @@ """ from slither.core.source_mapping.source_mapping import SourceMapping - +from slither.core.solidity_types.type import Type +from slither.core.solidity_types.elementary_type import ElementaryType class Variable(SourceMapping): @@ -73,6 +74,9 @@ class Variable(SourceMapping): return self._visibility def set_type(self, t): + if isinstance(t, str): + t = ElementaryType(t) + assert isinstance(t, Type) or t is None self._type = t def __str__(self): diff --git a/slither/slithir/convert.py b/slither/slithir/convert.py index ecffadfdd..eec9dc0d9 100644 --- a/slither/slithir/convert.py +++ b/slither/slithir/convert.py @@ -189,7 +189,10 @@ def convert_to_low_level(ir): call = SolidityFunction('abi.{}()'.format(ir.function_name)) new_ir = SolidityCall(call, ir.nbr_arguments, ir.lvalue, ir.type_call) new_ir.arguments = ir.arguments - new_ir.lvalue.set_type(call.return_type) + if isinstance(call.return_type, list) and len(call.return_type) == 1: + new_ir.lvalue.set_type(call.return_type[0]) + else: + new_ir.lvalue.set_type(call.return_type) return new_ir elif ir.function_name in ['call', 'delegatecall', 'callcode']: new_ir = LowLevelCall(ir.destination, @@ -427,7 +430,7 @@ def propagate_types(ir, node): if return_type: if len(return_type) == 1: ir.lvalue.set_type(return_type[0]) - else: + elif len(return_type)>1: ir.lvalue.set_type(return_type) else: ir.lvalue = None @@ -483,7 +486,7 @@ def propagate_types(ir, node): return_type = ir.function.return_type if len(return_type) == 1: ir.lvalue.set_type(return_type[0]) - else: + elif len(return_type)>1: ir.lvalue.set_type(return_type) elif isinstance(ir, TypeConversion): ir.lvalue.set_type(ir.type) diff --git a/slither/slithir/operations/binary.py b/slither/slithir/operations/binary.py index 1485f01b0..733b6596b 100644 --- a/slither/slithir/operations/binary.py +++ b/slither/slithir/operations/binary.py @@ -2,6 +2,7 @@ import logging from slither.slithir.operations.lvalue import OperationWithLValue from slither.core.variables.variable import Variable from slither.slithir.utils.utils import is_valid_lvalue, is_valid_rvalue +from slither.core.solidity_types import ElementaryType logger = logging.getLogger("BinaryOperationIR") @@ -135,7 +136,7 @@ class Binary(OperationWithLValue): self._type = operation_type self._lvalue = result if BinaryType.return_bool(operation_type): - result.set_type('bool') + result.set_type(ElementaryType('bool')) else: result.set_type(left_variable.type) diff --git a/slither/slithir/variables/tuple.py b/slither/slithir/variables/tuple.py index 7abe34a25..74091a301 100644 --- a/slither/slithir/variables/tuple.py +++ b/slither/slithir/variables/tuple.py @@ -1,6 +1,7 @@ from slither.core.variables.variable import Variable +from slither.core.solidity_types.type import Type class TupleVariable(Variable): COUNTER = 0 @@ -22,5 +23,9 @@ class TupleVariable(Variable): def name(self): return 'TUPLE_{}'.format(self.index) + def set_type(self, t): + assert all(isinstance(x, Type) or x is None for x in t) + self._type = t + def __str__(self): return self.name diff --git a/slither/solc_parsing/expressions/expression_parsing.py b/slither/solc_parsing/expressions/expression_parsing.py index 688482177..02d095cc8 100644 --- a/slither/solc_parsing/expressions/expression_parsing.py +++ b/slither/solc_parsing/expressions/expression_parsing.py @@ -152,11 +152,11 @@ def parse_call(expression, caller_context): type_info = children[0] expression_to_parse = children[1] assert type_info['name'] in ['ElementaryTypenameExpression', - 'ElementaryTypeNameExpression', - 'Identifier', - 'TupleExpression', - 'IndexAccess', - 'MemberAccess'] + 'ElementaryTypeNameExpression', + 'Identifier', + 'TupleExpression', + 'IndexAccess', + 'MemberAccess'] expression = parse_expression(expression_to_parse, caller_context) t = TypeConversion(expression, type_call)