Skip to content

Commit 6c00ce6

Browse files
committed
Improve file name generation to prevent "File name too long" OSError's
Adds a utility function to limit the maximum file name legnth produced by the fuzzer to a max size dictated by the host its run on.
1 parent 7b684cd commit 6c00ce6

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

fuzzing/fuzz-targets/fuzz_submodule.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import tempfile
55
from configparser import ParsingError
6-
from utils import is_expected_exception_message
6+
from utils import is_expected_exception_message, get_max_filename_length
77

88
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
99
path_to_bundled_git_binary = os.path.abspath(os.path.join(os.path.dirname(__file__), "git"))
@@ -42,12 +42,12 @@ def TestOneInput(data):
4242
writer.release()
4343

4444
submodule.update(init=fdp.ConsumeBool(), dry_run=fdp.ConsumeBool(), force=fdp.ConsumeBool())
45-
4645
submodule_repo = submodule.module()
47-
new_file_path = os.path.join(
48-
submodule_repo.working_tree_dir,
49-
f"new_file_{fdp.ConsumeUnicodeNoSurrogates(fdp.ConsumeIntInRange(1, 512))}",
46+
47+
new_file_name = fdp.ConsumeUnicodeNoSurrogates(
48+
fdp.ConsumeIntInRange(1, max(1, get_max_filename_length(submodule_repo.working_tree_dir)))
5049
)
50+
new_file_path = os.path.join(submodule_repo.working_tree_dir, new_file_name)
5151
with open(new_file_path, "wb") as new_file:
5252
new_file.write(fdp.ConsumeBytes(fdp.ConsumeIntInRange(1, 512)))
5353
submodule_repo.index.add([new_file_path])
@@ -77,14 +77,13 @@ def TestOneInput(data):
7777
BrokenPipeError,
7878
):
7979
return -1
80-
except (ValueError, OSError) as e:
80+
except ValueError as e:
8181
expected_messages = [
8282
"SHA is empty",
8383
"Reference at",
8484
"embedded null byte",
8585
"This submodule instance does not exist anymore",
8686
"cmd stdin was empty",
87-
"File name too long",
8887
]
8988
if is_expected_exception_message(e, expected_messages):
9089
return -1

fuzzing/fuzz-targets/utils.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import atheris # pragma: no cover
2+
import os
23
from typing import List # pragma: no cover
34

45

@@ -20,3 +21,17 @@ def is_expected_exception_message(exception: Exception, error_message_list: List
2021
if error.lower() in exception_message:
2122
return True
2223
return False
24+
25+
26+
@atheris.instrument_func
27+
def get_max_filename_length(path: str) -> int:
28+
"""
29+
Get the maximum filename length for the filesystem containing the given path.
30+
31+
Args:
32+
path (str): The path to check the filesystem for.
33+
34+
Returns:
35+
int: The maximum filename length.
36+
"""
37+
return os.pathconf(path, "PC_NAME_MAX")

0 commit comments

Comments
 (0)