Skip to content

Commit

Permalink
Merge branch 'dev' into dev-source-mapping-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
montyly committed Feb 11, 2022
2 parents 5b7a458 + 65383b9 commit a7d8a42
Show file tree
Hide file tree
Showing 8,257 changed files with 40,050 additions and 9,378 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
2 changes: 1 addition & 1 deletion .github/workflows/black.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
cp pyproject.toml .github/linters
- name: Black
uses: docker://github/super-linter:v3
uses: docker://github/super-linter:v4
if: always()
env:
# run linter on everything to catch preexisting problems
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
"slither_config",
"truffle",
"upgradability",
"prop",
# "prop",
"flat"]
steps:
- uses: actions/checkout@v1
Expand All @@ -55,4 +55,4 @@ jobs:
TEST_TYPE: ${{ matrix.type }}
GITHUB_ETHERSCAN: ${{ secrets.GITHUB_ETHERSCAN }}
run: |
bash scripts/ci_test_${TEST_TYPE}.sh
bash "scripts/ci_test_${TEST_TYPE}.sh"
47 changes: 47 additions & 0 deletions .github/workflows/features.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
name: Features tests

defaults:
run:
# To load bashrc
shell: bash -ieo pipefail {0}

on:
pull_request:
branches: [master, dev]
schedule:
# run CI every day even if no PRs/merges occur
- cron: '0 12 * * *'

jobs:
build:
name: Features tests
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v2

- name: Set up Python 3.6
uses: actions/setup-python@v2
with:
python-version: 3.6

- name: Install dependencies
run: |
python setup.py install
pip install deepdiff
pip install pytest
pip install solc-select
solc-select install all
solc-select use 0.8.0
cd tests/test_node_modules/
npm install hardhat
cd ../..
- name: Test with pytest
run: |
pytest tests/test_features.py
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
cp pyproject.toml .github/linters
- name: Lint everything else
uses: docker://github/super-linter:v3
uses: docker://github/super-linter:v4
if: always()
env:
# run linter on everything to catch preexisting problems
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/pip-audit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: pip-audit

on:
push:
branches: [ dev, master ]
pull_request:
branches: [ dev, master ]
schedule: [ cron: "0 7 * * 2" ]

jobs:
audit:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Python 3.10
uses: actions/setup-python@v2
with:
python-version: "3.10"
- name: Install pip-audit
run: |
python -m pip install --upgrade pip
python -m pip install pip-audit
- name: Run pip-audit
run: |
python -m pip install .
pip-audit --desc -v
2 changes: 1 addition & 1 deletion .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
cp pyproject.toml .github/linters
- name: Pylint
uses: docker://github/super-linter:v3
uses: docker://github/super-linter:v4
if: always()
env:
# run linter on everything to catch preexisting problems
Expand Down
10 changes: 9 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ To run them locally in the root dir of the repository:
- `pylint slither tests --rcfile pyproject.toml`
- `black . --config pyproject.toml`

We use pylint `2.8.2` black `20.8b1`.
We use pylint `2.12.2` black `21.10b0`.
### Detectors tests

