git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "brian m. carlson" <sandals@crustytoothpaste.net>
Cc: git@vger.kernel.org,
	Christian Couder <christian.couder@gmail.com>,
	Bruce Korb <bruce.korb@gmail.com>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH] format-patch: dereference tags with --ignore-if-in-upstream
Date: Mon, 1 Jun 2015 06:20:46 -0400	[thread overview]
Message-ID: <20150601102046.GA31792@peff.net> (raw)
In-Reply-To: <1433120593-186980-1-git-send-email-sandals@crustytoothpaste.net>

On Mon, Jun 01, 2015 at 01:03:13AM +0000, brian m. carlson wrote:

> format-patch would segfault if provided a tag as one of the range
> endpoints in conjunction with --ignore-if-in-upstream, as it assumed the
> object was a commit and attempted to cast it to struct commit.
> Dereference the tag as soon as possible to prevent this, but not until
> after copying the necessary flags.

I bisected Bruce's case earlier to 895c5ba (revision: do not peel tags
used in range notation, 2013-09-19). This is an obvious fallout from
that commit; unlike most traversals which read from rev->commits, we
read straight from rev->pending here. So I wondered briefly if that
commit was not being sufficiently careful.

But as it turns out, this code was buggy long before then. 895c5ba only
changed the range notation. Even before then, if you did:

  git format-patch --ignore-if-in-upstream ^v2.2.0 v2.2.1

we would segfault. Anybody reading from rev->pending should be ready to
handle any kind of object.

Which also makes me wonder about...

> diff --git a/builtin/log.c b/builtin/log.c
> index dd8f3fc..e0465ba 100644
> --- a/builtin/log.c
> +++ b/builtin/log.c
> @@ -807,6 +807,12 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids)
>  	o2 = rev->pending.objects[1].item;
>  	flags2 = o2->flags;
>  
> +	o1 = deref_tag(o1, NULL, 0);
> +	o2 = deref_tag(o2, NULL, 0);
> +
> +	if (!o1 || !o2)
> +		die(_("Invalid tag."));

This will dereference tags, but it won't help at all with:

  git format-patch --ignore-if-in-upstream ^HEAD:Makefile HEAD:Documentation

where we end up with blobs. That is ridiculous, of course, but we should
complain, not segfault.

So I think what you really want is lookup_commit_reference. And the
error message is really not "invalid tag", but "not a commit". I think
you can just use lookup_commit_or_die.

>  	if ((flags1 & UNINTERESTING) == (flags2 & UNINTERESTING))
>  		die(_("Not a range."));

As an aside, now that we are dereferencing, these flags are from the
wrong object. They _should_ be the same (we mark the tag as
UNINTERESTING, too), but it's a little weird that at the end of the
function we restore the saved flags from the tag object onto the commit.
Just bumping the assignment of flags{1,2} would work (or just bump up
the lookup_commit_or_die call to where we assign to o{1,2}).

> +test_expect_success "format-patch --ignore-if-in-upstream handles tags" '
> +
> +	git tag -a v1 -m tag side &&
> +	git format-patch --stdout \
> +		--ignore-if-in-upstream master..v1 >patch1 &&
> +	cnt=$(grep "^From " patch1 | wc -l) &&
> +	test $cnt = 2

I think this avoids the usual "wc" whitespace pitfall because you don't
use double-quotes. But maybe:

  grep "^From " patch1 >count &&
  test_line_count = 2 patch1

would be more idiomatic.

-Peff

  reply	other threads:[~2015-06-01 10:20 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-31 19:13 seg fault in "git format-patch" Bruce Korb
2015-05-31 20:26 ` Christian Couder
2015-05-31 20:41   ` Bruce Korb
2015-05-31 20:45     ` Bruce Korb
2015-05-31 23:14       ` Christian Couder
2015-05-31 23:53         ` Christian Couder
2015-06-01  0:01           ` Christian Couder
2015-06-01  1:03             ` [PATCH] format-patch: dereference tags with --ignore-if-in-upstream brian m. carlson
2015-06-01 10:20               ` Jeff King [this message]
2015-06-01 11:22                 ` brian m. carlson
2015-06-01 11:47                   ` Jeff King
2015-06-01 14:56               ` Junio C Hamano
2015-06-01 17:44                 ` Junio C Hamano
2015-06-01 17:47                   ` Jeff King
2015-06-01 20:35                     ` Junio C Hamano
2015-06-01 22:34                       ` brian m. carlson
2015-06-01 22:46                         ` Junio C Hamano
2015-06-01 17:58                   ` Junio C Hamano
2015-06-01 13:44             ` seg fault in "git format-patch" Christian Couder
2015-06-01 14:17               ` Christian Couder
2015-06-01 14:47           ` Bruce Korb

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=20150601102046.GA31792@peff.net \
    --to=peff@peff.net \
    --cc=bruce.korb@gmail.com \
    --cc=christian.couder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=sandals@crustytoothpaste.net \
    /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;
as well as URLs for NNTP newsgroup(s).