Skip to content

Commit 1420058

Browse files
codexByron
authored andcommitted
fix: require opt-in for no-index diffs
Treat --no-index as an unsafe diff option because it changes path operands from repository pathspecs to arbitrary filesystem paths. This addresses GHSA-whh4-5q6c-9v3x without exposing advisory reproduction details. Add regression coverage for keyword and raw-option spellings through commit and index diff paths. Git baseline: Git 2.50.1 documents --no-index as comparing two filesystem paths in Documentation/git-diff.adoc, implemented by builtin/diff.c. Validation: focused diff security tests; ruff check and format; git diff --check. The full test/test_diff.py run passed 25/26, with the unrelated staged-conflict test returning 0 entries instead of 2 in this local environment.
1 parent f44c1fb commit 1420058

3 files changed

Lines changed: 15 additions & 2 deletions

File tree

git/diff.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,8 @@ def diff(
239239
to be read and diffed.
240240
241241
:param allow_unsafe_options:
242-
If ``True``, allow options such as ``--output`` and ``-O`` that can write to
243-
or read from arbitrary filesystem paths.
242+
If ``True``, allow options such as ``--output``, ``--no-index``, and ``-O``
243+
that can write to or read from arbitrary filesystem paths.
244244
245245
:param kwargs:
246246
Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to

git/repo/base.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ class Repo:
209209
]
210210

211211
unsafe_git_diff_options = unsafe_git_revision_options + [
212+
# Treats pathspecs as arbitrary filesystem paths.
213+
"--no-index",
212214
# Reads caller-controlled order patterns from an arbitrary file.
213215
"-O",
214216
"--orderfile",

test/test_diff.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,17 @@ def test_diff_rejects_unsafe_output_options(self):
412412
commit.diff(output=allowed_target, allow_unsafe_options=True)
413413
self.assertTrue(osp.isfile(allowed_target))
414414

415+
def test_diff_rejects_no_index(self):
416+
calls = (
417+
lambda: self.rorepo.head.commit.diff(no_index=True),
418+
lambda: self.rorepo.head.commit.diff(other="--no-index"),
419+
lambda: self.rorepo.index.diff(None, no_index=True),
420+
lambda: self.rorepo.index.diff("--no-index"),
421+
)
422+
for call in calls:
423+
with self.assertRaises(UnsafeOptionError):
424+
call()
425+
415426
def test_diff_interface(self):
416427
"""Test a few variations of the main diff routine."""
417428
assertion_map = {}

0 commit comments

Comments
 (0)