From 263344e886551d4a09f97fcd936d8a7ecf27cff5 Mon Sep 17 00:00:00 2001 From: Arifdev1 Date: Tue, 2 Jul 2024 13:57:20 +0100 Subject: [PATCH] webapi: add optimal target analysis API (#1642) * webapp: apis: enable sorting out non-declared functins Signed-off-by: David Korczynski * webapp: add optimal target analysis API Ref: https://github.com/google/oss-fuzz-gen/issues/356#issuecomment-2178716065 Signed-off-by: David Korczynski --------- Signed-off-by: David Korczynski --- .../assets/db/web_db_creator_from_summary.py | 4 ++ .../app/webapp/routes.py | 71 +++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/tools/web-fuzzing-introspection/app/static/assets/db/web_db_creator_from_summary.py b/tools/web-fuzzing-introspection/app/static/assets/db/web_db_creator_from_summary.py index 5ff5a79..b026e54 100644 --- a/tools/web-fuzzing-introspection/app/static/assets/db/web_db_creator_from_summary.py +++ b/tools/web-fuzzing-introspection/app/static/assets/db/web_db_creator_from_summary.py @@ -543,6 +543,9 @@ def extract_project_data(project_name, date_str, should_include_details, functions_covered_estimate = project_stats[ 'code-coverage-function-percentage'] + optimal_targets = introspector_report.get('analyses', {}).get( + 'OptimalTargets', []) + # Get details if needed and otherwise leave empty refined_proj_list = list() refined_constructor_list = list() @@ -581,6 +584,7 @@ def extract_project_data(project_name, date_str, should_include_details, 'refined_proj_list': refined_proj_list, 'refined_constructor_list': refined_constructor_list, 'annotated_cfg': annotated_cfg, + 'optimal_targets': optimal_targets, } code_coverage_data_dict = extract_code_coverage_data( diff --git a/tools/web-fuzzing-introspection/app/webapp/routes.py b/tools/web-fuzzing-introspection/app/webapp/routes.py index 0781712..c53efd6 100644 --- a/tools/web-fuzzing-introspection/app/webapp/routes.py +++ b/tools/web-fuzzing-introspection/app/webapp/routes.py @@ -835,6 +835,77 @@ def api(): return render_template('api.html', gtag=gtag) +@blueprint.route('/api/optimal-targets') +def api_optimal_targets(): + """Returns the list of functions generated by Fuzz Introspector's analysis + `Optimal Targets`. + """ + project_name = request.args.get('project', None) + if project_name is None: + return {'result': 'error', 'msg': 'Please provide project name'} + + target_project = None + all_projects = data_storage.get_projects() + for project in all_projects: + if project.name == project_name: + target_project = project + break + if target_project is None: + return {'result': 'error', 'msg': 'Project not in the database'} + + if target_project.introspector_data is None: + return {'result': 'error', 'msg': 'Found no introspector data.'} + + all_functions = data_storage.get_functions() + project_functions = [] + for function in all_functions: + if function.project == project_name: + project_functions.append(function) + + try: + optimal_targets_raw = target_project.introspector_data[ + 'optimal_targets'] + function_model_optimal_targets = [] + for function in optimal_targets_raw: + substituted_function = None + for model_func in project_functions: + if model_func.name == function['name'].replace(' ', ''): + substituted_function = { + 'function_name': model_func.name, + 'function_filename': model_func.function_filename, + 'runtime_coverage_percent': + model_func.runtime_code_coverage, + 'accummulated_complexity': + model_func.accummulated_cyclomatic_complexity, + 'function_arguments': model_func.function_arguments, + 'function_argument_names': + model_func.function_argument_names, + 'return_type': model_func.return_type, + 'is_reached': model_func.is_reached, + 'reached_by_fuzzers': model_func.reached_by_fuzzers, + 'raw_function_name': model_func.raw_function_name, + 'source_line_begin': model_func.source_line_begin, + 'source_line_end': model_func.source_line_end, + 'function_signature': model_func.func_signature, + 'debug_summary': model_func.debug_data, + } + break + if substituted_function: + function_model_optimal_targets.append(substituted_function) + + return { + 'result': 'success', + 'project': { + 'name': project_name, + 'functions': function_model_optimal_targets + } + } + except KeyError: + return {'result': 'error', 'msg': 'Found no optimal analysis.'} + except TypeError: + return {'result': 'error', 'msg': 'Found no introspector data.'} + + @blueprint.route('/api/annotated-cfg') def api_annotated_cfg(): project_name = request.args.get('project', None)