Skip to content

Commit

Permalink
Exclude location for printer output
Browse files Browse the repository at this point in the history
This PR adds a new parameter to slither (--exlude-location) that exclude locations information from printer output.

Closes #2222
  • Loading branch information
DarkaMaul committed Apr 16, 2024
1 parent 57743a4 commit bdfef7a
Show file tree
Hide file tree
Showing 86 changed files with 703 additions and 27 deletions.
7 changes: 7 additions & 0 deletions slither/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,13 @@ def parse_args(
default=defaults_flag_in_config["exclude_high"],
)

group_detector.add_argument(
"--exclude-location",
help="Exclude location information from detector output",
action="store_true",
default=defaults_flag_in_config["exclude_location"],
)

fail_on_group = group_detector.add_mutually_exclusive_group()
fail_on_group.add_argument(
"--fail-pedantic",
Expand Down
1 change: 1 addition & 0 deletions slither/detectors/abstract_detector.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ def generate_result(
additional_fields,
standard_format=self.STANDARD_JSON,
markdown_root=self.slither.markdown_root,
exclude_location=self.slither.exclude_location,
)

output.data["check"] = self.ARGUMENT
Expand Down
2 changes: 2 additions & 0 deletions slither/slither.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ def __init__(self, target: Union[str, CryticCompile], **kwargs) -> None:
generate_patches (bool): if true, patches are generated (json output only)
change_line_prefix (str): Change the line prefix (default #)
for the displayed source codes (i.e. file.sol#1).
exclude_location (bool): if true, exclude locations from detector output (default false)
"""
super().__init__()
Expand Down Expand Up @@ -186,6 +187,7 @@ def __init__(self, target: Union[str, CryticCompile], **kwargs) -> None:
self.add_path_to_include(p)

self._exclude_dependencies = kwargs.get("exclude_dependencies", False)
self.exclude_location = kwargs.get("exclude_location", False)

triage_mode = kwargs.get("triage_mode", False)
triage_database = kwargs.get("triage_database", "slither.db.json")
Expand Down
1 change: 1 addition & 0 deletions slither/utils/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class FailOnLevel(enum.Enum):
"exclude_dependencies": False,
"exclude_informational": False,
"exclude_optimization": False,
"exclude_location": False,
"exclude_low": False,
"exclude_medium": False,
"exclude_high": False,
Expand Down
54 changes: 31 additions & 23 deletions slither/utils/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,46 +229,49 @@ def output_to_zip(filename: str, error: Optional[str], results: Dict, zip_type:
###################################################################################


def _convert_to_description(d: str) -> str:
def _convert_to_description(d: Any, exclude_location: bool = False) -> str:
if isinstance(d, str):
return d

if not isinstance(d, SourceMapping):
raise SlitherError(f"{d} does not inherit from SourceMapping, conversion impossible")

if isinstance(d, Node):
if d.expression:
return f"{d.expression} ({d.source_mapping})"
return f"{str(d)} ({d.source_mapping})"

if hasattr(d, "canonical_name"):
return f"{d.canonical_name} ({d.source_mapping})"
first_part = f"{d.expression}" if d.expression else f"{str(d)}"
elif hasattr(d, "canonical_name"):
first_part = f"{d.canonical_name}"
elif hasattr(d, "name"):
first_part = f"{d.name}"
else:
raise SlitherError(f"{type(d)} cannot be converted (no name, or canonical_name")

if hasattr(d, "name"):
return f"{d.name} ({d.source_mapping})"
if exclude_location:
return first_part

raise SlitherError(f"{type(d)} cannot be converted (no name, or canonical_name")
return f"{first_part} ({d.source_mapping})"


def _convert_to_markdown(d: str, markdown_root: str) -> str:
def _convert_to_markdown(d: str, markdown_root: str, exclude_location: bool = False) -> str:
if isinstance(d, str):
return d

if not isinstance(d, SourceMapping):
raise SlitherError(f"{d} does not inherit from SourceMapping, conversion impossible")

first_part: str
if isinstance(d, Node):
if d.expression:
return f"[{d.expression}]({d.source_mapping.to_markdown(markdown_root)})"
return f"[{str(d)}]({d.source_mapping.to_markdown(markdown_root)})"

if hasattr(d, "canonical_name"):
return f"[{d.canonical_name}]({d.source_mapping.to_markdown(markdown_root)})"
first_part = f"[{d.expression}]" if d.expression else f"[{str(d)}]"
elif hasattr(d, "canonical_name"):
first_part = f"[{d.canonical_name}]"
elif hasattr(d, "name"):
first_part = f"[{d.name}]"
else:
raise SlitherError(f"{type(d)} cannot be converted (no name, or canonical_name")

if hasattr(d, "name"):
return f"[{d.name}]({d.source_mapping.to_markdown(markdown_root)})"
if exclude_location:
return first_part

raise SlitherError(f"{type(d)} cannot be converted (no name, or canonical_name")
return f"{first_part}({d.source_mapping.to_markdown(markdown_root)})"


def _convert_to_id(d: str) -> str:
Expand Down Expand Up @@ -386,12 +389,13 @@ def _create_parent_element(


class Output:
def __init__(
def __init__( # pylint: disable=too-many-arguments
self,
info_: Union[str, List[Union[str, SupportedOutput]]],
additional_fields: Optional[Dict] = None,
markdown_root: str = "",
standard_format: bool = True,
exclude_location: bool = False,
) -> None:
if additional_fields is None:
additional_fields = {}
Expand All @@ -405,8 +409,12 @@ def __init__(

self._data = OrderedDict()
self._data["elements"] = []
self._data["description"] = "".join(_convert_to_description(d) for d in info)
self._data["markdown"] = "".join(_convert_to_markdown(d, markdown_root) for d in info)
self._data["description"] = "".join(
_convert_to_description(d, exclude_location) for d in info
)
self._data["markdown"] = "".join(
_convert_to_markdown(d, markdown_root, exclude_location) for d in info
)
self._data["first_markdown_element"] = ""
self._markdown_root = markdown_root

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Function A.bad5() trigger an abi encoding bug:
- event2_bad(s)

Function A.bad0() trigger an abi encoding bug:
- this.bad0_external(bad_arr)

Function A.bad4() trigger an abi encoding bug:
- event1_bad(bad_arr)

Function A.bad2() trigger an abi encoding bug:
- b = abi.encode(bad_arr)

Function A.bad1(A.S[3]) trigger an abi encoding bug:
- this.bad1_external(s)

Function A.bad3() trigger an abi encoding bug:
- b = abi.encode(s)

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
C.bad1(address,uint256) uses arbitrary from in transferFrom: erc20.transferFrom(notsend,to,am)

C.bad3(address,address,uint256) uses arbitrary from in transferFrom: erc20.safeTransferFrom(from,to,amount)

C.bad4(address,address,uint256) uses arbitrary from in transferFrom: SafeERC20.safeTransferFrom(erc20,from,to,amount)

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
C.int_transferFrom(address,uint256,uint256,uint8,bytes32,bytes32,address) uses arbitrary from in transferFrom in combination with permit: erc20.transferFrom(from,to,value)

C.bad1(address,uint256,uint256,uint8,bytes32,bytes32,address) uses arbitrary from in transferFrom in combination with permit: erc20.transferFrom(from,to,value)

C.bad4(address,uint256,uint256,uint8,bytes32,bytes32,address) uses arbitrary from in transferFrom in combination with permit: SafeERC20.safeTransferFrom(erc20,from,to,value)

C.bad3(address,uint256,uint256,uint8,bytes32,bytes32,address) uses arbitrary from in transferFrom in combination with permit: erc20.safeTransferFrom(from,to,value)

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Test.direct() sends eth to arbitrary user
Dangerous calls:
- msg.sender.send(address(this).balance)

Test.indirect() sends eth to arbitrary user
Dangerous calls:
- destination.send(address(this).balance)

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ArrayLengthAssignment contract sets array length with a user-controlled value:
- b.subStruct.x.length = param + 1

ArrayLengthAssignment contract sets array length with a user-controlled value:
- a.x.length = param

ArrayLengthAssignment contract sets array length with a user-controlled value:
- arr.length = param

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GetCode.at(address) uses assembly
- INLINE ASM

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
VectorSum.sumAsm(uint256[]) uses assembly
- INLINE ASM

VectorSum.sumPureAsm(uint256[]) uses assembly
- INLINE ASM

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
A.bad2() has an assert() call which possibly changes state.
-assert(bool)(bad2_callee())
Consider using require() or change the invariant to not modify the state.

A.bad0() has an assert() call which possibly changes state.
-assert(bool)((s_a += 1) > 10)
Consider using require() or change the invariant to not modify the state.

A.bad1(uint256) has an assert() call which possibly changes state.
-assert(bool)((s_a += a) > 10)
Consider using require() or change the invariant to not modify the state.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Backdoor function found in C.i_am_a_backdoor()

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
BadPRNG.bad1() uses a weak PRNG: "i = now % 10"

BadPRNG.bad0() uses a weak PRNG: "i = block.timestamp % 10"

BadPRNG.bad2() uses a weak PRNG: "i = uint256(blockhash(uint256)(10000)) % 10"

BadPRNG.bad3() uses a weak PRNG: "i = foo() % 10"

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
MyConc.bad1(bool) uses a Boolean constant improperly:
-(b || true)

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ExtendedContract.ecrecover (state variable) shadows built-in symbol"

FurtherExtendedContract.require().keccak256 (local variable) shadows built-in symbol"

FurtherExtendedContract.abi (state variable) shadows built-in symbol"

BaseContract.blockhash (state variable) shadows built-in symbol"

FurtherExtendedContract.this (state variable) shadows built-in symbol"

BaseContract.now (state variable) shadows built-in symbol"

ExtendedContract.assert(bool).msg (local variable) shadows built-in symbol"

ExtendedContract.assert(bool) (function) shadows built-in symbol"

BaseContract.revert(bool) (event) shadows built-in symbol"

FurtherExtendedContract.require().sha3 (local variable) shadows built-in symbol"

FurtherExtendedContract.blockhash (state variable) shadows built-in symbol"

FurtherExtendedContract.require() (modifier) shadows built-in symbol"

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
2 different versions of Solidity are used:
- Version constraint ^0.7.6 is used by:
- tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.6.sol#1
- Version constraint ^0.7.5 is used by:
- tests/e2e/detectors/test_data/pragma/0.7.6/pragma.0.7.5.sol#1

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
C.bad_delegate_call2(bytes) uses delegatecall to a input-controlled function id
- addr_bad.delegatecall(abi.encode(func_id,data))

C.bad_delegate_call(bytes) uses delegatecall to a input-controlled function id
- addr_bad.delegatecall(data)

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
A.text2 should be constant

B.mySistersAddress should be constant

A.myFriendsAddress should be constant

MyConc.should_be_constant should be constant

MyConc.should_be_constant_2 should be constant

A.test should be constant

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
C.bad(address[]) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))

C.bad3(address[]) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))

C.bad2_internal(address[]) has delegatecall inside a loop in a payable function: address(this).delegatecall(abi.encodeWithSignature(addBalance(address),receivers[i]))

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A.f(uint256,uint256,uint256) performs a multiplication on the result of a division:
- (a / b) * c

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The function signature of ERC20.fopwCDKKK() collides with DOMAIN_SEPARATOR and should be renamed or removed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The function signature of ERC20.fopwCDKKK collides with DOMAIN_SEPARATOR and should be renamed or removed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
The function signature of ERC20.DOMAIN_SEPARATOR() collides with DOMAIN_SEPARATOR and should be renamed or removed.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
bad4(string) should be declared external:
- Test.bad4(string)
Moreover, the following function parameters should change its data location:
x location should be calldata

bad3(Test.testStruct) should be declared external:
- Test.bad3(Test.testStruct)
Moreover, the following function parameters should change its data location:
x location should be calldata

bad2(uint256[]) should be declared external:
- Test.bad2(uint256[])
Moreover, the following function parameters should change its data location:
x location should be calldata

bad(bytes) should be declared external:
- Test.bad(bytes)
Moreover, the following function parameters should change its data location:
x location should be calldata

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
StateVarInitFromFunction.v is set pre-construction with a non-constant function or state variable:
- set()

StateVarInitFromFunction.z4 is set pre-construction with a non-constant function or state variable:
- z3 + 5

StateVarInitFromFunction.x is set pre-construction with a non-constant function or state variable:
- set()

StateVarInitFromFunction.y1 is set pre-construction with a non-constant function or state variable:
- 5 + get()

StateVarInitFromFunction.y2 is set pre-construction with a non-constant function or state variable:
- (10 + (5 + get()))

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Token has incorrect ERC20 function interface:Token.approve(address,uint256)

Token has incorrect ERC20 function interface:Token.allowance(address,address)

Token has incorrect ERC20 function interface:Token.balanceOf(address)

Token has incorrect ERC20 function interface:Token.transferFrom(address,address,uint256)

Token has incorrect ERC20 function interface:Token.totalSupply()

Token has incorrect ERC20 function interface:Token.transfer(address,uint256)

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Version constraint >=0.5.0<0.6.0 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
- DirtyBytesArrayToStorage
- ABIDecodeTwoDimensionalArrayMemory
- KeccakCaching
- EmptyByteArrayCopy
- DynamicArrayCleanup
- ImplicitConstructorCallvalueCheck
- TupleAssignmentMultiStackSlotComponents
- MemoryArrayCreationOverflow
- privateCanBeOverridden
- SignedArrayStorageCopy
- ABIEncoderV2StorageArrayWithMultiSlotElement
- DynamicConstructorArgumentsClippedABIV2
- UninitializedFunctionPointerInConstructor
- IncorrectEventSignatureInLibraries
- ABIEncoderV2PackedStorage.
It is used by:
- tests/e2e/detectors/test_data/solc-version/0.5.16/dynamic_2.sol#1

solc-0.5.16 is an outdated solc version. Use a more recent version (at least 0.8.0), if possible.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Version constraint 0.7.4 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html)
- FullInlinerNonExpressionSplitArgumentEvaluationOrder
- MissingSideEffectsOnSelectorAccess
- AbiReencodingHeadOverflowWithStaticArrayCleanup
- DirtyBytesArrayToStorage
- DataLocationChangeInInternalOverride
- NestedCalldataArrayAbiReencodingSizeValidation
- SignedImmutables
- ABIDecodeTwoDimensionalArrayMemory
- KeccakCaching.
It is used by:
- tests/e2e/detectors/test_data/solc-version/0.7.4/static.sol#1

solc-0.7.4 is an outdated solc version. Use a more recent version (at least 0.8.0), if possible.

Loading

0 comments on commit bdfef7a

Please sign in to comment.