Merge pull request #1571 from crytic/dev-add-no-fail

Add --no-fail mode
pull/1573/head
Feist Josselin 2 years ago committed by GitHub
commit 53238600a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      slither/__main__.py
  2. 4
      slither/core/slither_core.py
  3. 47
      slither/printers/guidance/echidna.py
  4. 48
      slither/slither.py
  5. 1
      slither/utils/command_line.py

@ -555,6 +555,13 @@ def parse_args(
default=False, default=False,
) )
group_misc.add_argument(
"--no-fail",
help="Do not fail in case of parsing (echidna mode only)",
action="store_true",
default=defaults_flag_in_config["no_fail"],
)
codex.init_parser(parser) codex.init_parser(parser)
# debugger command # debugger command

@ -92,6 +92,10 @@ class SlitherCore(Context):
# But we allow to alter this (ex: file.sol:1) for vscode integration # But we allow to alter this (ex: file.sol:1) for vscode integration
self.line_prefix: str = "#" self.line_prefix: str = "#"
# Use by the echidna printer
# If true, partial analysis is allowed
self.no_fail = False
@property @property
def compilation_units(self) -> List[SlitherCompilationUnit]: def compilation_units(self) -> List[SlitherCompilationUnit]:
return list(self._compilation_units) return list(self._compilation_units)

@ -329,27 +329,32 @@ def _call_a_parameter(slither: SlitherCore) -> Dict[str, List[Dict]]:
ret: Dict[str, List[Dict]] = defaultdict(list) ret: Dict[str, List[Dict]] = defaultdict(list)
for contract in slither.contracts: # pylint: disable=too-many-nested-blocks for contract in slither.contracts: # pylint: disable=too-many-nested-blocks
for function in contract.functions_entry_points: for function in contract.functions_entry_points:
for ir in function.all_slithir_operations(): try:
if isinstance(ir, HighLevelCall): for ir in function.all_slithir_operations():
for idx, parameter in enumerate(function.parameters): if isinstance(ir, HighLevelCall):
if is_dependent(ir.destination, parameter, function): for idx, parameter in enumerate(function.parameters):
ret[contract.name].append( if is_dependent(ir.destination, parameter, function):
{ ret[contract.name].append(
"function": _get_name(function), {
"parameter_idx": idx, "function": _get_name(function),
"signature": _get_name(ir.function), "parameter_idx": idx,
} "signature": _get_name(ir.function),
) }
if isinstance(ir, LowLevelCall): )
for idx, parameter in enumerate(function.parameters): if isinstance(ir, LowLevelCall):
if is_dependent(ir.destination, parameter, function): for idx, parameter in enumerate(function.parameters):
ret[contract.name].append( if is_dependent(ir.destination, parameter, function):
{ ret[contract.name].append(
"function": _get_name(function), {
"parameter_idx": idx, "function": _get_name(function),
"signature": None, "parameter_idx": idx,
} "signature": None,
) }
)
except Exception as e:
if slither.no_fail:
continue
raise e
return ret return ret

@ -91,6 +91,8 @@ class Slither(SlitherCore): # pylint: disable=too-many-instance-attributes
self.codex_max_tokens = kwargs.get("codex_max_tokens", 300) self.codex_max_tokens = kwargs.get("codex_max_tokens", 300)
self.codex_log = kwargs.get("codex_log", False) self.codex_log = kwargs.get("codex_log", False)
self.no_fail = kwargs.get("no_fail", False)
self._parsers: List[SlitherCompilationUnitSolc] = [] self._parsers: List[SlitherCompilationUnitSolc] = []
try: try:
if isinstance(target, CryticCompile): if isinstance(target, CryticCompile):
@ -128,41 +130,27 @@ class Slither(SlitherCore): # pylint: disable=too-many-instance-attributes
triage_mode = kwargs.get("triage_mode", False) triage_mode = kwargs.get("triage_mode", False)
self._triage_mode = triage_mode self._triage_mode = triage_mode
self._init_parsing_and_analyses(kwargs.get("skip_analyze", False))
def _init_parsing_and_analyses(self, skip_analyze: bool) -> None:
for parser in self._parsers: for parser in self._parsers:
parser.parse_contracts() try:
parser.parse_contracts()
except Exception as e:
if self.no_fail:
continue
raise e
# skip_analyze is only used for testing # skip_analyze is only used for testing
if not kwargs.get("skip_analyze", False): if not skip_analyze:
for parser in self._parsers: for parser in self._parsers:
parser.analyze_contracts() try:
parser.analyze_contracts()
# def _init_from_raw_json(self, filename): except Exception as e:
# if not os.path.isfile(filename): if self.no_fail:
# raise SlitherError( continue
# "{} does not exist (are you in the correct directory?)".format(filename) raise e
# )
# assert filename.endswith("json")
# with open(filename, encoding="utf8") as astFile:
# stdout = astFile.read()
# if not stdout:
# to_log = f"Empty AST file: {filename}"
# raise SlitherError(to_log)
# contracts_json = stdout.split("\n=")
#
# self._parser = SlitherCompilationUnitSolc(filename, self)
#
# for c in contracts_json:
# self._parser.parse_top_level_from_json(c)
# def _init_from_list(self, contract):
# self._parser = SlitherCompilationUnitSolc("", self)
# for c in contract:
# if "absolutePath" in c:
# path = c["absolutePath"]
# else:
# path = c["attributes"]["absolutePath"]
# self._parser.parse_top_level_from_loaded_json(c, path)
@property @property
def detectors(self): def detectors(self):

@ -60,6 +60,7 @@ defaults_flag_in_config = {
"zip": None, "zip": None,
"zip_type": "lzma", "zip_type": "lzma",
"show_ignored_findings": False, "show_ignored_findings": False,
"no_fail": False,
**DEFAULTS_FLAG_IN_CONFIG_CRYTIC_COMPILE, **DEFAULTS_FLAG_IN_CONFIG_CRYTIC_COMPILE,
} }

Loading…
Cancel
Save