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
An Uncaught Python exception:
IndexError: string index out of range
can be triggered if when trying to call .read()
on GitConfigParser
if it was initialized with a malformed config file.
Current Behavior
It's easiest to demonstrate, so please consider this example:
import io
from git.config import GitConfigParser
def reproduce_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#L623
problematic_config_file.name = "fuzzedconfig.config"
# This is fine
git_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_issue
git_config.read()
File "/path/to/example/.venv/lib/python3.12/site-packages/git/config.py", line 607, in read
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_decode
if 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-64bit
Installed Packages:
Package Version
--------- -------
gitdb 4.0.11
GitPython 3.1.42
pip 24.0
smmap 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 bf7f8d6fa6f460bf0a16ffe
OS Information: Linux-6.6.16-linuxkit-x86_64-with-glibc2.2.5
Installed Packages:
Package Version
------------------------- -------
altgraph 0.17.4
atheris 2.3.0
coverage 6.3.2
importlib_metadata 7.0.2
gitdb 4.0.11
GitPython 3.1.42
pip 24.0
smmap 5.0.1
packaging 24.0
pyinstaller 5.0.1
setuptools 41.0.1
six 1.15.0
zipp 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 in c7675d2
and passes an empty string to string_decode
which isn't expecting that when it indexes into it's arg:
Lines 454 to 455 in c7675d2
Expected Behavior
I'd expect an explicitly raised ParsingError
similar to how it's handled a little further up:
Lines 514 to 518 in c7675d2