""" Some helping functions to reduce the duplicate code for stand alone evaluation """ import argparse import json from collections import OrderedDict from os import path, listdir from ..ErrorRegistry import ErrorRegistry from ..Error import Error def arg_parse_mackedir(description): """ Parse command line arguments for macke directory """ parser = argparse.ArgumentParser( description=description ) parser.add_argument( "mackedir", help="The directory of a MACKE run to be analyzed") args = parser.parse_args() if (path.isdir(args.mackedir) and path.isfile(path.join(args.mackedir, 'klee.json'))): return args.mackedir else: raise ValueError("'%s' is not a directory of a MACKE run" % args.mackedir) def store_as_json(macke_directory, filename, content): """ Store content as json inside filename """ jsonfile = path.join(macke_directory, filename) with open(jsonfile, 'w') as file: json.dump(content, file) def get_fuzz_outdirs(macke_directory): fuzzdir = path.join(macke_directory, "fuzzer") if not path.isdir(path.join(macke_directory, "fuzzer")): return [] result = [] prefix = "fuzz_out_" for f in listdir(fuzzdir): if not f.startswith(prefix): continue fpath = path.join(fuzzdir, f) function = f[len(prefix):] if path.islink(fpath) or not path.isdir(fpath): continue result.append((function, fpath)) return result def append_to_registry_from_fuzzdir(registry, macke_directory): for (function, fpath) in get_fuzz_outdirs(macke_directory): errordir = path.join(fpath, "macke_errors") # sanity check if path.islink(errordir) or not path.isdir(errordir): continue registry.create_from_dir(errordir, function) def get_klee_registry_from_mackedir(macke_directory): """ Build an OrderedDict with informations about all KLEE runs in a MACKE run """ kinfo = OrderedDict() with open(path.join(macke_directory, 'klee.json')) as klee_json: kinfo = json.load(klee_json, object_pairs_hook=OrderedDict) return kinfo def get_error_registry_for_mackedir(macke_directory, callgraph): """ Build an error Registry for a MACKE run """ Error.set_program_functions(callgraph.get_internal_functions()) macke_directory = path.abspath(macke_directory) registry = ErrorRegistry() klees = get_klee_registry_from_mackedir(macke_directory) append_to_registry_from_fuzzdir(registry, macke_directory) for _, klee in klees.items(): if "function" in klee: registry.create_from_dir(klee['folder'], klee['function']) else: registry.create_from_dir(klee['folder'], klee['caller']) return registry def generic_main(description, feedback, filename, callback): """ Entry point to run an analyse-script stand alone. It reads a MACKE directory, perform the analysis and store the result as a json file. """ mackedir = arg_parse_mackedir(description) store_as_json(mackedir, filename, callback(mackedir)) if feedback: print(feedback % filename)