For each new detector, at least one regression tests must be present.
Expand All @@ -56,3 +56,11 @@ To see the tests coverage, run `pytest tests/test_detectors.py --cov=slither/d
- Run `pytest ./tests/test_ast_parsing.py` and check that everything worked.

To see the tests coverage, run `pytest tests/test_ast_parsing.py --cov=slither/solc_parsing --cov-branch --cov-report html`

### Synchronization with crytic-compile
By default, `slither` follows either the latest version of crytic-compile in pip, or `crytic-compile@master` (look for dependencies in [`setup.py`](./setup.py). If crytic-compile development comes with breaking changes, the process to update `slither` is:
- Update `slither/setup.py` to point to the related crytic-compile's branch
- Create a PR in `slither` and ensure it passes the CI
- Once the development branch is merged in `crytic-compile@master`, ensure `slither` follows the `master` branch

The `slither`'s PR can either be merged while using a crytic-compile non-`master` branch, or kept open until the breaking changes are available in `crytic-compile@master`.
140 changes: 72 additions & 68 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion plugin_example/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Slither, Plugin Example

This repo contains an example of plugin for Slither.
This repository contains an example of plugin for Slither.

See the [detector documentation](https://github.com/trailofbits/slither/wiki/Adding-a-new-detector).

Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ logging-fstring-interpolation,
logging-not-lazy,
duplicate-code,
import-error,
unsubscriptable-object
unsubscriptable-object,
consider-using-f-string
"""
13 changes: 8 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
from setuptools import setup, find_packages

with open("README.md", "r", encoding="utf-8") as f:
long_description = f.read()

setup(
name="slither-analyzer",
description="Slither is a Solidity static analysis framework written in Python 3.",
url="https://github.com/crytic/slither",
author="Trail of Bits",
version="0.8.0",
version="0.8.2",
packages=find_packages(),
python_requires=">=3.6",
install_requires=[
"prettytable>=0.7.2",
"pysha3>=1.0.2",
# "crytic-compile>=0.2.0",
"crytic-compile",
"crytic-compile>=0.2.2",
# "crytic-compile",
],
dependency_links=["git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile"],
# dependency_links=["git+https://github.com/crytic/crytic-compile.git@master#egg=crytic-compile"],
license="AGPL-3.0",
long_description=open("README.md").read(),
long_description=long_description,
entry_points={
"console_scripts": [
"slither = slither.__main__:main",
Expand Down
62 changes: 40 additions & 22 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@

from crytic_compile import cryticparser
from crytic_compile.platform.standard import generate_standard_export
from crytic_compile.platform.etherscan import SUPPORTED_NETWORK
from crytic_compile import compile_all, is_supported

from slither.detectors import all_detectors
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification
from slither.printers import all_printers
from slither.printers.abstract_printer import AbstractPrinter
from slither.slither import Slither
from slither.utils.output import output_to_json, output_to_zip, ZIP_TYPES_ACCEPTED
from slither.utils.output import output_to_json, output_to_zip, output_to_sarif, ZIP_TYPES_ACCEPTED
from slither.utils.output_capture import StandardOutputCapture
from slither.utils.colors import red, blue, set_colorization_enabled
from slither.utils.colors import red, set_colorization_enabled
from slither.utils.command_line import (
output_detectors,
output_results_to_markdown,
Expand All @@ -38,6 +39,7 @@
read_config_file,
JSON_OUTPUT_TYPES,
DEFAULT_JSON_OUTPUT_TYPES,
check_and_sanitize_markdown_root,
)
from slither.exceptions import SlitherException

Expand Down Expand Up @@ -171,13 +173,11 @@ def get_detectors_and_printers():
detector = None
if not all(issubclass(detector, AbstractDetector) for detector in plugin_detectors):
raise Exception(
"Error when loading plugin %s, %r is not a detector" % (entry_point, detector)
f"Error when loading plugin {entry_point}, {detector} is not a detector"
)
printer = None
if not all(issubclass(printer, AbstractPrinter) for printer in plugin_printers):
raise Exception(
"Error when loading plugin %s, %r is not a printer" % (entry_point, printer)
)
raise Exception(f"Error when loading plugin {entry_point}, {printer} is not a printer")

# We convert those to lists in case someone returns a tuple
detectors += list(plugin_detectors)
Expand Down Expand Up @@ -251,7 +251,7 @@ def choose_printers(args, all_printer_classes):
if printer in printers:
printers_to_run.append(printers[printer])
else:
raise Exception("Error: {} is not a printer".format(printer))
raise Exception(f"Error: {printer} is not a printer")
return printers_to_run


Expand All @@ -270,12 +270,20 @@ def parse_filter_paths(args):


def parse_args(detector_classes, printer_classes): # pylint: disable=too-many-statements

usage = "slither target [flag]\n"
usage += "\ntarget can be:\n"
usage += "\t- file.sol // a Solidity file\n"
usage += "\t- project_directory // a project directory. See https://github.com/crytic/crytic-compile/#crytic-compile for the supported platforms\n"
usage += "\t- 0x.. // a contract on mainet\n"
usage += f"\t- NETWORK:0x.. // a contract on a different network. Supported networks: {','.join(x[:-1] for x in SUPPORTED_NETWORK)}\n"

parser = argparse.ArgumentParser(
description="Slither. For usage information, see https://github.com/crytic/slither/wiki/Usage",
usage="slither.py contract.sol [flag]",
description="For usage information, see https://github.com/crytic/slither/wiki/Usage",
usage=usage,
)

parser.add_argument("filename", help="contract.sol")
parser.add_argument("filename", help=argparse.SUPPRESS)

cryticparser.init(parser)

Expand All @@ -293,7 +301,7 @@ def parse_args(detector_classes, printer_classes): # pylint: disable=too-many-s
group_detector.add_argument(
"--detect",
help="Comma-separated list of detectors, defaults to all, "
"available detectors: {}".format(", ".join(d.ARGUMENT for d in detector_classes)),
f"available detectors: {', '.join(d.ARGUMENT for d in detector_classes)}",
action="store",
dest="detectors_to_run",
default=defaults_flag_in_config["detectors_to_run"],
Expand All @@ -302,7 +310,7 @@ def parse_args(detector_classes, printer_classes): # pylint: disable=too-many-s
group_printer.add_argument(
"--print",
help="Comma-separated list fo contract information printers, "
"available printers: {}".format(", ".join(d.ARGUMENT for d in printer_classes)),
f"available printers: {', '.join(d.ARGUMENT for d in printer_classes)}",
action="store",
dest="printers_to_run",
default=defaults_flag_in_config["printers_to_run"],
Expand Down Expand Up @@ -388,6 +396,13 @@ def parse_args(detector_classes, printer_classes): # pylint: disable=too-many-s
default=defaults_flag_in_config["json"],
)

group_misc.add_argument(
"--sarif",
help='Export the results as a SARIF JSON file ("--sarif -" to export to stdout)',
action="store",
default=defaults_flag_in_config["sarif"],
)

group_misc.add_argument(
"--json-types",
help="Comma-separated list of result types to output to JSON, defaults to "
Expand All @@ -413,6 +428,7 @@ def parse_args(detector_classes, printer_classes): # pylint: disable=too-many-s

group_misc.add_argument(
"--markdown-root",
type=check_and_sanitize_markdown_root,
help="URL for markdown generation",
action="store",
default="",
Expand Down Expand Up @@ -636,15 +652,17 @@ def main_impl(all_detector_classes, all_printer_classes):
output_error = None
outputting_json = args.json is not None
outputting_json_stdout = args.json == "-"
outputting_sarif = args.sarif is not None
outputting_sarif_stdout = args.sarif == "-"
outputting_zip = args.zip is not None
if args.zip_type not in ZIP_TYPES_ACCEPTED.keys():
if args.zip_type not in ZIP_TYPES_ACCEPTED:
to_log = f'Zip type not accepted, it must be one of {",".join(ZIP_TYPES_ACCEPTED.keys())}'
logger.error(to_log)

# If we are outputting JSON, capture all standard output. If we are outputting to stdout, we block typical stdout
# output.
if outputting_json:
StandardOutputCapture.enable(outputting_json_stdout)
if outputting_json or output_to_sarif:
StandardOutputCapture.enable(outputting_json_stdout or outputting_sarif_stdout)

printer_classes = choose_printers(args, all_printer_classes)
detector_classes = choose_detectors(args, all_detector_classes)
Expand Down Expand Up @@ -723,7 +741,7 @@ def main_impl(all_detector_classes, all_printer_classes):
) = process_all(filename, args, detector_classes, printer_classes)

# Determine if we are outputting JSON
if outputting_json or outputting_zip:
if outputting_json or outputting_zip or output_to_sarif:
# Add our compilation information to JSON
if "compilations" in args.json_types:
compilation_results = []
Expand Down Expand Up @@ -768,12 +786,6 @@ def main_impl(all_detector_classes, all_printer_classes):
len(detector_classes),
len(results_detectors),
)

logger.info(
blue(
"Use https://crytic.io/ to get access to additional detectors and Github integration"
)
)
if args.ignore_return_value:
return

Expand All @@ -800,6 +812,12 @@ def main_impl(all_detector_classes, all_printer_classes):
StandardOutputCapture.disable()
output_to_json(None if outputting_json_stdout else args.json, output_error, json_results)

if outputting_sarif:
StandardOutputCapture.disable()
output_to_sarif(
None if outputting_sarif_stdout else args.sarif, json_results, detector_classes
)

if outputting_zip:
output_to_zip(args.zip, output_error, json_results, args.zip_type)

Expand Down
Loading

0 comments on commit a7d8a42

Please sign in to comment.