diff --git a/src/fuzz_introspector/analysis.py b/src/fuzz_introspector/analysis.py index 85661dd9e..5b18c52ce 100644 --- a/src/fuzz_introspector/analysis.py +++ b/src/fuzz_introspector/analysis.py @@ -28,6 +28,7 @@ ) from fuzz_introspector import utils +from fuzz_introspector import constants from fuzz_introspector import cfg_load from fuzz_introspector import code_coverage from fuzz_introspector import html_helpers @@ -254,13 +255,7 @@ def callstack_set_curr_node( # Map hitcount to color of target. def get_hit_count_color(hit_count: int) -> str: - color_schemes = [ - (0, 1, "red"), - (1, 10, "gold"), - (10, 30, "yellow"), - (30, 50, "greenyellow"), - (50, 1000000000000, "lawngreen")] - for cmin, cmax, cname in color_schemes: + for cmin, cmax, cname, rgb in constants.COLOR_CONSTANTS: if hit_count >= cmin and hit_count < cmax: return cname return "red" diff --git a/src/fuzz_introspector/constants.py b/src/fuzz_introspector/constants.py index ea83b7340..3c2aa0775 100644 --- a/src/fuzz_introspector/constants.py +++ b/src/fuzz_introspector/constants.py @@ -22,3 +22,19 @@ APP_EXIT_SUCCESS = 0 INPUT_BUG_FILE = "input_bugs.json" + +# Color constants used for call trees. Composed of tuples, +# (min, max, color) where +# min and max construct an interval [min: max) (max non-inclusive) +# and this interval indicates how many times a callsite was hit. If a +# callsite is hit X times and X falls in the given interval then it will +# have the color of the tuple. +# - color is the string +# The hitcount is [min:max) +COLOR_CONSTANTS = [ + (0, 1, "red", "#ff0000"), + (1, 10, "gold", "#ffd700"), + (10, 30, "yellow", "#ffff00"), + (30, 50, "greenyellow", "#adff2f"), + (50, 1000000000000, "lawngreen", "#7cfc00") +] diff --git a/src/fuzz_introspector/html_report.py b/src/fuzz_introspector/html_report.py index 4c5fed5ee..eff8bdb15 100644 --- a/src/fuzz_introspector/html_report.py +++ b/src/fuzz_introspector/html_report.py @@ -46,7 +46,7 @@ def create_horisontal_calltree_image( image_name: str, profile: fuzzer_profile.FuzzerProfile -) -> None: +) -> List[str]: """ Creates a horisontal image of the calltree. The height is fixed and each element on the x-axis shows a node in the calltree in the form @@ -56,7 +56,8 @@ def create_horisontal_calltree_image( logger.info(f"Creating image {image_name}") if profile.function_call_depths is None: - return + return [] + # Extract color sequence color_list: List[str] = [] for node in cfg_load.extract_all_callsites(profile.function_call_depths): @@ -116,6 +117,7 @@ def create_horisontal_calltree_image( fig.tight_layout() fig.savefig(image_name, bbox_extra_artists=[xlabel]) logger.info("- image saved") + return color_list def create_overview_table( @@ -498,13 +500,26 @@ def create_fuzzer_detailed_section( f"The following is the call tree with color coding for which " f"functions are hit/not hit. This info is based on the coverage " f"achieved of all fuzzers together and not just this specific " - f"fuzzer." - f"

" - f"

" + f"fuzzer. We use the following coloring scheme where min/max is " + f"an interval [min:max) (max non-inclusive) to color the callsite " + f"based on how many times the callsite is covered at run time." + ) + html_string += ( + "" + "" + "" + ) + for _min, _max, color, rgb_code in constants.COLOR_CONSTANTS: + html_string += "" + html_string += f"" + html_string += ( + f"" + ) + html_string += "" + html_string += "
MinMaxColor
{_min}{_max}{color}

" + html_string += ( f"

" f"For further technical details on the call tree overview" f", please see the " + color_dictionary = { + "red": 0, + "gold": 0, + "yellow": 0, + "greenyellow": 0, + "lawngreen": 0 + } + for color in color_list: + color_dictionary[color] = color_dictionary[color] + 1 + html_string += ( + "

The distribution of callsites in terms of hit count is" + ) + + html_string += ( + "" + "" + "" + ) + for _min, _max, color, rgb_code in constants.COLOR_CONSTANTS: + html_string += ( + f"" + ) + html_string += f"" + + # Add a row with total amount of callsites + html_string += f"" + html_string += "
ColorCallsite count
{color}{color_dictionary[color]}
All colors{len(color_list)}
" + html_string += "

" # Full calltree html_string += html_helpers.html_add_header_with_link(