Skip to content

Commit 4e212c6

Browse files
authored
Merge pull request #1914 from DaveLak/add-diff-fuzz-target
Add `Diff` Fuzz Target
2 parents a5815b6 + 989ae1a commit 4e212c6

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

Diff for: fuzzing/fuzz-targets/fuzz_diff.py

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import sys
2+
import os
3+
import io
4+
import tempfile
5+
from binascii import Error as BinasciiError
6+
7+
import atheris
8+
9+
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
10+
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
11+
os.environ["GIT_PYTHON_GIT_EXECUTABLE"] = path_to_bundled_git_binary
12+
13+
with atheris.instrument_imports():
14+
from git import Repo, Diff
15+
16+
17+
class BytesProcessAdapter:
18+
"""Allows bytes to be used as process objects returned by subprocess.Popen."""
19+
20+
def __init__(self, input_string):
21+
self.stdout = io.BytesIO(input_string)
22+
self.stderr = io.BytesIO()
23+
24+
def wait(self):
25+
return 0
26+
27+
poll = wait
28+
29+
30+
def TestOneInput(data):
31+
fdp = atheris.FuzzedDataProvider(data)
32+
33+
with tempfile.TemporaryDirectory() as temp_dir:
34+
repo = Repo.init(path=temp_dir)
35+
try:
36+
diff = Diff(
37+
repo,
38+
a_rawpath=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
39+
b_rawpath=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
40+
a_blob_id=fdp.ConsumeBytes(20),
41+
b_blob_id=fdp.ConsumeBytes(20),
42+
a_mode=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
43+
b_mode=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
44+
new_file=fdp.ConsumeBool(),
45+
deleted_file=fdp.ConsumeBool(),
46+
copied_file=fdp.ConsumeBool(),
47+
raw_rename_from=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
48+
raw_rename_to=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
49+
diff=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())),
50+
change_type=fdp.PickValueInList(["A", "D", "C", "M", "R", "T", "U"]),
51+
score=fdp.ConsumeIntInRange(0, fdp.remaining_bytes()),
52+
)
53+
except BinasciiError:
54+
return -1
55+
except AssertionError as e:
56+
if "Require 20 byte binary sha, got" in str(e):
57+
return -1
58+
else:
59+
raise e
60+
61+
_ = diff.__str__()
62+
_ = diff.a_path
63+
_ = diff.b_path
64+
_ = diff.rename_from
65+
_ = diff.rename_to
66+
_ = diff.renamed_file
67+
68+
diff_index = diff._index_from_patch_format(
69+
repo, proc=BytesProcessAdapter(fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())))
70+
)
71+
72+
diff._handle_diff_line(
73+
lines_bytes=fdp.ConsumeBytes(fdp.ConsumeIntInRange(0, fdp.remaining_bytes())), repo=repo, index=diff_index
74+
)
75+
76+
77+
def main():
78+
atheris.Setup(sys.argv, TestOneInput)
79+
atheris.Fuzz()
80+
81+
82+
if __name__ == "__main__":
83+
main()

0 commit comments

Comments
 (0)