Skip to content

Commit

Permalink
Merge pull request #1922 from DaveLak/fix-fuzz-submodule-expected-exc…
Browse files Browse the repository at this point in the history
…eptions-handling

Add graceful handling of expected exceptions in fuzz_submodule.py
  • Loading branch information
Byron authored May 31, 2024
2 parents 2345c1a + 2b64dee commit 8502efe
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
40 changes: 29 additions & 11 deletions fuzzing/fuzz-targets/fuzz_submodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@
import os
import tempfile
from configparser import ParsingError
from utils import is_expected_exception_message
from utils import is_expected_exception_message, get_max_filename_length
from git import Repo, GitCommandError, InvalidGitRepositoryError

if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): # pragma: no cover
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
os.environ["GIT_PYTHON_GIT_EXECUTABLE"] = path_to_bundled_git_binary

with atheris.instrument_imports():
from git import Repo, GitCommandError, InvalidGitRepositoryError
if not sys.warnoptions: # pragma: no cover
# The warnings filter below can be overridden by passing the -W option
# to the Python interpreter command line or setting the `PYTHONWARNINGS` environment variable.
import warnings
import logging

# Fuzzing data causes some modules to generate a large number of warnings
# which are not usually interesting and make the test output hard to read, so we ignore them.
warnings.simplefilter("ignore")
logging.getLogger().setLevel(logging.ERROR)


def TestOneInput(data):
Expand Down Expand Up @@ -42,12 +51,12 @@ def TestOneInput(data):
writer.release()

submodule.update(init=fdp.ConsumeBool(), dry_run=fdp.ConsumeBool(), force=fdp.ConsumeBool())

submodule_repo = submodule.module()
new_file_path = os.path.join(
submodule_repo.working_tree_dir,
f"new_file_{fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(1, 512))}",

new_file_name = fdp.ConsumeUnicodeNoSurrogates(
fdp.ConsumeIntInRange(1, max(1, get_max_filename_length(submodule_repo.working_tree_dir)))
)
new_file_path = os.path.join(submodule_repo.working_tree_dir, new_file_name)
with open(new_file_path, "wb") as new_file:
new_file.write(fdp.ConsumeBytes(fdp.ConsumeIntInRange(1, 512)))
submodule_repo.index.add([new_file_path])
Expand All @@ -67,16 +76,24 @@ def TestOneInput(data):
)
repo.index.commit(f"Removed submodule {submodule_name}")

except (ParsingError, GitCommandError, InvalidGitRepositoryError, FileNotFoundError, BrokenPipeError):
except (
ParsingError,
GitCommandError,
InvalidGitRepositoryError,
FileNotFoundError,
FileExistsError,
IsADirectoryError,
NotADirectoryError,
BrokenPipeError,
):
return -1
except (ValueError, OSError) as e:
except ValueError as e:
expected_messages = [
"SHA is empty",
"Reference at",
"embedded null byte",
"This submodule instance does not exist anymore",
"cmd stdin was empty",
"File name too long",
]
if is_expected_exception_message(e, expected_messages):
return -1
Expand All @@ -85,6 +102,7 @@ def TestOneInput(data):


def main():
atheris.instrument_all()
atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()

Expand Down
15 changes: 15 additions & 0 deletions fuzzing/fuzz-targets/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import atheris # pragma: no cover
import os # pragma: no cover
from typing import List # pragma: no cover


Expand All @@ -20,3 +21,17 @@ def is_expected_exception_message(exception: Exception, error_message_list: List
if error.lower() in exception_message:
return True
return False


@atheris.instrument_func
def get_max_filename_length(path: str) -> int: # pragma: no cover
"""
Get the maximum filename length for the filesystem containing the given path.
Args:
path (str): The path to check the filesystem for.
Returns:
int: The maximum filename length.
"""
return os.pathconf(path, "PC_NAME_MAX")

0 comments on commit 8502efe

Please sign in to comment.