mirror of https://github.com/crytic/slither
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
3.0 KiB
57 lines
3.0 KiB
6 years ago
|
import re
|
||
|
from ..utils.patches import create_patch
|
||
6 years ago
|
|
||
|
class FormatExternalFunction:
|
||
|
|
||
|
@staticmethod
|
||
|
def format (slither, patches, elements):
|
||
|
for element in elements:
|
||
6 years ago
|
target_contract = slither.get_contract_from_name(element['type_specific_fields']['parent']['name'])
|
||
|
if target_contract:
|
||
|
for function in target_contract.functions:
|
||
|
if function.name == element['name']:
|
||
|
# If function parameters are written to in function body then we cannot convert this function
|
||
|
# to external because external function parameters are allocated in calldata region which is
|
||
|
# non-modifiable. See https://solidity.readthedocs.io/en/develop/types.html#data-location
|
||
|
if not FormatExternalFunction.function_parameters_written(function):
|
||
6 years ago
|
FormatExternalFunction.create_patch(slither, patches,
|
||
|
element['source_mapping']['filename_absolute'],
|
||
|
element['source_mapping']['filename_relative'],
|
||
|
"external",
|
||
|
int(function.parameters_src.source_mapping['start']),
|
||
6 years ago
|
int(function.returns_src.source_mapping['start']))
|
||
6 years ago
|
break
|
||
6 years ago
|
|
||
|
@staticmethod
|
||
6 years ago
|
def create_patch(slither, patches, in_file, in_file_relative, replace_text, modify_loc_start, modify_loc_end):
|
||
6 years ago
|
in_file_str = slither.source_code[in_file].encode('utf-8')
|
||
6 years ago
|
old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end]
|
||
6 years ago
|
m = re.search(r'((\spublic)\s+)|(\spublic)$|(\)public)$', old_str_of_interest.decode('utf-8'))
|
||
6 years ago
|
if m is None:
|
||
|
# No visibility specifier exists; public by default.
|
||
6 years ago
|
create_patch(patches,
|
||
|
"external-function",
|
||
|
in_file_relative,
|
||
|
in_file,
|
||
|
modify_loc_start + len(old_str_of_interest.decode('utf-8').split(')')[0]) + 1,
|
||
|
modify_loc_start + len(old_str_of_interest.decode('utf-8').split(')')[0]) + 1,
|
||
|
"",
|
||
|
" "+ replace_text)
|
||
6 years ago
|
else:
|
||
6 years ago
|
create_patch(patches,
|
||
|
"external-function",
|
||
|
in_file_relative,
|
||
|
in_file,
|
||
|
modify_loc_start + m.span()[0] + 1,
|
||
|
modify_loc_start + m.span()[0] + 1 + 6,
|
||
|
"",
|
||
|
" " + replace_text)
|
||
6 years ago
|
|
||
|
@staticmethod
|
||
|
def function_parameters_written(function):
|
||
|
for node in function.nodes:
|
||
|
if any (var.name == parameter.name for var in node.local_variables_written for parameter in function.parameters):
|
||
|
return True
|
||
|
return False
|
||
|
|