diff options
author | Martin Ågren <martin.agren@gmail.com> | 2017-09-09 08:57:16 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-09-10 16:36:58 +0900 |
commit | 851e1fbd01250f56a6e479e1addada220a56e1f7 (patch) | |
tree | c4e44d4a0281378c83cc09983e01c66ede74f88c /refs | |
parent | refs/files-backend: add longer-scoped copy of string to list (diff) | |
download | tgif-851e1fbd01250f56a6e479e1addada220a56e1f7.tar.xz |
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>
Diffstat (limited to 'refs')
-rw-r--r-- | refs/files-backend.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index baceef3b3c..3d63639665 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2756,7 +2756,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, struct strbuf referent = STRBUF_INIT; int mustexist = (update->flags & REF_HAVE_OLD) && !is_null_oid(&update->old_oid); - int ret; + int ret = 0; struct ref_lock *lock; 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, affected_refnames, err); if (ret) - return ret; + goto out; } 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", original_update_refname(update), reason); free(reason); - return ret; + goto out; } 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': " "error reading reference", original_update_refname(update)); - return -1; + ret = -1; + goto out; } } else if (check_old_oid(update, &lock->old_oid, err)) { - return TRANSACTION_GENERIC_ERROR; + ret = TRANSACTION_GENERIC_ERROR; + goto out; } } else { /* @@ -2818,13 +2820,15 @@ static int lock_ref_for_update(struct files_ref_store *refs, referent.buf, transaction, affected_refnames, err); if (ret) - return ret; + goto out; } } else { struct ref_update *parent_update; - if (check_old_oid(update, &lock->old_oid, err)) - return TRANSACTION_GENERIC_ERROR; + if (check_old_oid(update, &lock->old_oid, err)) { + ret = TRANSACTION_GENERIC_ERROR; + goto out; + } /* * 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", update->refname, write_err); free(write_err); - return TRANSACTION_GENERIC_ERROR; + ret = TRANSACTION_GENERIC_ERROR; + goto out; } else { update->flags |= REF_NEEDS_COMMIT; } @@ -2875,10 +2880,14 @@ static int lock_ref_for_update(struct files_ref_store *refs, if (close_ref(lock)) { strbuf_addf(err, "couldn't close '%s.lock'", update->refname); - return TRANSACTION_GENERIC_ERROR; + ret = TRANSACTION_GENERIC_ERROR; + goto out; } } - return 0; + +out: + strbuf_release(&referent); + return ret; } /* |