Skip to content

Commit

Permalink
code-coverage: handle functions in __init__.py files (#1005)
Browse files Browse the repository at this point in the history
* code-coverage: handle functions in __init__.py files

Fixes: ossf/fuzz-introspector#1003

Signed-off-by: David Korczynski <[email protected]>

* utils: fix link-handling of functions declared in __init__.py files

Signed-off-by: David Korczynski <[email protected]>

* fix formatting

Signed-off-by: David Korczynski <[email protected]>

* formatting nit

Signed-off-by: David Korczynski <[email protected]>

---------

Signed-off-by: David Korczynski <[email protected]>
  • Loading branch information
shovon58 committed Apr 24, 2023
1 parent 1ba90bc commit 86f9fd7
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/fuzz_introspector/code_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,9 +180,11 @@ def _python_ast_funcname_to_cov_file(self, function_name) -> Optional[str]:
# Resolve name if required. This is needed to normalise filenames.
logger.debug("Resolving name")
potential_paths = []
init_paths = []
current_path = ""
for module_name in function_name.split("."):
current_path += module_name
init_paths.append(current_path + "/__init__.py")
potential_paths.append(current_path + ".py")
current_path += "/"

Expand All @@ -193,6 +195,24 @@ def _python_ast_funcname_to_cov_file(self, function_name) -> Optional[str]:
if potential_key.endswith(potential_path):
logger.debug(f"Found key: {str(potential_key)}")
return potential_key
# We found no matches when filenames exclude __init__.py. Try to
# include these now.
init_matches = []
# Iterate based in init paths since we want to have the longest match
# at the end of __init__matches list.
logger.info("Scanning for init paths")
for potential_init_path in init_paths:
logger.info("Trying %s" % (potential_init_path))
for potential_key in self.file_map:
logger.debug(f"Scanning {str(potential_key)}")
if potential_key.endswith(potential_init_path):
logger.debug(f"Found __init__ match: {str(potential_key)}")
init_matches.append(potential_key)

# Return the last match, as this signals the path with most precise
# matching.
if len(init_matches) > 0:
return init_matches[-1]

# If this is reached then no match was found. Return None.
logger.debug("Could not find key")
Expand Down Expand Up @@ -639,7 +659,6 @@ def load_python_json_coverage(json_file: str,
'executed_lines']
cp.dual_file_map[cov_entry]['missing_lines'] = data['files'][entry][
'missing_lines']

return cp


Expand Down
12 changes: 12 additions & 0 deletions src/fuzz_introspector/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,13 @@ def approximate_python_coverage_files(src1: str, src2: str) -> bool:

# Generate list of potential candidates
possible_candidates = []
possible_init_candidates = []
splits = src1.split(".")
curr_str = ""
for s2 in splits:
curr_str = curr_str + s2
possible_candidates.append(curr_str + ".py")
possible_init_candidates.append("/__init__.py")
curr_str = curr_str + "/"

# Start from backwards to find te longest possible candidate
Expand All @@ -218,6 +220,16 @@ def approximate_python_coverage_files(src1: str, src2: str) -> bool:
target = candidate
break

if target is None:
for init_candidate in reversed(possible_init_candidates):
if src2.endswith(init_candidate):
# ensure the entire filename is matched in the event of not slashes
if "/" not in init_candidate:
if not src2.split("/")[-1] == init_candidate:
continue
target = init_candidate
break

if target is not None:
logger.debug(f"Found target {target}")
return True
Expand Down

0 comments on commit 86f9fd7

Please sign in to comment.