Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork938
Description
Hi, I noticed the fuzzing tests that OSS-Fuzz runs on this project are broken and while I was working on fixing them I believe I came across a minor bug:
The Bug
AnUncaught Python exception:
IndexError: string index out of range
can be triggered if when trying to call.read()
onGitConfigParser
if it was initialized with a malformed config file.
Current Behavior
It's easiest to demonstrate, so please consider this example:
importiofromgit.configimportGitConfigParserdefreproduce_issue():malformed_config_content_bytestring=b'[-]\nk:"v\n"'problematic_config_file=io.BytesIO(malformed_config_content_bytestring)# problematic_config_file looks now like this:""" [-] k:"v " """# We have to name the file otherwise we'll trigger# `AttributeError: '_io.BytesIO' object has no attribute 'name'` here:# https://github.com/gitpython-developers/GitPython/blob/c7675d2cedcd737f20359a4a786e213510452413/git/config.py#L623problematic_config_file.name="fuzzedconfig.config"# This is finegit_config=GitConfigParser(problematic_config_file)# The next line raised an unhandled `IndexError: string index out of range`git_config.read()if__name__=="__main__":reproduce_issue()
Assuming that code is in/path/to/example/config_indexerror_reproduction.py
then
python config_indexerror_reproduction.py
produces something akin to:
Traceback (most recent call last): File"/path/to/example/config_indexerror_reproduction.py", line 30,in<module>reproduce_issue() File"/path/to/example/config_indexerror_reproduction.py", line 26,in reproduce_issuegit_config.read() File"/path/to/example/.venv/lib/python3.12/site-packages/git/config.py", line 607,inread self._read(file_path, file_path.name) File"/path/to/example/.venv/lib/python3.12/site-packages/git/config.py", line 514,in _read cursect.setlast(optname, optval + string_decode(line)) ^^^^^^^^^^^^^^^^^^^ File"/path/to/example/.venv/lib/python3.12/site-packages/git/config.py", line 441,in string_decodeif v[-1] =="\\":~^^^^IndexError: string index out of range
My Reproduction Environment Details
The reproduction code above was tested on:
Python Version: 3.12.1 (main, Feb 5 2024, 16:23:00) [Clang 15.0.0 (clang-1500.1.0.2.5)]OS Information: macOS-14.4.1-x86_64-i386-64bitInstalled Packages:Package Version--------- -------gitdb 4.0.11GitPython 3.1.42pip 24.0smmap 5.0.1
And the fuzzer environment was:
Python Version: 3.8.3 (default, Mar 17 2024, 03:21:27)[Clang 15.0.0 (https://github.com/llvm/llvm-project.git bf7f8d6fa6f460bf0a16ffeOS Information: Linux-6.6.16-linuxkit-x86_64-with-glibc2.2.5Installed Packages:Package Version------------------------- -------altgraph 0.17.4atheris 2.3.0coverage 6.3.2importlib_metadata 7.0.2gitdb 4.0.11GitPython 3.1.42pip 24.0smmap 5.0.1packaging 24.0pyinstaller 5.0.1setuptools 41.0.1six 1.15.0zipp 3.18.1
So, if I'm reading the source correct, it seems like the combination of some header section ([-]
above) followed by a key/value assignment that has a value consisting of a double quoted string with a new line inside it confuses the check here which strips the"
on the new line:
Lines 521 to 528 inc7675d2
else: | |
line=line.rstrip() | |
ifline.endswith('"'): | |
is_multi_line=False | |
line=line[:-1] | |
# END handle quotations | |
optval=cursect.getlast(optname) | |
cursect.setlast(optname,optval+string_decode(line)) |
and passes an empty string tostring_decode
which isn't expecting that when it indexes into it's arg:
Lines 454 to 455 inc7675d2
defstring_decode(v:str)->str: | |
ifv[-1]=="\\": |
Expected Behavior
I'd expect an explicitly raisedParsingError
similar to how it's handled a little further up:
Lines 514 to 518 inc7675d2
else: | |
# Check if it's an option with no value - it's just ignored by git. | |
ifnotself.OPTVALUEONLY.match(line): | |
ifnote: | |
e=cp.ParsingError(fpname) |