WIP: add support for config file

pull/172/head
Josselin 6 years ago
parent a9e434ab08
commit 2deecb3ddf
  1. 96
      slither/__main__.py
  2. 6
      slither/slither.py

@ -48,7 +48,7 @@ def process(filename, args, detector_classes, printer_classes):
disable_solc_warnings=args.disable_solc_warnings, disable_solc_warnings=args.disable_solc_warnings,
solc_arguments=args.solc_args, solc_arguments=args.solc_args,
ast_format=ast, ast_format=ast,
paths_to_filter=parse_paths_to_filter(args), filter_paths=parse_filter_paths(args),
interactive_mode=args.interactive_mode) interactive_mode=args.interactive_mode)
return _process(slither, detector_classes, printer_classes) return _process(slither, detector_classes, printer_classes)
@ -106,7 +106,7 @@ def process_truffle(dirname, args, detector_classes, printer_classes):
disable_solc_warnings=args.disable_solc_warnings, disable_solc_warnings=args.disable_solc_warnings,
solc_arguments=args.solc_args, solc_arguments=args.solc_args,
is_truffle=True, is_truffle=True,
paths_to_filter=parse_paths_to_filter(args), filter_paths=parse_filter_paths(args),
interactive_mode=args.interactive_mode) interactive_mode=args.interactive_mode)
return _process(slither, detector_classes, printer_classes) return _process(slither, detector_classes, printer_classes)
@ -124,7 +124,7 @@ def process_files(filenames, args, detector_classes, printer_classes):
solc=args.solc, solc=args.solc,
disable_solc_warnings=args.disable_solc_warnings, disable_solc_warnings=args.disable_solc_warnings,
solc_arguments=args.solc_args, solc_arguments=args.solc_args,
paths_to_filter=parse_paths_to_filter(args), filter_paths=parse_filter_paths(args),
interactive_mode=args.interactive_mode) interactive_mode=args.interactive_mode)
return _process(slither, detector_classes, printer_classes) return _process(slither, detector_classes, printer_classes)
@ -200,10 +200,11 @@ def choose_detectors(args, all_detector_classes):
if args.detectors_to_run == 'all': if args.detectors_to_run == 'all':
detectors_to_run = all_detector_classes detectors_to_run = all_detector_classes
detectors_excluded = args.detectors_to_exclude.split(',') if args.detectors_to_exclude:
for d in detectors: detectors_excluded = args.detectors_to_exclude.split(',')
if d in detectors_excluded: for d in detectors:
detectors_to_run.remove(detectors[d]) if d in detectors_excluded:
detectors_to_run.remove(detectors[d])
else: else:
for d in args.detectors_to_run.split(','): for d in args.detectors_to_run.split(','):
if d in detectors: if d in detectors:
@ -238,7 +239,7 @@ def choose_printers(args, all_printer_classes):
printers_to_run = [] printers_to_run = []
# disable default printer # disable default printer
if args.printers_to_run == '': if args.printers_to_run is None:
return [] return []
printers = {p.ARGUMENT: p for p in all_printer_classes} printers = {p.ARGUMENT: p for p in all_printer_classes}
@ -256,11 +257,31 @@ def choose_printers(args, all_printer_classes):
################################################################################### ###################################################################################
################################################################################### ###################################################################################
def parse_paths_to_filter(args): def parse_filter_paths(args):
if args.paths_to_filter: if args.filter_paths:
return args.paths_to_filter.split(',') return args.filter_paths.split(',')
return [] return []
# Those are the flags shared by the command line and the config file
defaults_flag_in_config = {
'detectors_to_run': 'all',
'printers_to_run': None,
'detectors_to_exclude': None,
'exclude_informational': False,
'exclude_low': False,
'exclude_medium': False,
'exclude_high': False,
'solc': 'solc',
'solc_args': None,
'disable_solc_warnings': False,
'json': None,
'truffle_version': None,
'disable_color': False,
'filter_paths': None,
'ignore_truffle_compile': False,
'legacy_ast': False
}
def parse_args(detector_classes, printer_classes): def parse_args(detector_classes, printer_classes):
parser = argparse.ArgumentParser(description='Slither', parser = argparse.ArgumentParser(description='Slither',
usage="slither.py contract.sol [flag]") usage="slither.py contract.sol [flag]")
@ -284,7 +305,7 @@ def parse_args(detector_classes, printer_classes):
', '.join(d.ARGUMENT for d in detector_classes)), ', '.join(d.ARGUMENT for d in detector_classes)),
action='store', action='store',
dest='detectors_to_run', dest='detectors_to_run',
default='all') default=defaults_flag_in_config['detectors_to_run'])
group_printer.add_argument('--print', group_printer.add_argument('--print',
help='Comma-separated list fo contract information printers, ' help='Comma-separated list fo contract information printers, '
@ -292,7 +313,7 @@ def parse_args(detector_classes, printer_classes):
', '.join(d.ARGUMENT for d in printer_classes)), ', '.join(d.ARGUMENT for d in printer_classes)),
action='store', action='store',
dest='printers_to_run', dest='printers_to_run',
default='') default=defaults_flag_in_config['printers_to_run'])
group_detector.add_argument('--list-detectors', group_detector.add_argument('--list-detectors',
help='List available detectors', help='List available detectors',
@ -310,42 +331,42 @@ def parse_args(detector_classes, printer_classes):
help='Comma-separated list of detectors that should be excluded', help='Comma-separated list of detectors that should be excluded',
action='store', action='store',
dest='detectors_to_exclude', dest='detectors_to_exclude',
default='') default=defaults_flag_in_config['detectors_to_exclude'])
group_detector.add_argument('--exclude-informational', group_detector.add_argument('--exclude-informational',
help='Exclude informational impact analyses', help='Exclude informational impact analyses',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['exclude_informational'])
group_detector.add_argument('--exclude-low', group_detector.add_argument('--exclude-low',
help='Exclude low impact analyses', help='Exclude low impact analyses',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['exclude_low'])
group_detector.add_argument('--exclude-medium', group_detector.add_argument('--exclude-medium',
help='Exclude medium impact analyses', help='Exclude medium impact analyses',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['exclude_medium'])
group_detector.add_argument('--exclude-high', group_detector.add_argument('--exclude-high',
help='Exclude high impact analyses', help='Exclude high impact analyses',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['exclude_high'])
group_solc.add_argument('--solc', group_solc.add_argument('--solc',
help='solc path', help='solc path',
action='store', action='store',
default='solc') default=defaults_flag_in_config['solc'])
group_solc.add_argument('--solc-args', group_solc.add_argument('--solc-args',
help='Add custom solc arguments. Example: --solc-args "--allow-path /tmp --evm-version byzantium".', help='Add custom solc arguments. Example: --solc-args "--allow-path /tmp --evm-version byzantium".',
action='store', action='store',
default=None) default=defaults_flag_in_config['solc_args'])
group_solc.add_argument('--disable-solc-warnings', group_solc.add_argument('--disable-solc-warnings',
help='Disable solc warnings', help='Disable solc warnings',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['disable_solc_warnings'])
group_solc.add_argument('--solc-ast', group_solc.add_argument('--solc-ast',
help='Provide the ast solc file', help='Provide the ast solc file',
@ -355,28 +376,28 @@ def parse_args(detector_classes, printer_classes):
group_misc.add_argument('--json', group_misc.add_argument('--json',
help='Export results as JSON', help='Export results as JSON',
action='store', action='store',
default=None) default=defaults_flag_in_config['json'])
group_misc.add_argument('--truffle-version', group_misc.add_argument('--truffle-version',
help='Use a local Truffle version (with npx)', help='Use a local Truffle version (with npx)',
action='store', action='store',
default=False) default=defaults_flag_in_config['truffle_version'])
group_misc.add_argument('--disable-color', group_misc.add_argument('--disable-color',
help='Disable output colorization', help='Disable output colorization',
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['disable_color'])
group_misc.add_argument('--filter-paths', group_misc.add_argument('--filter-paths',
help='Comma-separated list of paths for which results will be excluded', help='Comma-separated list of paths for which results will be excluded',
action='store', action='store',
dest='paths_to_filter', dest='filter_paths',
default='') default=defaults_flag_in_config['filter_paths'])
group_misc.add_argument('--ignore-truffle-compile', group_misc.add_argument('--ignore-truffle-compile',
help='Do not run truffle compile', help='Do not run truffle compile',
action='store_true', action='store_true',
dest='ignore_truffle_compile', dest='ignore_truffle_compile',
default=False) default=defaults_flag_in_config['ignore_truffle_compile'])
group_misc.add_argument('--interactive-mode', group_misc.add_argument('--interactive-mode',
help='Run interactive mode (save results in slither.db.json)', help='Run interactive mode (save results in slither.db.json)',
@ -384,6 +405,12 @@ def parse_args(detector_classes, printer_classes):
dest='interactive_mode', dest='interactive_mode',
default=False) default=False)
group_misc.add_argument('--config-file',
help='Provide a config file (default: slither.config.json)',
action='store',
dest='config_file',
default='slither.config.json')
# debugger command # debugger command
parser.add_argument('--debug', parser.add_argument('--debug',
help=argparse.SUPPRESS, help=argparse.SUPPRESS,
@ -409,7 +436,7 @@ def parse_args(detector_classes, printer_classes):
parser.add_argument('--legacy-ast', parser.add_argument('--legacy-ast',
help=argparse.SUPPRESS, help=argparse.SUPPRESS,
action='store_true', action='store_true',
default=False) default=defaults_flag_in_config['legacy_ast'])
# if the json is splitted in different files # if the json is splitted in different files
parser.add_argument('--splitted', parser.add_argument('--splitted',
@ -423,6 +450,19 @@ def parse_args(detector_classes, printer_classes):
args = parser.parse_args() args = parser.parse_args()
if os.path.isfile(args.config_file):
try:
with open(args.config_file) as f:
config = json.load(f)
for key, elem in config.items():
if key not in defaults_flag_in_config:
logger.info(yellow('{} has an unknown key: {} : {}'.format(args.config_file, key, elem)))
continue
if getattr(args, key) == defaults_flag_in_config[key]:
setattr(args, key, elem)
except json.decoder.JSONDecodeError as e:
logger.error(red('Impossible to read {}, please check the file {}'.format(args.config_file, e)))
return args return args
class ListDetectors(argparse.Action): class ListDetectors(argparse.Action):

@ -29,7 +29,7 @@ class Slither(SlitherSolc):
solc_argeuments (str): solc arguments (default '') solc_argeuments (str): solc arguments (default '')
ast_format (str): ast format (default '--ast-compact-json') ast_format (str): ast format (default '--ast-compact-json')
is_truffle (bool): is a truffle directory (default false) is_truffle (bool): is a truffle directory (default false)
paths_to_filter (list(str)): list of path to filter (default []) filter_paths (list(str)): list of path to filter (default [])
interactive_mode (bool): if true, switch to interactive mode (default false) interactive_mode (bool): if true, switch to interactive mode (default false)
''' '''
@ -48,8 +48,8 @@ class Slither(SlitherSolc):
self._detectors = [] self._detectors = []
self._printers = [] self._printers = []
paths_to_filter = kwargs.get('paths_to_filter', []) filter_paths = kwargs.get('filter_paths', [])
for p in paths_to_filter: for p in filter_paths:
self.add_path_to_filter(p) self.add_path_to_filter(p)
interactive_mode = kwargs.get('interactive_mode', False) interactive_mode = kwargs.get('interactive_mode', False)

Loading…
Cancel
Save