public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: Git Mailing List <git@vger.kernel.org>,
	Josh Boyer <jwboyer@fedoraproject.org>,
	"Linux-Kernel\@Vger. Kernel. Org" <linux-kernel@vger.kernel.org>,
	twaugh@redhat.com, Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH] apply: refuse touching a file beyond symlink
Date: Fri, 30 Jan 2015 13:10:24 -0800	[thread overview]
Message-ID: <xmqqmw50asan.fsf@gitster.dls.corp.google.com> (raw)
In-Reply-To: <20150130204805.GA10616@peff.net> (Jeff King's message of "Fri, 30 Jan 2015 15:48:05 -0500")

Jeff King <peff@peff.net> writes:

> Ah, OK. Yeah, doing it progressively can only be accurate if our
> name-checks follow the same order as applying, because we are checking
> against a particular state.
>
> But could we instead pull this check to just before the write-out time?
> That is, to let any horrible thing happen in-core, as long as what we
> write out to the index and the filesystem is sane?

That would make me feel dirty.

I noticed one thing.  The PATH_TO_BE_DELETED/PATH_WAS_DELETED crud
kicks in -only- during the actual application phase, and all patches
that remove paths from the end result should have been appropriately
marked in fn_table[] by the call to prepare_fn_table() at the
beginning of check_patch_list() as PATH_TO_BE_DELETED.

But it was wrong to call previous_patch() in my fix.  The function
is the cause of evil I see in the "let's support concatenated patch,
making the later patch depend on the result of earlier ones" and
deliberately ignores PATH_TO_BE_DELETED patches.  We would need to
do the early part of previous_patch() without the filtering.

This is a preparatory step to clean-up the mess I have in mind.  It
does not mean to change the semantics (applied to the codebase with
or without the changes we have been discussing); it only makes it
always return the "previous" patch to the callers and makes them
responsible to see if the previous was to-be-deleted or was-deleted.

With that change, I think my symlink fix plus the "check the deleted
one with old_name, too" change has a better chance to do the moral
equivalent of your two-phase thing.  Essentially, "First see what
will be deleted in the input as a whole" has already been done by
the prepare_fn_table() thing.

 builtin/apply.c | 34 ++++++++++++----------------------
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index 41b7236..a064017 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -3097,25 +3097,12 @@ static int checkout_target(struct cache_entry *ce, struct stat *st)
 	return 0;
 }
 
-static struct patch *previous_patch(struct patch *patch, int *gone)
+static struct patch *previous_patch(struct patch *patch)
 {
-	struct patch *previous;
-
-	*gone = 0;
 	if (patch->is_copy || patch->is_rename)
 		return NULL; /* "git" patches do not depend on the order */
 
-	previous = in_fn_table(patch->old_name);
-	if (!previous)
-		return NULL;
-
-	if (to_be_deleted(previous))
-		return NULL; /* the deletion hasn't happened yet */
-
-	if (was_deleted(previous))
-		*gone = 1;
-
-	return previous;
+	return in_fn_table(patch->old_name);
 }
 
 static int verify_index_match(const struct cache_entry *ce, struct stat *st)
@@ -3170,11 +3157,11 @@ static int load_preimage(struct image *image,
 	struct patch *previous;
 	int status;
 
-	previous = previous_patch(patch, &status);
-	if (status)
+	previous = previous_patch(patch);
+	if (was_deleted(previous))
 		return error(_("path %s has been renamed/deleted"),
 			     patch->old_name);
-	if (previous) {
+	if (previous && !to_be_deleted(previous)) {
 		/* We have a patched copy in memory; use that. */
 		strbuf_add(&buf, previous->result, previous->resultsize);
 	} else {
@@ -3384,18 +3371,18 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
 {
 	const char *old_name = patch->old_name;
 	struct patch *previous = NULL;
-	int stat_ret = 0, status;
+	int stat_ret = 0;
 	unsigned st_mode = 0;
 
 	if (!old_name)
 		return 0;
 
 	assert(patch->is_new <= 0);
-	previous = previous_patch(patch, &status);
+	previous = previous_patch(patch);
 
-	if (status)
+	if (was_deleted(previous))
 		return error(_("path %s has been renamed/deleted"), old_name);
-	if (previous) {
+	if (previous && !to_be_deleted(previous)) {
 		st_mode = previous->new_mode;
 	} else if (!cached) {
 		stat_ret = lstat(old_name, st);
@@ -3403,6 +3390,9 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
 			return error(_("%s: %s"), old_name, strerror(errno));
 	}
 
+	if (to_be_deleted(previous))
+		previous = NULL;
+
 	if (check_index && !previous) {
 		int pos = cache_name_pos(old_name, strlen(old_name));
 		if (pos < 0) {

  reply	other threads:[~2015-01-30 21:10 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-26 16:29 patch-2.7.3 no longer applies relative symbolic link patches Josh Boyer
2015-01-26 16:32 ` Josh Boyer
2015-01-26 20:44   ` Linus Torvalds
2015-01-26 21:01     ` David Kastrup
2015-01-26 21:07     ` Josh Boyer
2015-01-26 21:30       ` Linus Torvalds
2015-01-26 21:35         ` Junio C Hamano
2015-01-26 21:50           ` Linus Torvalds
2015-01-27 15:47             ` Andreas Gruenbacher
2015-01-31 21:27               ` Andreas Gruenbacher
2015-01-26 22:15         ` Josh Boyer
2015-01-27  3:27     ` Junio C Hamano
2015-01-27 20:39       ` Junio C Hamano
2015-01-29  6:05         ` Junio C Hamano
2015-01-29  6:34           ` Junio C Hamano
2015-01-29 20:45             ` [PATCH] apply: refuse touching a file beyond symlink Junio C Hamano
2015-01-29 22:15               ` Stefan Beller
2015-01-29 23:48               ` [PATCH 2/1] apply: reject input that touches outside $cwd Junio C Hamano
2015-01-30 18:24                 ` Jeff King
2015-01-30 19:07                   ` Junio C Hamano
2015-01-30 19:16                     ` Jeff King
2015-01-30  9:04               ` [PATCH] apply: refuse touching a file beyond symlink Christian Couder
2015-01-30 18:11               ` Jeff King
2015-01-30 19:42                 ` Junio C Hamano
2015-01-30 19:46                   ` Jeff King
2015-01-30 19:48                 ` Junio C Hamano
2015-01-30 20:07                   ` Jeff King
2015-01-30 20:32                     ` Junio C Hamano
2015-01-30 20:11                   ` Junio C Hamano
2015-01-30 20:16                     ` Jeff King
2015-01-30 20:20                       ` Junio C Hamano
2015-01-30 20:48                         ` Jeff King
2015-01-30 21:10                           ` Junio C Hamano [this message]
2015-01-30 21:50                           ` Junio C Hamano
2015-01-27 15:26     ` patch-2.7.3 no longer applies relative symbolic link patches Andreas Gruenbacher

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

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

  git send-email \
    --in-reply-to=xmqqmw50asan.fsf@gitster.dls.corp.google.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=jwboyer@fedoraproject.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peff@peff.net \
    --cc=torvalds@linux-foundation.org \
    --cc=twaugh@redhat.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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox