git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 2/3] Clean up builtin-update-ref's option parsing

From
Junio C Hamano <gitster@pobox.com>
Date
May 25, 2008, 18:40 UTC
Message-ID
<7vk5hii5wn.fsf@gitster.siamese.dyndns.org>
In-Reply-To
<20080525161435.25087.82683.stgit@yoghurt>
Karl Hasselström <kha@treskal.com> writes:
Show 6 quoted lines
> builtin-update-ref's option parsing was somewhat tricky to follow,
> especially if the -d option was given. This patch cleans it upp a bit
> (including fixing an out-of-bounds argv access), at the expense of
> making it a bit longer.
>
> Signed-off-by: Karl Hasselström <kha@treskal.com>

Longer is fine but I am afraid that this patch is not much easier to follow than the original, does not fix anything, and introduces a new bug.

Show 31 quoted lines
> diff --git a/builtin-update-ref.c b/builtin-update-ref.c
> index e90737c..0d3eb8e 100644
> --- a/builtin-update-ref.c
> +++ b/builtin-update-ref.c
> @@ -27,25 +27,29 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix)
>  	if (msg && !*msg)
>  		die("Refusing to perform update with empty message.");
>  
> -	if (argc < 2 || argc > 3)
> -		usage_with_options(git_update_ref_usage, options);
> -	refname = argv[0];
> -	value   = argv[1];
> -	oldval  = argv[2];
> -
> -	if (get_sha1(value, sha1))
> -		die("%s: not a valid SHA1", value);
> -
>  	if (delete) {
> -		if (oldval)
> +		if (argc != 2)
>  			usage_with_options(git_update_ref_usage, options);
> -		return delete_ref(refname, sha1);
> +		refname = argv[0];
> +		value = NULL;
> +		oldval = argv[1];
> +	} else {
> +		if (argc < 2 || argc > 3)
> +			usage_with_options(git_update_ref_usage, options);
> +		refname = argv[0];
> +		value = argv[1];
> +		oldval = argc > 2 ? argv[2] : NULL;

When (argc == 3), argv[2] has the old value string given on the command line. When (argc == 2), argv[2] has the terminating NULL pointer. So either case you can safely use argv[2]. You do not allow other cases upfront, so I do not understand why you need this conditional expression?

IOW, I do not see "an out-of-bounds argv access" in the original, and you are making this assignment harder to follow.

>  	}
>  
> +	if (value && *value && get_sha1(value, sha1))
> +		die("%s: not a valid SHA1", value);
Dropping *value in the sequence may fix it but I think this is wrong.

We used to barf if you said "git update-ref refs/heads/master '' master" because it would be nonsense to give an empty string as the new value of the ref, didn't we? Doesn't this change break it? Does your set of additional tests in [1/3] catch it?

Show 12 quoted lines
>  	hashclr(oldsha1);
>  	if (oldval && *oldval && get_sha1(oldval, oldsha1))
>  		die("%s: not a valid old SHA1", oldval);
>  
> -	return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
> -			  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);
> +	if (delete)
> +		return delete_ref(refname, oldsha1);
> +	else
> +		return update_ref(msg, refname, sha1, oldval ? oldsha1 : NULL,
> +				  no_deref ? REF_NODEREF : 0, DIE_ON_ERR);
>  }
Previous: Karl HasselströmNext: Karl Hasselström
Message 4 of 8 in “Make old sha1 optional with git update-ref -d”
  1. 0/3 Make old sha1 optional with git update-ref -dKarl Hasselström, May 25, 2008
  2. 1/3 Add some tests for git update-ref -dKarl Hasselström, May 25, 2008
  3. 2/3 Clean up builtin-update-ref's option parsingKarl Hasselström, May 25, 2008
  4. Junio C HamanoMay 25, 2008
  5. Karl HasselströmMay 25, 2008
  6. 3/3 Make old sha1 optional with git update-ref -dKarl Hasselström, May 25, 2008
  7. Johannes SchindelinMay 26, 2008
  8. Karl HasselströmMay 26, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.