def _patch( # pylint: disable=too-many-arguments compilation_unit: SlitherCompilationUnit, result, in_file, match_text, replace_text, modify_loc_start, modify_loc_end, ): in_file_str = compilation_unit.core.source_code[in_file].encode("utf8") old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] # Add keyword `constant` before the variable name (new_str_of_interest, num_repl) = re.subn(match_text, replace_text, old_str_of_interest.decode("utf-8"), 1) if num_repl != 0: create_patch( result, in_file, modify_loc_start, modify_loc_end, old_str_of_interest, new_str_of_interest, ) else: raise FormatError("State variable not found?!")
def _patch(slither, result, element, _target): if _target == "contract": target = slither.get_contract_from_name(element['name']) elif _target == "structure": target = _get_from_contract(slither, element, element['name'], 'get_structure_from_name') elif _target == "event": target = _get_from_contract(slither, element, element['name'], 'get_event_from_name') elif _target == "function": # Avoid constructor (FP?) if element['name'] != element['type_specific_fields']['parent']['name']: function_sig = element['type_specific_fields']['signature'] target = _get_from_contract(slither, element, function_sig, 'get_function_from_signature') elif _target == "modifier": modifier_sig = element['type_specific_fields']['signature'] target = _get_from_contract(slither, element, modifier_sig, 'get_modifier_from_signature') elif _target == "parameter": contract_name = element['type_specific_fields']['parent'][ 'type_specific_fields']['parent']['name'] function_sig = element['type_specific_fields']['parent'][ 'type_specific_fields']['signature'] param_name = element['name'] contract = slither.get_contract_from_name(contract_name) function = contract.get_function_from_signature(function_sig) target = function.get_local_variable_from_name(param_name) elif _target in ["variable", "variable_constant"]: # Local variable if element['type_specific_fields']['parent'] == 'function': contract_name = element['type_specific_fields']['parent'][ 'type_specific_fields']['parent']['name'] function_sig = element['type_specific_fields']['parent'][ 'type_specific_fields']['signature'] var_name = element['name'] contract = slither.get_contract_from_name(contract_name) function = contract.get_function_from_signature(function_sig) target = function.get_local_variable_from_name(var_name) # State variable else: target = _get_from_contract(slither, element, element['name'], 'get_state_variable_from_name') elif _target == "enum": target = _get_from_contract(slither, element, element['name'], 'get_enum_from_canonical_name') else: raise FormatError("Unknown naming convention! " + _target) _explore(slither, result, target, conventions[element['additional_fields']['convention']])
def _patch(slither, result, in_file, match_text, replace_text, modify_loc_start, modify_loc_end): in_file_str = slither.source_code[in_file].encode('utf8') old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] # Add keyword `constant` before the variable name (new_str_of_interest, num_repl) = re.subn(match_text, replace_text, old_str_of_interest.decode('utf-8'), 1) if num_repl != 0: create_patch(result, in_file, modify_loc_start, modify_loc_end, old_str_of_interest, new_str_of_interest) else: raise FormatError("State variable not found?!")
def _patch(slither, result, in_file, modify_loc_start, modify_loc_end): in_file_str = slither.source_code[in_file].encode('utf8') old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] # Find the keywords view|pure|constant and remove them m = re.search("(view|pure|constant)", old_str_of_interest.decode('utf-8')) if m: create_patch( result, in_file, modify_loc_start + m.span()[0], modify_loc_start + m.span()[1], m.groups(0)[0], # this is view|pure|constant "") else: raise FormatError( "No view/pure/constant specifier exists. Regex failed to remove specifier!" )
def _explore_irs(slither, irs, result, target, convert): # pylint: disable=too-many-locals if irs is None: return for ir in irs: for v in get_ir_variables(ir): if target == v or ( isinstance(target, Function) and isinstance(v, Function) and v.canonical_name == target.canonical_name ): source_mapping = ir.expression.source_mapping filename_source_code = source_mapping["filename_absolute"] full_txt_start = source_mapping["start"] full_txt_end = full_txt_start + source_mapping["length"] full_txt = slither.source_code[filename_source_code].encode("utf8")[ full_txt_start:full_txt_end ] if not target.name.encode("utf8") in full_txt: raise FormatError(f"{target} not found in {full_txt} ({source_mapping}") old_str = target.name.encode("utf8") new_str = convert(old_str, slither) counter = 0 # Can be found multiple time on the same IR # We patch one by one while old_str in full_txt: target_found_at = full_txt.find((old_str)) full_txt = full_txt[target_found_at + 1 :] counter += target_found_at loc_start = full_txt_start + counter loc_end = loc_start + len(old_str) create_patch( result, filename_source_code, loc_start, loc_end, old_str, new_str, )
def _patch(compilation_unit: SlitherCompilationUnit, result, element, _target): if _target == "contract": target = compilation_unit.get_contract_from_name(element["name"]) elif _target == "structure": target = _get_from_contract(compilation_unit, element, element["name"], "get_structure_from_name") elif _target == "event": target = _get_from_contract(compilation_unit, element, element["name"], "get_event_from_name") elif _target == "function": # Avoid constructor (FP?) if element["name"] != element["type_specific_fields"]["parent"]["name"]: function_sig = element["type_specific_fields"]["signature"] target = _get_from_contract(compilation_unit, element, function_sig, "get_function_from_signature") elif _target == "modifier": modifier_sig = element["type_specific_fields"]["signature"] target = _get_from_contract(compilation_unit, element, modifier_sig, "get_modifier_from_signature") elif _target == "parameter": contract_name = element["type_specific_fields"]["parent"][ "type_specific_fields"]["parent"]["name"] function_sig = element["type_specific_fields"]["parent"][ "type_specific_fields"]["signature"] param_name = element["name"] contract = compilation_unit.get_contract_from_name(contract_name) function = contract.get_function_from_signature(function_sig) target = function.get_local_variable_from_name(param_name) elif _target in ["variable", "variable_constant"]: # Local variable if element["type_specific_fields"]["parent"] == "function": contract_name = element["type_specific_fields"]["parent"][ "type_specific_fields"]["parent"]["name"] function_sig = element["type_specific_fields"]["parent"][ "type_specific_fields"]["signature"] var_name = element["name"] contract = compilation_unit.get_contract_from_name(contract_name) function = contract.get_function_from_signature(function_sig) target = function.get_local_variable_from_name(var_name) # State variable else: target = _get_from_contract(compilation_unit, element, element["name"], "get_state_variable_from_name") elif _target == "enum": target = _get_from_contract(compilation_unit, element, element["name"], "get_enum_from_canonical_name") else: raise FormatError("Unknown naming convention! " + _target) _explore(compilation_unit, result, target, conventions[element["additional_fields"]["convention"]])