refs/files-backend: fix memory leak in lock_ref_for_update

After the previous patch, none of the functions we call hold on to
`referent.buf`, so we can safely release the string buffer before
returning.

Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Martin Ågren <martin.agren@gmail.com>
Reviewed-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Martin Ågren 2017-09-09 08:57:16 +02:00 коммит произвёл Junio C Hamano
Родитель c299468bd7
Коммит 851e1fbd01
1 изменённых файлов: 20 добавлений и 11 удалений

Просмотреть файл

@ -2756,7 +2756,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
struct strbuf referent = STRBUF_INIT; struct strbuf referent = STRBUF_INIT;
int mustexist = (update->flags & REF_HAVE_OLD) && int mustexist = (update->flags & REF_HAVE_OLD) &&
!is_null_oid(&update->old_oid); !is_null_oid(&update->old_oid);
int ret; int ret = 0;
struct ref_lock *lock; struct ref_lock *lock;
files_assert_main_repository(refs, "lock_ref_for_update"); files_assert_main_repository(refs, "lock_ref_for_update");
@ -2768,7 +2768,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
ret = split_head_update(update, transaction, head_ref, ret = split_head_update(update, transaction, head_ref,
affected_refnames, err); affected_refnames, err);
if (ret) if (ret)
return ret; goto out;
} }
ret = lock_raw_ref(refs, update->refname, mustexist, ret = lock_raw_ref(refs, update->refname, mustexist,
@ -2782,7 +2782,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
strbuf_addf(err, "cannot lock ref '%s': %s", strbuf_addf(err, "cannot lock ref '%s': %s",
original_update_refname(update), reason); original_update_refname(update), reason);
free(reason); free(reason);
return ret; goto out;
} }
update->backend_data = lock; update->backend_data = lock;
@ -2801,10 +2801,12 @@ static int lock_ref_for_update(struct files_ref_store *refs,
strbuf_addf(err, "cannot lock ref '%s': " strbuf_addf(err, "cannot lock ref '%s': "
"error reading reference", "error reading reference",
original_update_refname(update)); original_update_refname(update));
return -1; ret = -1;
goto out;
} }
} else if (check_old_oid(update, &lock->old_oid, err)) { } else if (check_old_oid(update, &lock->old_oid, err)) {
return TRANSACTION_GENERIC_ERROR; ret = TRANSACTION_GENERIC_ERROR;
goto out;
} }
} else { } else {
/* /*
@ -2818,13 +2820,15 @@ static int lock_ref_for_update(struct files_ref_store *refs,
referent.buf, transaction, referent.buf, transaction,
affected_refnames, err); affected_refnames, err);
if (ret) if (ret)
return ret; goto out;
} }
} else { } else {
struct ref_update *parent_update; struct ref_update *parent_update;
if (check_old_oid(update, &lock->old_oid, err)) if (check_old_oid(update, &lock->old_oid, err)) {
return TRANSACTION_GENERIC_ERROR; ret = TRANSACTION_GENERIC_ERROR;
goto out;
}
/* /*
* If this update is happening indirectly because of a * If this update is happening indirectly because of a
@ -2861,7 +2865,8 @@ static int lock_ref_for_update(struct files_ref_store *refs,
"cannot update ref '%s': %s", "cannot update ref '%s': %s",
update->refname, write_err); update->refname, write_err);
free(write_err); free(write_err);
return TRANSACTION_GENERIC_ERROR; ret = TRANSACTION_GENERIC_ERROR;
goto out;
} else { } else {
update->flags |= REF_NEEDS_COMMIT; update->flags |= REF_NEEDS_COMMIT;
} }
@ -2875,10 +2880,14 @@ static int lock_ref_for_update(struct files_ref_store *refs,
if (close_ref(lock)) { if (close_ref(lock)) {
strbuf_addf(err, "couldn't close '%s.lock'", strbuf_addf(err, "couldn't close '%s.lock'",
update->refname); update->refname);
return TRANSACTION_GENERIC_ERROR; ret = TRANSACTION_GENERIC_ERROR;
goto out;
} }
} }
return 0;
out:
strbuf_release(&referent);
return ret;
} }
/* /*