From 09f2cf383a992d1af697364569e9f384748c1bd8 Mon Sep 17 00:00:00 2001
From: Byron <sebastian.thiel@icloud.com>
Date: Mon, 17 Aug 2026 06:15:12 +0200
Subject: [PATCH] fix: require opt-in for no-index diffs

<!-- agent -->
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.

Assisted-by: GPT 5.6
Co-authored-by: GPT 5.6 <codex@openai.com>
---
 doc/source/changes.rst |  1 +
 git/diff.py            |  4 ++--
 git/repo/base.py       |  2 ++
 test/test_diff.py      | 11 +++++++++++
 4 files changed, 16 insertions(+), 2 deletions(-)

Index: GitPython-3.1.59/git/diff.py
===================================================================
--- GitPython-3.1.59.orig/git/diff.py
+++ GitPython-3.1.59/git/diff.py
@@ -220,8 +220,8 @@ class Diffable:
             to be read and diffed.
 
         :param allow_unsafe_options:
-            If ``True``, allow options such as ``--output`` and ``-O`` that can write to
-            or read from arbitrary filesystem paths.
+            If ``True``, allow options such as ``--output``, ``--no-index``, and ``-O``
+            that can write to or read from arbitrary filesystem paths.
 
         :param kwargs:
             Additional arguments passed to :manpage:`git-diff(1)`, such as ``R=True`` to
Index: GitPython-3.1.59/git/repo/base.py
===================================================================
--- GitPython-3.1.59.orig/git/repo/base.py
+++ GitPython-3.1.59/git/repo/base.py
@@ -208,6 +208,8 @@ class Repo:
     ]
 
     unsafe_git_diff_options = unsafe_git_revision_options + [
+        # Treats path operands as arbitrary filesystem paths.
+        "--no-index",
         # Reads caller-controlled order patterns from an arbitrary file.
         "-O",
         "--orderfile",
Index: GitPython-3.1.59/test/test_diff.py
===================================================================
--- GitPython-3.1.59.orig/test/test_diff.py
+++ GitPython-3.1.59/test/test_diff.py
@@ -406,6 +406,17 @@ class TestDiff(TestBase):
         commit.diff(output=allowed_target, allow_unsafe_options=True)
         self.assertTrue(osp.isfile(allowed_target))
 
+    def test_diff_rejects_no_index(self):
+        calls = (
+            lambda: self.rorepo.head.commit.diff(no_index=True),
+            lambda: self.rorepo.head.commit.diff(other="--no-index"),
+            lambda: self.rorepo.index.diff(None, no_index=True),
+            lambda: self.rorepo.index.diff("--no-index"),
+        )
+        for call in calls:
+            with self.assertRaises(UnsafeOptionError):
+                call()
+
     def test_diff_interface(self):
         """Test a few variations of the main diff routine."""
         assertion_map = {}
