Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Exception handling #229

Merged
merged 2 commits into from May 7, 2019
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -24,6 +24,7 @@
output_detectors_json, output_printers,
output_to_markdown, output_wiki)
from crytic_compile import is_supported
from slither.exceptions import SlitherException

logging.basicConfig()
logger = logging.getLogger("Slither")
@@ -551,6 +552,12 @@ def main_impl(all_detector_classes, all_printer_classes):
return
exit(results)

except SlitherException as e:
logging.error(red('Error:'))
logging.error(red(e))
logging.error('Please report an issue to https://github.com/crytic/slither/issues')
sys.exit(-1)

except Exception:
logging.error('Error in %s' % args.filename)
logging.error(traceback.format_exc())
@@ -0,0 +1,7 @@
"""
This module import all slither exceptions
"""
from slither.slithir.exceptions import SlithIRError
from slither.solc_parsing.exceptions import ParsingError, ParsingContractNotFound, ParsingNameReuse
from slither.core.exceptions import SlitherCoreError
from slither.exceptions import SlitherException
@@ -0,0 +1,3 @@
from slither.exceptions import SlitherException

class SlitherCoreError(SlitherException): pass
@@ -1,7 +1,7 @@
import logging
from slither.core.expressions.expression_typed import ExpressionTyped
from slither.core.expressions.expression import Expression

from slither.core.exceptions import SlitherCoreError

logger = logging.getLogger("AssignmentOperation")

@@ -43,8 +43,7 @@ def get_type(operation_type):
if operation_type == '%=':
return AssignmentOperationType.ASSIGN_MODULO

logger.error('get_type: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlitherCoreError('get_type: Unknown operation type {})'.format(operation_type))

@staticmethod
def str(operation_type):
@@ -71,8 +70,7 @@ def str(operation_type):
if operation_type == AssignmentOperationType.ASSIGN_MODULO:
return '%='

logger.error('str: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlitherCoreError('str: Unknown operation type {})'.format(operation_type))

class AssignmentOperation(ExpressionTyped):

@@ -1,7 +1,7 @@
import logging
from slither.core.expressions.expression_typed import ExpressionTyped
from slither.core.expressions.expression import Expression

from slither.core.exceptions import SlitherCoreError

logger = logging.getLogger("BinaryOperation")

@@ -67,8 +67,7 @@ def get_type(operation_type):
if operation_type == '||':
return BinaryOperationType.OROR

logger.error('get_type: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlitherCoreError('get_type: Unknown operation type {})'.format(operation_type))

@staticmethod
def str(operation_type):
@@ -110,8 +109,7 @@ def str(operation_type):
return '&&'
if operation_type == BinaryOperationType.OROR:
return '||'
logger.error('str: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlitherCoreError('str: Unknown operation type {})'.format(operation_type))

class BinaryOperation(ExpressionTyped):

@@ -1,7 +1,7 @@
import logging
from slither.core.expressions.expression_typed import ExpressionTyped
from slither.core.expressions.expression import Expression
from slither.core.solidity_types.type import Type
from slither.core.exceptions import SlitherCoreError

logger = logging.getLogger("UnaryOperation")

@@ -38,8 +38,7 @@ def get_type(operation_type, isprefix):
return UnaryOperationType.PLUSPLUS_POST
if operation_type == '--':
return UnaryOperationType.MINUSMINUS_POST
logger.error('get_type: Unknown operation type {}'.format(operation_type))
exit(-1)
raise SlitherCoreError('get_type: Unknown operation type {}'.format(operation_type))

@staticmethod
def str(operation_type):
@@ -58,8 +57,7 @@ def str(operation_type):
if operation_type in [UnaryOperationType.MINUSMINUS_PRE, UnaryOperationType.MINUSMINUS_POST]:
return '--'

logger.error('str: Unknown operation type {}'.format(operation_type))
exit(-1)
raise SlitherCoreError('str: Unknown operation type {}'.format(operation_type))

@staticmethod
def is_prefix(operation_type):
@@ -74,8 +72,7 @@ def is_prefix(operation_type):
elif operation_type in [UnaryOperationType.PLUSPLUS_POST, UnaryOperationType.MINUSMINUS_POST]:
return False

logger.error('is_prefix: Unknown operation type {}'.format(operation_type))
exit(-1)
raise SlitherCoreError('is_prefix: Unknown operation type {}'.format(operation_type))

class UnaryOperation(ExpressionTyped):

@@ -0,0 +1,3 @@
class SlitherException(Exception): pass

