On Thu, Dec 11, 2014 at 12:47:52AM +0100, Michael Haggerty wrote:
> If "git update-ref --stdin" was given a "verify" command with no
> "<newvalue>" at all (not even zeros), the code was mistakenly setting
> have_old=0 (and leaving old_sha1 uninitialized). But this is
> incorrect: this command is supposed to verify that the reference
> doesn't exist. So in this case we really need old_sha1 to be set to
> null_sha1 and have_old to be set to 1.
> 
> Moreover, since have_old was being set to zero, *no* check of the old
> value was being done, so the new value of the reference was being set
> unconditionally to the value in new_sha1. new_sha1, in turn, was set
> to null_sha1 in the expectation that that was the old value and it
> shouldn't be changed. But because the precondition was not being
> checked, the result was that the reference was being deleted
> unconditionally.
> 
> So, if <oldvalue> is missing, set have_old unconditionally and set
> old_sha1 to null_sha1.
> 
> Signed-off-by: Michael Haggerty <mhag...@alum.mit.edu>

This is reviewed by me as well.
Reviewed-by: Stefan Beller <sbel...@google.com>

> ---
>  builtin/update-ref.c  | 14 +++++---------
>  t/t1400-update-ref.sh |  4 ++--
>  2 files changed, 7 insertions(+), 11 deletions(-)
> 
> diff --git a/builtin/update-ref.c b/builtin/update-ref.c
> index 6c9be05..1993529 100644
> --- a/builtin/update-ref.c
> +++ b/builtin/update-ref.c
> @@ -282,26 +282,22 @@ static const char *parse_cmd_verify(struct 
> ref_transaction *transaction,
>       char *refname;
>       unsigned char new_sha1[20];
>       unsigned char old_sha1[20];
> -     int have_old;
>  
>       refname = parse_refname(input, &next);
>       if (!refname)
>               die("verify: missing <ref>");
>  
>       if (parse_next_sha1(input, &next, old_sha1, "verify", refname,
> -                         PARSE_SHA1_OLD)) {
> -             hashclr(new_sha1);
> -             have_old = 0;
> -     } else {
> -             hashcpy(new_sha1, old_sha1);
> -             have_old = 1;
> -     }
> +                         PARSE_SHA1_OLD))
> +             hashclr(old_sha1);
> +
> +     hashcpy(new_sha1, old_sha1);
>  
>       if (*next != line_termination)
>               die("verify %s: extra input: %s", refname, next);
>  
>       if (ref_transaction_update(transaction, refname, new_sha1, old_sha1,
> -                                update_flags, have_old, msg, &err))
> +                                update_flags, 1, msg, &err))
>               die("%s", err.buf);
>  
>       update_flags = 0;
> diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
> index 6a3cdd1..6805b9e 100755
> --- a/t/t1400-update-ref.sh
> +++ b/t/t1400-update-ref.sh
> @@ -655,7 +655,7 @@ test_expect_success 'stdin verify fails for mistaken null 
> value' '
>       test_cmp expect actual
>  '
>  
> -test_expect_failure 'stdin verify fails for mistaken empty value' '
> +test_expect_success 'stdin verify fails for mistaken empty value' '
>       M=$(git rev-parse $m) &&
>       test_when_finished "git update-ref $m $M" &&
>       git rev-parse $m >expect &&
> @@ -1020,7 +1020,7 @@ test_expect_success 'stdin -z verify fails for mistaken 
> null value' '
>       test_cmp expect actual
>  '
>  
> -test_expect_failure 'stdin -z verify fails for mistaken empty value' '
> +test_expect_success 'stdin -z verify fails for mistaken empty value' '
>       M=$(git rev-parse $m) &&
>       test_when_finished "git update-ref $m $M" &&
>       git rev-parse $m >expect &&
> -- 
> 2.1.3
> 
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to