Skip to content

Commit

Permalink
Merge pull request crytic#1768 from crytic/dev
Browse files Browse the repository at this point in the history
Sync master with dev
  • Loading branch information
montyly authored Mar 17, 2023
2 parents 64b2e0c + 081056c commit 5869d74
Show file tree
Hide file tree
Showing 51 changed files with 1,529 additions and 116 deletions.
61 changes: 61 additions & 0 deletions .github/ISSUE_TEMPLATE/false_negative.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
body:
-
attributes:
value: |
Please check the issues tab to avoid duplicates.
Thanks for helping make Slither the best it can be!
type: markdown
-
attributes:
label: "What bug did Slither miss and which detector did you anticipate would catch it?"
id: what-happened
type: textarea
validations:
required: true
-
attributes:
label: Frequency
description: How often do you run across this false negative?
options:
- Very Frequently
- Occasionally
- Rarely
- Not sure
id: frequency
type: dropdown
validations:
required: true
-
attributes:
description: "It can be a github repo, etherscan link, or code snippet."
label: "Code example to reproduce the issue:"
placeholder: "`contract A {}`\n"
id: reproduce
type: textarea
validations:
required: true
-
attributes:
description: |
What version of slither are you running?
Run `slither --version`
label: "Version:"
id: version
type: textarea
validations:
required: true
-
attributes:
description: |
Please copy and paste the result output. This
will be automatically formatted into code, so no need for backticks.
render: shell
label: "Relevant log output:"
id: logs
type: textarea
description: "Slither missed a bug it should find."
labels:
- false-negative
name: False Negative"
title: "[False Negative]: "
61 changes: 61 additions & 0 deletions .github/ISSUE_TEMPLATE/false_positive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
body:
-
attributes:
value: |
Please check the issues tab to avoid duplicates.
Thanks for helping make Slither the best it can be!
type: markdown
-
attributes:
label: "Describe the false alarm that Slither raise and how you know it's inaccurate:"
id: what-happened
type: textarea
validations:
required: true
-
attributes:
label: Frequency
description: How often do you run across this false positive?
options:
- Very Frequently
- Occasionally
- Rarely
- Not sure
id: frequency
type: dropdown
validations:
required: true
-
attributes:
description: "It can be a github repo, etherscan link, or code snippet."
label: "Code example to reproduce the issue:"
placeholder: "`contract A {}`\n"
id: reproduce
type: textarea
validations:
required: true
-
attributes:
description: |
What version of slither are you running?
Run `slither --version`
label: "Version:"
id: version
type: textarea
validations:
required: true
-
attributes:
description: |
Please copy and paste the result output. This
will be automatically formatted into code, so no need for backticks.
render: shell
label: "Relevant log output:"
id: logs
type: textarea
description: "Slither warned of an issue that is not legitimate and does not need to be fixed."
labels:
- false-positive
name: "False Positive"
title: "[False-Positive]: "
1 change: 1 addition & 0 deletions .github/workflows/features.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ jobs:
pytest tests/test_features.py
pytest tests/test_constant_folding.py
pytest tests/slithir/test_ternary_expressions.py
pytest tests/slithir/test_operation_reads.py
pytest tests/test_functions_ids.py
pytest tests/test_function.py
pytest tests/test_source_mapping.py
2 changes: 1 addition & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ concurrency:

jobs:
build:
name: Pylint
name: Superlinter
runs-on: ubuntu-latest

