summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylor Blau <me@ttaylorr.com>2025-05-28 12:55:15 -0400
committerTaylor Blau <me@ttaylorr.com>2025-05-28 12:55:15 -0400
commit2d22f0cd07c308d7ff25bbf4ec8f1bb53b4bcda7 (patch)
tree2f0075729780e39a72abf7da71d18fa9082e3e34
parentd2bc61fcabd6cfa582d286bed1ce20d5d7c58d52 (diff)
parent05e9cd64ee23bbadcea6bcffd6660ed02b8eab89 (diff)
Merge branch 'jt/config-quote-cr' into maint-2.43
This merges in the fix for CVE-2025-48384. * jt/config-quote-cr: config: quote values containing CR character Signed-off-by: Taylor Blau <me@ttaylorr.com>
-rw-r--r--config.c2
-rwxr-xr-xt/t1300-config.sh11
-rwxr-xr-xt/t7450-bad-git-dotfiles.sh33
3 files changed, 45 insertions, 1 deletions
diff --git a/config.c b/config.c
index 9ff6ae1cb9..629981451d 100644
--- a/config.c
+++ b/config.c
@@ -2999,7 +2999,7 @@ static ssize_t write_pair(int fd, const char *key, const char *value,
if (value[0] == ' ')
quote = "\"";
for (i = 0; value[i]; i++)
- if (value[i] == ';' || value[i] == '#')
+ if (value[i] == ';' || value[i] == '#' || value[i] == '\r')
quote = "\"";
if (i && value[i - 1] == ' ')
quote = "\"";
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index f4e2752134..1010410b7e 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -2590,4 +2590,15 @@ test_expect_success 'includeIf.hasconfig:remote.*.url forbids remote url in such
grep "fatal: remote URLs cannot be configured in file directly or indirectly included by includeIf.hasconfig:remote.*.url" err
'
+test_expect_success 'writing value with trailing CR not stripped on read' '
+ test_when_finished "rm -rf cr-test" &&
+
+ printf "bar\r\n" >expect &&
+ git init cr-test &&
+ git -C cr-test config set core.foo $(printf "bar\r") &&
+ git -C cr-test config get core.foo >actual &&
+
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh
index 5b845e899b..2026285566 100755
--- a/t/t7450-bad-git-dotfiles.sh
+++ b/t/t7450-bad-git-dotfiles.sh
@@ -347,4 +347,37 @@ test_expect_success 'checkout -f --recurse-submodules must not use a nested gitd
test_path_is_missing nested_checkout/thing2/.git
'
+test_expect_success SYMLINKS,!WINDOWS,!MINGW 'submodule must not checkout into different directory' '
+ test_when_finished "rm -rf sub repo bad-clone" &&
+
+ git init sub &&
+ write_script sub/post-checkout <<-\EOF &&
+ touch "$PWD/foo"
+ EOF
+ git -C sub add post-checkout &&
+ git -C sub commit -m hook &&
+
+ git init repo &&
+ git -C repo -c protocol.file.allow=always submodule add "$PWD/sub" sub &&
+ git -C repo mv sub $(printf "sub\r") &&
+
+ # Ensure config values containing CR are wrapped in quotes.
+ git config unset -f repo/.gitmodules submodule.sub.path &&
+ printf "\tpath = \"sub\r\"\n" >>repo/.gitmodules &&
+
+ git config unset -f repo/.git/modules/sub/config core.worktree &&
+ {
+ printf "[core]\n" &&
+ printf "\tworktree = \"../../../sub\r\"\n"
+ } >>repo/.git/modules/sub/config &&
+
+ ln -s .git/modules/sub/hooks repo/sub &&
+ git -C repo add -A &&
+ git -C repo commit -m submodule &&
+
+ git -c protocol.file.allow=always clone --recurse-submodules repo bad-clone &&
+ ! test -f "$PWD/foo" &&
+ test -f $(printf "bad-clone/sub\r/post-checkout")
+'
+
test_done