From dd631a1a089f9602d839c181364f3bdb94e3ac3a Mon Sep 17 00:00:00 2001 From: rajeevgopalakrishna Date: Tue, 28 May 2019 13:29:20 +0530 Subject: [PATCH] - Fixes contract naming convention to include interface & library - Adds success info messages - Adds runSlitherFormat script to run slither-format on a directory of files --- .../format_naming_convention.py | 16 +++++++++++-- utils/slither_format/slither_format.py | 3 +++ .../slither_format/tests/runSlitherFormat.py | 24 +++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 utils/slither_format/tests/runSlitherFormat.py diff --git a/utils/slither_format/format_naming_convention.py b/utils/slither_format/format_naming_convention.py index 2a902a314..740530a6c 100644 --- a/utils/slither_format/format_naming_convention.py +++ b/utils/slither_format/format_naming_convention.py @@ -94,9 +94,9 @@ class FormatNamingConvention: def create_patch_contract_definition(slither, patches, name, in_file, in_file_relative, modify_loc_start, modify_loc_end): in_file_str = slither.source_code[in_file].encode('utf-8') old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] - m = re.match(r'(.*)'+"contract"+r'(.*)'+name, old_str_of_interest.decode('utf-8')) + m = re.match(r'(.*)'+"(contract|interface|library)"+r'(.*)'+name, old_str_of_interest.decode('utf-8')) old_str_of_interest = in_file_str[modify_loc_start:modify_loc_start+m.span()[1]] - (new_str_of_interest, num_repl) = re.subn(r'(.*)'+"contract"+r'(.*)'+name, r'\1'+"contract"+r'\2'+name.capitalize(), + (new_str_of_interest, num_repl) = re.subn(r'(.*)'+r'(contract|interface|library)'+r'(.*)'+name, r'\1'+r'\2'+r'\3'+name.capitalize(), old_str_of_interest.decode('utf-8'), 1) if num_repl != 0: patch = { @@ -166,6 +166,9 @@ class FormatNamingConvention: old_str_of_interest = in_file_str[node.source_mapping['start']:node.source_mapping['start'] + node.source_mapping['length']] m = re.search("new"+r'(.*)'+name, old_str_of_interest.decode('utf-8')) + # Skip rare cases where re search fails. To-do: Investigate + if not m: + continue old_str_of_interest = old_str_of_interest.decode('utf-8')[m.span()[0]:] (new_str_of_interest, num_repl) = re.subn("new"+r'(.*)'+name, "new"+r'\1'+name[0].upper() + name[1:], old_str_of_interest, 1) @@ -430,6 +433,9 @@ class FormatNamingConvention: (node._local_vars_read + node._local_vars_written) if str(lv) == name]: + # Skip rare cases where source_mapping is absent. To-do: Investigate + if not v.source_mapping: + continue modify_loc_start = int(v.source_mapping['start']) modify_loc_end = int(v.source_mapping['start']) + int(v.source_mapping['length']) old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] @@ -500,6 +506,9 @@ class FormatNamingConvention: in_file_str = slither.source_code[in_file].encode('utf-8') old_str_of_interest = in_file_str[modify_loc_start:modify_loc_end] m = re.search(name, old_str_of_interest.decode('utf-8')) + # Skip rare cases where re search fails. To-do: Investigate + if not m: + continue if (_target == "variable_constant"): new_string = old_str_of_interest.decode('utf-8')[m.span()[0]:m.span()[1]].upper() else: @@ -639,6 +648,9 @@ class FormatNamingConvention: node.source_mapping['length'])].decode('utf-8')\ .split('=')[1] m = re.search(r'(.*)'+name, old_str_of_interest) + # Skip rare cases where re search fails. To-do: Investigate + if not m: + continue old_str_of_interest = old_str_of_interest[m.span()[0]:] (new_str_of_interest, num_repl) = re.subn(r'(.*)'+name, r'\1'+name[0].upper()+name[1:], old_str_of_interest, 1) diff --git a/utils/slither_format/slither_format.py b/utils/slither_format/slither_format.py index 8838ba071..5bc3f5596 100644 --- a/utils/slither_format/slither_format.py +++ b/utils/slither_format/slither_format.py @@ -106,11 +106,14 @@ def generate_patch_files(slither, patches): out_file = open(_in_file+".format",'w') out_file.write(out_file_str) out_file.close() + logger.info("slither-format successful.") + logger.info("Created formatted file: " + _in_file+".format") patch_file_name = _in_file + ".format.patch" outFD = open(patch_file_name,"w") p1 = subprocess.Popen(['diff', '-u', _in_file, _in_file+".format"], stdout=outFD) p1.wait() outFD.close() + logger.info("Created patch file: " + patch_file_name) def print_patches(number_of_slither_results, patches): logger.info("Number of Slither results: " + str(number_of_slither_results)) diff --git a/utils/slither_format/tests/runSlitherFormat.py b/utils/slither_format/tests/runSlitherFormat.py new file mode 100644 index 000000000..4f0efd84c --- /dev/null +++ b/utils/slither_format/tests/runSlitherFormat.py @@ -0,0 +1,24 @@ +from os import listdir +from os.path import isfile, join +import subprocess + +contracts_path = "../../smart-contracts-detectors-testing/most_used/contracts/" +slither_format_output_path = "./slither_format/tests/slither_format_output_most_used_contracts/" + +def analyze_contract_with_slither_format(): + for contract_file in contract_files: + run_slither_format(contract_file) + +def run_slither_format(contract_name): + print("Running Slither Format on contract: " + contract_name) + command = "python3 -m slither_format " + contracts_path+contract_name + contract_slither_output_fd = open(slither_format_output_path+contract_name[:-21]+".txt","w+") + contract_slither_output_fd.write("Command run: " + command + "\n\n") + contract_slither_output_fd.flush() + result = subprocess.run(command, shell=True, stdout=contract_slither_output_fd, stderr=contract_slither_output_fd) + contract_slither_output_fd.close() + +if __name__ == "__main__": + contract_files = [f for f in listdir(contracts_path) if f.endswith(".sol")] + print("Number of contract files: " + str(len(contract_files))) + analyze_contract_with_slither_format()