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?!")
Exemple #2
0
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?!")
Exemple #4
0
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!"
        )
Exemple #5
0
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,
                    )
Exemple #6
0
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"]])