class SlitherError(SlitherException): pass
@@ -11,7 +11,7 @@
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.printers.abstract_printer import AbstractPrinter
from .solc_parsing.slitherSolc import SlitherSolc
from .utils.colors import red
from .exceptions import SlitherError

logger = logging.getLogger("Slither")
logging.basicConfig()
@@ -56,11 +56,8 @@ def __init__(self, contract, **kwargs):
crytic_compile = CryticCompile(contract, **kwargs)
self._crytic_compile = crytic_compile
except InvalidCompilation as e:
logger.error('Invalid compilation')
logger.error(e)
exit(-1)
raise SlitherError('Invalid compilation: '+e)
for path, ast in crytic_compile.asts.items():

self._parse_contracts_from_loaded_json(ast, path)
self._add_source_code(path)

@@ -78,14 +75,12 @@ def __init__(self, contract, **kwargs):

def _init_from_raw_json(self, filename):
if not os.path.isfile(filename):
logger.error('{} does not exist (are you in the correct directory?)'.format(filename))
exit(-1)
raise SlitherError('{} does not exist (are you in the correct directory?)'.format(filename))
assert filename.endswith('json')
with open(filename, encoding='utf8') as astFile:
stdout = astFile.read()
if not stdout:
logger.info('Empty AST file: %s', filename)
sys.exit(-1)
raise SlitherError('Empty AST file: %s', filename)
contracts_json = stdout.split('\n=')

super(Slither, self).__init__(filename)
@@ -173,14 +168,12 @@ def _check_common_things(self, thing_name, cls, base_cls, instances_list):

def _run_solc(self, filename, solc, disable_solc_warnings, solc_arguments, ast_format):
if not os.path.isfile(filename):
logger.error('{} does not exist (are you in the correct directory?)'.format(filename))
exit(-1)
raise SlitherError('{} does not exist (are you in the correct directory?)'.format(filename))
assert filename.endswith('json')
with open(filename, encoding='utf8') as astFile:
stdout = astFile.read()
if not stdout:
logger.info('Empty AST file: %s', filename)
sys.exit(-1)
raise SlitherError('Empty AST file: %s', filename)
stdout = stdout.split('\n=')

return stdout
@@ -33,6 +33,7 @@
from slither.visitors.slithir.expression_to_slithir import ExpressionToSlithIR
from slither.utils.function import get_function_id
from slither.utils.type import export_nested_types_from_variable
from slither.slithir.exceptions import SlithIRError

logger = logging.getLogger('ConvertToIR')

@@ -457,8 +458,7 @@ def propagate_types(ir, node):
# temporary operation; they will be removed
pass
else:
logger.error('Not handling {} during type propgation'.format(type(ir)))
exit(-1)
raise SlithIRError('Not handling {} during type propgation'.format(type(ir)))

def extract_tmp_call(ins, contract):
assert isinstance(ins, TmpCall)
@@ -577,8 +577,7 @@ def convert_to_low_level(ir):
new_ir.arguments = ir.arguments
new_ir.lvalue.set_type(ElementaryType('bool'))
return new_ir
logger.error('Incorrect conversion to low level {}'.format(ir))
exit(-1)
raise SlithIRError('Incorrect conversion to low level {}'.format(ir))

