fuzz_repo.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import sys
  2. import os
  3. import tempfile
  4. import atheris
  5. with atheris.instrument_imports():
  6. # We instrument `test_utils` as well, so it doesn't block coverage analysis in Fuzz Introspector:
  7. from test_utils import EnhancedFuzzedDataProvider
  8. from dulwich.repo import (
  9. Repo,
  10. InvalidUserIdentity,
  11. )
  12. def TestOneInput(data):
  13. fdp = EnhancedFuzzedDataProvider(data)
  14. with tempfile.TemporaryDirectory() as temp_dir:
  15. repo = Repo.init(temp_dir)
  16. repo.set_description(fdp.ConsumeRandomBytes())
  17. repo.get_description()
  18. # Generate a minimal set of files based on fuzz data to minimize I/O operations.
  19. file_paths = [
  20. os.path.join(temp_dir, f"File{i}")
  21. for i in range(min(3, fdp.ConsumeIntInRange(1, 3)))
  22. ]
  23. for file_path in file_paths:
  24. with open(file_path, "wb") as f:
  25. f.write(fdp.ConsumeRandomBytes())
  26. try:
  27. repo.do_commit(
  28. message=fdp.ConsumeRandomBytes(),
  29. committer=fdp.ConsumeRandomBytes(),
  30. author=fdp.ConsumeRandomBytes(),
  31. commit_timestamp=fdp.ConsumeRandomInt(),
  32. commit_timezone=fdp.ConsumeRandomInt(),
  33. author_timestamp=fdp.ConsumeRandomInt(),
  34. author_timezone=fdp.ConsumeRandomInt(),
  35. )
  36. except InvalidUserIdentity:
  37. return -1
  38. for file_path in file_paths:
  39. with open(file_path, "wb") as f:
  40. f.write(fdp.ConsumeRandomBytes())
  41. repo.stage(file_paths)
  42. repo.do_commit(
  43. message=fdp.ConsumeRandomBytes(),
  44. )
  45. def main():
  46. atheris.Setup(sys.argv, TestOneInput)
  47. atheris.Fuzz()
  48. if __name__ == "__main__":
  49. main()