steps:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/read_storage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ jobs:
- name: Install python dependencies
run: |
pip install ".[dev]"
pip install web3
solc-select install 0.8.1
solc-select install 0.8.10
solc-select use 0.8.1
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ Slither is licensed and distributed under the AGPLv3 license. [Contact us](mailt
- [Slither: A Static Analysis Framework For Smart Contracts](https://arxiv.org/abs/1908.09878), Josselin Feist, Gustavo Grieco, Alex Groce - WETSEB '19

### External publications
Title | Usage | Authors | Venue | Code
Title | Usage | Authors | Venue | Code
--- | --- | --- | --- | ---
[ReJection: A AST-Based Reentrancy Vulnerability Detection Method](https://www.researchgate.net/publication/339354823_ReJection_A_AST-Based_Reentrancy_Vulnerability_Detection_Method) | AST-based analysis built on top of Slither | Rui Ma, Zefeng Jian, Guangyuan Chen, Ke Ma, Yujia Chen | CTCIS 19
[MPro: Combining Static and Symbolic Analysis forScalable Testing of Smart Contract](https://arxiv.org/pdf/1911.00570.pdf) | Leverage data dependency through Slither | William Zhang, Sebastian Banescu, Leodardo Pasos, Steven Stewart, Vijay Ganesh | ISSRE 2019 | [MPro](https://github.com/QuanZhang-William/M-Pro)
Expand Down
13 changes: 11 additions & 2 deletions scripts/ci_test_printers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@
cd tests/ast-parsing/compile || exit

# Do not test the evm printer,as it needs a refactoring
ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,human-summary,inheritance,inheritance-graph,slithir,slithir-ssa,vars-and-auth,require,variable-order"
ALL_PRINTERS="cfg,constructor-calls,contract-summary,data-dependency,echidna,function-id,function-summary,modifiers,call-graph,human-summary,inheritance,inheritance-graph,slithir,slithir-ssa,vars-and-auth,require,variable-order,declaration"

# Only test 0.5.17 to limit test time
for file in *0.5.17-compact.zip; do
if ! slither "$file" --print "$ALL_PRINTERS" > /dev/null 2>&1 ; then
if ! slither "$file" --print "$ALL_PRINTERS" ; then
echo "Printer failed"
echo "$file"
exit 1
fi
done

# Only test 0.8.12 to limit test time
for file in *0.8.12-compact.zip; do
if ! slither "$file" --print "declaration" ; then
echo "Printer failed"
echo "$file"
exit 1
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@
"pytest-xdist",
"deepdiff",
"numpy",
"solc-select>=v1.0.0b1",
"openai",
"pdoc",
]
"web3>=6.0.0",
],
},
license="AGPL-3.0",
long_description=long_description,
Expand Down
11 changes: 5 additions & 6 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ def process_single(
ast = "--ast-compact-json"
if args.legacy_ast:
ast = "--ast-json"
if args.checklist:
args.show_ignored_findings = True

slither = Slither(target, ast_format=ast, **vars(args))

return _process(slither, detector_classes, printer_classes)
Expand Down Expand Up @@ -517,7 +514,7 @@ def parse_args(

group_misc.add_argument(
"--filter-paths",
help="Comma-separated list of paths for which results will be excluded",
help="Regex filter to exclude detector results matching file path e.g. (mocks/|test/)",
action="store",
dest="filter_paths",
default=defaults_flag_in_config["filter_paths"],
Expand Down Expand Up @@ -760,7 +757,7 @@ def main_impl(

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

printer_classes = choose_printers(args, all_printer_classes)
Expand Down Expand Up @@ -871,7 +868,9 @@ def main_impl(

# Output our results to markdown if we wish to compile a checklist.
if args.checklist:
output_results_to_markdown(results_detectors, args.checklist_limit)
output_results_to_markdown(
results_detectors, args.checklist_limit, args.show_ignored_findings
)

# Don't print the number of result for printers
if number_contracts == 0:
Expand Down
27 changes: 27 additions & 0 deletions slither/core/declarations/contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def __init__(self, compilation_unit: "SlitherCompilationUnit", scope: "FileScope
Dict["StateVariable", Set[Union["StateVariable", "Function"]]]
] = None

self._comments: Optional[str] = None

###################################################################################
###################################################################################
# region General's properties
Expand Down Expand Up @@ -165,6 +167,31 @@ def is_library(self) -> bool:
def is_library(self, is_library: bool):
self._is_library = is_library

@property
def comments(self) -> Optional[str]:
"""
Return the comments associated with the contract.
When using comments, avoid strict text matching, as the solc behavior might change.
For example, for old solc version, the first space after the * is not kept, i.e:
* @title Test Contract
* @dev Test comment
Returns
- " @title Test Contract\n @dev Test comment" for newest versions
- "@title Test Contract\n@dev Test comment" for older versions
Returns:
the comment as a string
"""
return self._comments

@comments.setter
def comments(self, comments: str):
self._comments = comments

# endregion
###################################################################################
###################################################################################
Expand Down
31 changes: 11 additions & 20 deletions slither/core/source_mapping/source_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

# pylint: disable=too-many-instance-attributes
class Source:
def __init__(self) -> None:
def __init__(self, compilation_unit: "SlitherCompilationUnit") -> None:
self.start: int = 0
self.length: int = 0
self.filename: Filename = Filename("", "", "", "")
Expand All @@ -27,7 +27,7 @@ def __init__(self) -> None:
self.starting_column: int = 0
self.ending_column: int = 0
self.end: int = 0
self.compilation_unit: Optional["SlitherCompilationUnit"] = None
self.compilation_unit = compilation_unit

def to_json(self) -> Dict:
return {
Expand All @@ -51,17 +51,13 @@ def to_markdown(self, markdown_root: str) -> str:
filename_relative: str = self.filename.relative if self.filename.relative else ""
return f"{markdown_root}{filename_relative}{lines}"

def to_detailled_str(self) -> str:
def to_detailed_str(self) -> str:
lines = self._get_lines_str()
filename_short: str = self.filename.short if self.filename.short else ""
return f"{filename_short}{lines} ({self.starting_column} - {self.ending_column})"

def _get_lines_str(self, line_descr: str = "") -> str:

# If the compilation unit was not initialized, it means that the set_offset was never called
# on the corresponding object, which should not happen
assert self.compilation_unit is not None

line_prefix = self.compilation_unit.core.line_prefix

lines = self.lines
Expand Down Expand Up @@ -129,6 +125,7 @@ def _compute_line(
Not done in an efficient way
"""

start_line, starting_column = compilation_unit.core.crytic_compile.get_line_from_offset(
filename, start
)
Expand All @@ -151,15 +148,15 @@ def _convert_source_mapping(

position = re.findall("([0-9]*):([0-9]*):([-]?[0-9]*)", offset)
if len(position) != 1:
return Source()
return Source(compilation_unit)

s, l, f = position[0]
s = int(s)
l = int(l)
f = int(f)

if f not in sourceUnits:
new_source = Source()
new_source = Source(compilation_unit)
new_source.start = s
new_source.length = l
return new_source
Expand All @@ -173,7 +170,7 @@ def _convert_source_mapping(

(lines, starting_column, ending_column) = _compute_line(compilation_unit, filename, s, l)

new_source = Source()
new_source = Source(compilation_unit)
new_source.start = s
new_source.length = l
new_source.filename = filename
Expand All @@ -182,28 +179,22 @@ def _convert_source_mapping(
new_source.starting_column = starting_column
new_source.ending_column = ending_column
new_source.end = new_source.start + l

return new_source


class SourceMapping(Context, metaclass=ABCMeta):
def __init__(self) -> None:
super().__init__()
# self._source_mapping: Optional[Dict] = None
self.source_mapping: Source = Source()
self.source_mapping: Optional[Source] = None
self.references: List[Source] = []

def set_offset(
self, offset: Union["Source", str], compilation_unit: "SlitherCompilationUnit"
) -> None:
assert compilation_unit
if isinstance(offset, Source):
self.source_mapping.start = offset.start
self.source_mapping.length = offset.length
self.source_mapping.filename = offset.filename
self.source_mapping.is_dependency = offset.is_dependency
self.source_mapping.lines = offset.lines
self.source_mapping.starting_column = offset.starting_column
self.source_mapping.ending_column = offset.ending_column
self.source_mapping.end = offset.end
self.source_mapping = offset
else:
self.source_mapping = _convert_source_mapping(offset, compilation_unit)
self.source_mapping.compilation_unit = compilation_unit
Expand Down
Loading

0 comments on commit 5869d74

Please sign in to comment.