def convert_to_push(ir, node):
"""
@@ -0,0 +1,3 @@
from slither.exceptions import SlitherException

class SlithIRError(SlitherException): pass
@@ -4,6 +4,7 @@
from slither.slithir.utils.utils import is_valid_lvalue, is_valid_rvalue
from slither.core.solidity_types import ElementaryType
from slither.slithir.variables import ReferenceVariable
from slither.slithir.exceptions import SlithIRError

logger = logging.getLogger("BinaryOperationIR")

@@ -80,8 +81,7 @@ def get_type(operation_type):
if operation_type == '||':
return BinaryType.OROR

logger.error('get_type: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlithIRError('get_type: Unknown operation type {})'.format(operation_type))

@staticmethod
def str(operation_type):
@@ -123,8 +123,7 @@ def str(operation_type):
return '&&'
if operation_type == BinaryType.OROR:
return '||'
logger.error('str: Unknown operation type {})'.format(operation_type))
exit(-1)
raise SlithIRError('str: Unknown operation type {})'.format(operation_type))

class Binary(OperationWithLValue):

@@ -1,8 +1,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.slithir.exceptions import SlithIRError

logger = logging.getLogger("BinaryOperationIR")

@@ -17,8 +16,7 @@ def get_type(operation_type, isprefix):
return UnaryType.BANG
if operation_type == '~':
return UnaryType.TILD
logger.error('get_type: Unknown operation type {}'.format(operation_type))
exit(-1)
raise SlithIRError('get_type: Unknown operation type {}'.format(operation_type))

@staticmethod
def str(operation_type):
@@ -27,8 +25,7 @@ def str(operation_type):
if operation_type == UnaryType.TILD:
return '~'

logger.error('str: Unknown operation type {}'.format(operation_type))
exit(-1)
raise SlithIRError('str: Unknown operation type {}'.format(operation_type))

class Unary(OperationWithLValue):

@@ -22,6 +22,7 @@
ReferenceVariable, ReferenceVariableSSA,
StateIRVariable, TemporaryVariable,
TemporaryVariableSSA, TupleVariable, TupleVariableSSA)
from slither.slithir.exceptions import SlithIRError

logger = logging.getLogger('SSA_Conversion')

@@ -662,7 +663,6 @@ def copy_ir(ir, *instances):
return Length(value, lvalue)


logger.error('Impossible ir copy on {} ({})'.format(ir, type(ir)))
exit(-1)
raise SlithIRError('Impossible ir copy on {} ({})'.format(ir, type(ir)))

# endregion
@@ -9,6 +9,7 @@
from slither.solc_parsing.declarations.structure import StructureSolc
from slither.solc_parsing.solidity_types.type_parsing import parse_type
from slither.solc_parsing.variables.state_variable import StateVariableSolc
from slither.solc_parsing.exceptions import ParsingError

logger = logging.getLogger("ContractSolcParsing")

@@ -186,8 +187,7 @@ def _parse_contract_items(self):
elif item[self.get_key()] == 'UsingForDirective':
self._usingForNotParsed.append(item)
else:
logger.error('Unknown contract item: '+item[self.get_key()])
exit(-1)
raise ParsingError('Unknown contract item: '+item[self.get_key()])
return

def _parse_struct(self, struct):
@@ -26,6 +26,7 @@
from slither.utils.utils import unroll
from slither.visitors.expression.export_values import ExportValues
from slither.visitors.expression.has_conditional import HasConditional
from slither.solc_parsing.exceptions import ParsingError

logger = logging.getLogger("FunctionSolc")

@@ -725,8 +726,7 @@ def _parse_statement(self, statement, node):
link_nodes(node, new_node)
node = new_node
else:
logger.error('Statement not parsed %s'%name)
exit(-1)
raise ParsingError('Statement not parsed %s'%name)

return node

@@ -814,8 +814,7 @@ def _fix_break_node(self, node):
end_node = self._find_end_loop(node, [], 0)

if not end_node:
logger.error('Break in no-loop context {}'.format(node))
exit(-1)
raise ParsingError('Break in no-loop context {}'.format(node))

for son in node.sons:
son.remove_father(node)
@@ -826,8 +825,7 @@ def _fix_continue_node(self, node):
start_node = self._find_start_loop(node, [])

if not start_node:
logger.error('Continue in no-loop context {}'.format(node.nodeId()))
exit(-1)
raise ParsingError('Continue in no-loop context {}'.format(node.nodeId()))

for son in node.sons:
son.remove_father(node)
@@ -0,0 +1,7 @@
from slither.exceptions import SlitherException

class ParsingError(SlitherException): pass

class ParsingNameReuse(SlitherException): pass

class ParsingContractNotFound(SlitherException): pass
@@ -35,7 +35,7 @@
FunctionType, MappingType)
from slither.solc_parsing.solidity_types.type_parsing import (UnknownType,
parse_type)

from slither.solc_parsing.exceptions import ParsingError
logger = logging.getLogger("ExpressionParsing")


@@ -78,8 +78,7 @@ def find_variable(var_name, caller_context, referenced_declaration=None):
function = caller_context
contract = function.contract
else:
logger.error('Incorrect caller context')
exit(-1)
raise ParsingError('Incorrect caller context')

if function:
# We look for variable declared with the referencedDeclaration attr
@@ -627,8 +626,7 @@ def parse_expression(expression, caller_context):
elif type_name[caller_context.get_key()] == 'FunctionTypeName':
array_type = parse_type(type_name, caller_context)
else:
logger.error('Incorrect type array {}'.format(type_name))
exit(-1)
raise ParsingError('Incorrect type array {}'.format(type_name))
array = NewArray(depth, array_type)
return array

@@ -664,5 +662,5 @@ def parse_expression(expression, caller_context):
call = CallExpression(called, arguments, 'Modifier')
return call

logger.error('Expression not parsed %s'%name)
exit(-1)
raise ParsingError('Expression not parsed %s'%name)

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.