Skip to content

Commit f6174e7

Browse files
committed
Fix IndexError in GitConfigParser when config value ends in new line
Improve the guarding `if` check in `GitConfigParser`'s `string_decode` function to safely handle empty strings and prevent `IndexError`s when accessing string elements. This resolves an IndexError in the `GitConfigParser`'s `.read()` method when the config file contains a quoted value containing a trailing new line. Fixes: #1887
1 parent bc7bd22 commit f6174e7

File tree

3 files changed

+10
-6
lines changed

3 files changed

+10
-6
lines changed

fuzzing/fuzz-targets/fuzz_config.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,7 @@ def TestOneInput(data):
3535
except (MissingSectionHeaderError, ParsingError, UnicodeDecodeError):
3636
return -1 # Reject inputs raising expected exceptions
3737
except (IndexError, ValueError) as e:
38-
if isinstance(e, IndexError) and "string index out of range" in str(e):
39-
# Known possibility that might be patched
40-
# See: https://github.com/gitpython-developers/GitPython/issues/1887
41-
pass
42-
elif isinstance(e, ValueError) and "embedded null byte" in str(e):
38+
if isinstance(e, ValueError) and "embedded null byte" in str(e):
4339
# The `os.path.expanduser` function, which does not accept strings
4440
# containing null bytes might raise this.
4541
return -1

git/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def _read(self, fp: Union[BufferedReader, IO[bytes]], fpname: str) -> None:
452452
e = None # None, or an exception.
453453

454454
def string_decode(v: str) -> str:
455-
if v[-1] == "\\":
455+
if v and v[-1] == "\\":
456456
v = v[:-1]
457457
# END cut trailing escapes to prevent decode error
458458

test/test_config.py

+8
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ def test_multi_line_config(self):
142142
)
143143
self.assertEqual(len(config.sections()), 23)
144144

145+
def test_config_value_with_trailing_new_line(self):
146+
config_content = b'[section-header]\nkey:"value\n"'
147+
config_file = io.BytesIO(config_content)
148+
config_file.name = "multiline_value.config"
149+
150+
git_config = GitConfigParser(config_file)
151+
git_config.read() # This should not throw an exception
152+
145153
def test_base(self):
146154
path_repo = fixture_path("git_config")
147155
path_global = fixture_path("git_config_global")

0 commit comments

Comments
 (0)