FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

reject control chars in written values in configuration by Byron · Pull Request #2137 · gitpython-developers/GitPython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .py  (2) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
24 changes: 22 additions & 2 deletions git/config.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,24 @@ def _value_to_string(self, value: Union[str, bytes, int, float, bool]) -> str:
return str(value)
return force_text(value)

def _value_to_string_safe(self, value: Union[str, bytes, int, float, bool]) -> str:
value_str = self._value_to_string(value)
if re.search(r"[\r\n\x00]", value_str):
raise ValueError("Git config values must not contain CR, LF, or NUL")
return value_str

@needs_values
@set_dirty_and_flush_changes
def set(
self,
section: str,
option: str,
value: Union[str, bytes, int, float, bool, None] = None,
) -> None:
if value is not None:
value = self._value_to_string_safe(value)
return super().set(section, option, value)

@needs_values
@set_dirty_and_flush_changes
def set_value(self, section: str, option: str, value: Union[str, bytes, int, float, bool]) -> "GitConfigParser":
Expand All @@ -902,9 +920,10 @@ def set_value(self, section: str, option: str, value: Union[str, bytes, int, flo
:return:
This instance
"""
value_str = self._value_to_string_safe(value)
if not self.has_section(section):
self.add_section(section)
self.set(section, option, self._value_to_string(value))
super().set(section, option, value_str)
return self
Comment thread
Byron marked this conversation as resolved.

@needs_values
Expand All @@ -929,9 +948,10 @@ def add_value(self, section: str, option: str, value: Union[str, bytes, int, flo
:return:
This instance
"""
value_str = self._value_to_string_safe(value)
if not self.has_section(section):
self.add_section(section)
self._sections[section].add(option, self._value_to_string(value))
self._sections[section].add(option, value_str)
return self

def rename_section(self, section: str, new_name: str) -> "GitConfigParser":
Expand Down
33 changes: 33 additions & 0 deletions test/test_config.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,39 @@ def test_config_value_with_trailing_new_line(self):
git_config = GitConfigParser(config_file)
git_config.read() # This should not throw an exception

@with_rw_directory
def test_set_value_rejects_config_injection(self, rw_dir):
config_path = osp.join(rw_dir, "config")
payload = "foo\n[core]\nhooksPath=/tmp/hooks"

with GitConfigParser(config_path, read_only=False) as git_config:
with pytest.raises(ValueError, match="CR, LF, or NUL"):
git_config.set_value("user", "name", payload)

with GitConfigParser(config_path, read_only=True) as git_config:
self.assertFalse(git_config.has_section("user"))
self.assertFalse(git_config.has_section("core"))

@with_rw_directory
def test_set_and_add_value_reject_unsafe_value_characters(self, rw_dir):
config_path = osp.join(rw_dir, "config")
bad_values = ("foo\rbar", "foo\nbar", "foo\x00bar", b"foo\nbar")

with GitConfigParser(config_path, read_only=False) as git_config:
git_config.add_section("user")
for bad_value in bad_values:
with pytest.raises(ValueError, match="CR, LF, or NUL"):
git_config.set("user", "name", bad_value)
with pytest.raises(ValueError, match="CR, LF, or NUL"):
git_config.set_value("user", "name", bad_value)
with pytest.raises(ValueError, match="CR, LF, or NUL"):
git_config.add_value("user", "name", bad_value)

git_config.set_value("user", "name", "safe")

with GitConfigParser(config_path, read_only=True) as git_config:
self.assertEqual(git_config.get_value("user", "name"), "safe")

def test_base(self):
path_repo = fixture_path("git_config")
path_global = fixture_path("git_config_global")
Expand Down
Loading

Back | FazBrowse Home | New Git URL