apply: parse names out of "diff --git" more carefully
commit5ea0176003f4a5f4a2bffbe87b6ba2365bf1c254
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Mar 2024 22:56:44 +0000 (19 15:56 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Mar 2024 22:58:15 +0000 (19 15:58 -0700)
treecd792171b75d058d87c73684d0f56291aa9904ab
parent0d1bd1dfb37ef25e1911777c94129fc769ffec38
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
t/t4126-apply-empty.sh