mirror of https://github.com/crytic/slither
Merge pull request #1660 from crytic/bart1e-detector_for_cc
High cyclomatic complexity detectorpull/1665/head
commit
90efe7adc1
@ -0,0 +1,50 @@ |
||||
from typing import List, Tuple |
||||
|
||||
from slither.core.declarations import Function |
||||
from slither.detectors.abstract_detector import AbstractDetector, DetectorClassification |
||||
from slither.utils.code_complexity import compute_cyclomatic_complexity |
||||
from slither.utils.output import Output |
||||
|
||||
|
||||
def _check_for_high_cc(high_cc_functions: List[Tuple[Function, int]], f: Function) -> None: |
||||
cc = compute_cyclomatic_complexity(f) |
||||
if cc > 11: |
||||
high_cc_functions.append((f, cc)) |
||||
|
||||
|
||||
class CyclomaticComplexity(AbstractDetector): |
||||
""" |
||||
Detects functions with high (> 11) cyclomatic complexity. |
||||
""" |
||||
|
||||
ARGUMENT = "cyclomatic-complexity" |
||||
HELP = "Detects functions with high (> 11) cyclomatic complexity" |
||||
IMPACT = DetectorClassification.INFORMATIONAL |
||||
CONFIDENCE = DetectorClassification.HIGH |
||||
|
||||
WIKI = 'https://github.com/crytic/slither/wiki/Detector-Documentation#cyclomatic-complexity"' |
||||
|
||||
WIKI_TITLE = "Cyclomatic complexity" |
||||
WIKI_DESCRIPTION = "Detects functions with high (> 11) cyclomatic complexity." |
||||
WIKI_EXPLOIT_SCENARIO = "" |
||||
WIKI_RECOMMENDATION = ( |
||||
"Reduce cyclomatic complexity by splitting the function into several smaller subroutines." |
||||
) |
||||
|
||||
def _detect(self) -> List[Output]: |
||||
results = [] |
||||
high_cc_functions: List[Tuple[Function, int]] = [] |
||||
|
||||
f: Function |
||||
for c in self.compilation_unit.contracts: |
||||
for f in c.functions_declared: |
||||
_check_for_high_cc(high_cc_functions, f) |
||||
|
||||
for f in self.compilation_unit.functions_top_level: |
||||
_check_for_high_cc(high_cc_functions, f) |
||||
|
||||
for f, cc in high_cc_functions: |
||||
info = [f, f" has a high cyclomatic complexity ({cc}).\n"] |
||||
res = self.generate_result(info) |
||||
results.append(res) |
||||
return results |
@ -0,0 +1,32 @@ |
||||
pragma solidity 0.8.16; |
||||
|
||||
contract HighCyclomaticComplexity |
||||
{ |
||||
bool bool1; |
||||
bool bool2; |
||||
bool bool3; |
||||
bool bool4; |
||||
bool bool5; |
||||
bool bool6; |
||||
bool bool7; |
||||
bool bool8; |
||||
bool bool9; |
||||
bool bool10; |
||||
bool bool11; |
||||
|
||||
function highCC() internal view |
||||
{ |
||||
if (bool1) |
||||
if (bool2) |
||||
if (bool3) |
||||
if (bool4) |
||||
if (bool5) |
||||
if (bool6) |
||||
if (bool7) |
||||
if (bool8) |
||||
if (bool9) |
||||
if (bool10) |
||||
if (bool11) |
||||
revert(); |
||||
} |
||||
} |
@ -0,0 +1,96 @@ |
||||
[ |
||||
[ |
||||
{ |
||||
"elements": [ |
||||
{ |
||||
"type": "function", |
||||
"name": "highCC", |
||||
"source_mapping": { |
||||
"start": 244, |
||||
"length": 536, |
||||
"filename_relative": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
17, |
||||
18, |
||||
19, |
||||
20, |
||||
21, |
||||
22, |
||||
23, |
||||
24, |
||||
25, |
||||
26, |
||||
27, |
||||
28, |
||||
29, |
||||
30, |
||||
31 |
||||
], |
||||
"starting_column": 5, |
||||
"ending_column": 6 |
||||
}, |
||||
"type_specific_fields": { |
||||
"parent": { |
||||
"type": "contract", |
||||
"name": "HighCyclomaticComplexity", |
||||
"source_mapping": { |
||||
"start": 25, |
||||
"length": 757, |
||||
"filename_relative": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol", |
||||
"filename_absolute": "/GENERIC_PATH", |
||||
"filename_short": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol", |
||||
"is_dependency": false, |
||||
"lines": [ |
||||
3, |
||||
4, |
||||
5, |
||||
6, |
||||
7, |
||||
8, |
||||
9, |
||||
10, |
||||
11, |
||||
12, |
||||
13, |
||||
14, |
||||
15, |
||||
16, |
||||
17, |
||||
18, |
||||
19, |
||||
20, |
||||
21, |
||||
22, |
||||
23, |
||||
24, |
||||
25, |
||||
26, |
||||
27, |
||||
28, |
||||
29, |
||||
30, |
||||
31, |
||||
32, |
||||
33 |
||||
], |
||||
"starting_column": 1, |
||||
"ending_column": 0 |
||||
} |
||||
}, |
||||
"signature": "highCC()" |
||||
} |
||||
} |
||||
], |
||||
"description": "HighCyclomaticComplexity.highCC() (tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#17-31) has a high cyclomatic complexity (12).\n", |
||||
"markdown": "[HighCyclomaticComplexity.highCC()](tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#L17-L31) has a high cyclomatic complexity (12).\n", |
||||
"first_markdown_element": "tests/detectors/cyclomatic-complexity/0.8.16/HighCyclomaticComplexity.sol#L17-L31", |
||||
"id": "405b9e7f5697539c75171d728f0a10b6ebb7fe08441c445b0e63c33982c98e2d", |
||||
"check": "cyclomatic-complexity", |
||||
"impact": "Informational", |
||||
"confidence": "High" |
||||
} |
||||
] |
||||
] |
@ -0,0 +1,15 @@ |
||||
pragma solidity 0.8.16; |
||||
|
||||
contract LowCyclomaticComplexity |
||||
{ |
||||
function lowCC() public pure |
||||
{ |
||||
for (uint i = 0; i < 10; i++) |
||||
{ |
||||
for (uint j = 0; j < i; j++) |
||||
{ |
||||
uint a = i + 1; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,3 @@ |
||||
[ |
||||
[] |
||||
] |
Loading…
Reference in new issue