git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Han Young <hanyang.tony@bytedance.com>
Subject: Re: [PATCH 0/1] quote: quote space
Date: Tue, 19 Mar 2024 15:56:44 -0700	[thread overview]
Message-ID: <xmqqfrwlltjn.fsf@gitster.g> (raw)
In-Reply-To: <xmqqttl2qml9.fsf@gitster.g> (Junio C. Hamano's message of "Tue, 19 Mar 2024 08:15:46 -0700")

Junio C Hamano <gitster@pobox.com> writes:

> That is an interesting corner case.  You should make this into a set
> of new tests somewhere in t/; I suspect this only will "break" for
> creation and deletion but not modification in-place or renaming (and
> that should also be in the tests).

It turns out that this is even more unintereseting than I hoped; it
happens ONLY when there is no contents shown at all in the patch,
and the patch is about creation or deletion of a path.  Mode change
without touching any contents may also trigger the same breakage.

Here is a fix, which seems not to break any existing tests.

----- >8 --------- >8 --------- >8 --------- >8 -----
Subject: [PATCH] apply: parse names out of "diff --git" more carefully

"git apply" uses the pathname parsed out of the "diff --git" header
to decide which path is being patched, but this is used only when
there is no other names available in the patch.  When there is any
content change (like we can see in this patch, that modifies the
contents of "apply.c") or rename (which comes with "rename from" and
"rename to" extended diff headers), the names are available without
having to parse this header.

When we do need to parse this header, a special care needs to be
taken, as the name of a directory or a file can have a SP in it so
it is not like "find a space, and take everything before the space
and that is the preimage filename, everything after the space is the
postimage filename".  We have a loop that stops at every SP on the
"diff --git a/dir/file b/dir/foo" line and see if that SP is the
right place that separates such a pair of names.

Unfortunately, this loop can terminate prematurely when a crafted
directory name ended with a SP.  The next pathname component after
that SP (i.e. the beginning of the possible postimage filename) will
be a slash, and instead of rejecting that position as the valid
separation point between pre- and post-image filenames and keep
looping, we stopped processing right there.

The fix is simple.  Instead of stopping and giving up, keep going on
when we see such a condition.

Reported-by: Han Young <hanyang.tony@bytedance.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 apply.c                |  9 ++++++++-
 t/t4126-apply-empty.sh | 22 ++++++++++++++++++++++
 2 files changed, 30 insertions(+), 1 deletion(-)

diff --git c/apply.c w/apply.c
index 432837a674..e311013bc4 100644
--- c/apply.c
+++ w/apply.c
@@ -1292,8 +1292,15 @@ static char *git_header_name(int p_value,
 				return NULL; /* no postimage name */
 			second = skip_tree_prefix(p_value, name + len + 1,
 						  line_len - (len + 1));
+			/*
+			 * If we are at the SP at the end of a directory,
+			 * skip_tree_prefix() may return NULL as that makes
+			 * it appears as if we have an absolute path.
+			 * Keep going to find another SP.
+			 */
 			if (!second)
-				return NULL;
+				continue;
+
 			/*
 			 * Does len bytes starting at "name" and "second"
 			 * (that are separated by one HT or SP we just
diff --git c/t/t4126-apply-empty.sh w/t/t4126-apply-empty.sh
index ece9fae207..eaf0c5304a 100755
--- c/t/t4126-apply-empty.sh
+++ w/t/t4126-apply-empty.sh
@@ -66,4 +66,26 @@ test_expect_success 'apply --index create' '
 	git diff --exit-code
 '
 
+test_expect_success 'apply with no-contents and a funny pathname' '
+	mkdir "funny " &&
+	>"funny /empty" &&
+	git add "funny /empty" &&
+	git diff HEAD "funny /" >sample.patch &&
+	git diff -R HEAD "funny /" >elpmas.patch &&
+	git reset --hard &&
+	rm -fr "funny " &&
+
+	git apply --stat --check --apply sample.patch &&
+	test_must_be_empty "funny /empty" &&
+
+	git apply --stat --check --apply elpmas.patch &&
+	test_path_is_missing "funny /empty" &&
+
+	git apply -R --stat --check --apply elpmas.patch &&
+	test_must_be_empty "funny /empty" &&
+
+	git apply -R --stat --check --apply sample.patch &&
+	test_path_is_missing "funny /empty"
+'
+
 test_done


  reply	other threads:[~2024-03-19 22:57 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-19  9:52 [PATCH 0/1] quote: quote space Han Young
2024-03-19  9:52 ` [PATCH 1/1] " Han Young
2024-03-19  9:59   ` Kristoffer Haugsbakk
2024-03-19 15:15 ` [PATCH 0/1] " Junio C Hamano
2024-03-19 22:56   ` Junio C Hamano [this message]
2024-03-26 21:41     ` Junio C Hamano
2024-03-27  9:17     ` Jeff King
2024-03-27 14:59       ` Junio C Hamano
2024-03-27 22:11     ` Junio C Hamano
2024-03-28 10:32       ` Jeff King
2024-03-28 11:40         ` Jeff King
2024-03-28 17:05           ` Eric Sunshine
2024-03-28 17:31             ` Junio C Hamano
2024-03-28 21:08               ` [PATCH v2] t4126: make sure a directory with SP at the end is usable Junio C Hamano
2024-03-29  2:18                 ` Junio C Hamano
2024-03-29  5:37                   ` [PATCH] t4126: fix "funny directory name" test on Windows (again) Junio C Hamano
2024-03-29 12:00                     ` Jeff King
2024-03-29 17:21                     ` [PATCH v2] " Junio C Hamano
2024-03-29 18:34                       ` Jeff King
2024-03-29 11:27                   ` [PATCH v2] t4126: make sure a directory with SP at the end is usable Jeff King
2024-03-29 17:01                     ` Junio C Hamano
2024-04-27 14:47                       ` Johannes Schindelin
2024-04-27 17:20                         ` Junio C Hamano
2024-03-28 16:19         ` [PATCH 0/1] quote: quote space Junio C Hamano
2024-03-28 16:30           ` Jeff King
2024-03-28 16:53             ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=xmqqfrwlltjn.fsf@gitster.g \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=hanyang.tony@bytedance.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).