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>

Martin Ågren committed Sep 9, 2017 at 08:57 UTC 851e1fbd01250f56a6e479e1addada220a56e1f7
1 file changed +20 -11
refs/files-backend.c
+20 -11
@@ -2756,7 +2756,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2756 struct strbuf referent = STRBUF_INIT;
2757 int mustexist = (update->flags & REF_HAVE_OLD) &&
2758 !is_null_oid(&update->old_oid);
2759 - int ret;
2759 + int ret = 0;
2760 struct ref_lock *lock;
2761
2762 files_assert_main_repository(refs, "lock_ref_for_update");
@@ -2768,7 +2768,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2768 ret = split_head_update(update, transaction, head_ref,
2769 affected_refnames, err);
2770 if (ret)
2771 - return ret;
2771 + goto out;
2772 }
2773
2774 ret = lock_raw_ref(refs, update->refname, mustexist,
@@ -2782,7 +2782,7 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2782 strbuf_addf(err, "cannot lock ref '%s': %s",
2783 original_update_refname(update), reason);
2784 free(reason);
2785 - return ret;
2785 + goto out;
2786 }
2787
2788 update->backend_data = lock;
@@ -2801,10 +2801,12 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2801 strbuf_addf(err, "cannot lock ref '%s': "
2802 "error reading reference",
2803 original_update_refname(update));
2804 - return -1;
2804 + ret = -1;
2805 + goto out;
2806 }
2807 } else if (check_old_oid(update, &lock->old_oid, err)) {
2807 - return TRANSACTION_GENERIC_ERROR;
2808 + ret = TRANSACTION_GENERIC_ERROR;
2809 + goto out;
2810 }
2811 } else {
2812 /*
@@ -2818,13 +2820,15 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2820 referent.buf, transaction,
2821 affected_refnames, err);
2822 if (ret)
2821 - return ret;
2823 + goto out;
2824 }
2825 } else {
2826 struct ref_update *parent_update;
2827
2826 - if (check_old_oid(update, &lock->old_oid, err))
2827 - return TRANSACTION_GENERIC_ERROR;
2828 + if (check_old_oid(update, &lock->old_oid, err)) {
2829 + ret = TRANSACTION_GENERIC_ERROR;
2830 + goto out;
2831 + }
2832
2833 /*
2834 * If this update is happening indirectly because of a
@@ -2861,7 +2865,8 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2865 "cannot update ref '%s': %s",
2866 update->refname, write_err);
2867 free(write_err);
2864 - return TRANSACTION_GENERIC_ERROR;
2868 + ret = TRANSACTION_GENERIC_ERROR;
2869 + goto out;
2870 } else {
2871 update->flags |= REF_NEEDS_COMMIT;
2872 }
@@ -2875,10 +2880,14 @@ static int lock_ref_for_update(struct files_ref_store *refs,
2880 if (close_ref(lock)) {
2881 strbuf_addf(err, "couldn't close '%s.lock'",
2882 update->refname);
2878 - return TRANSACTION_GENERIC_ERROR;
2883 + ret = TRANSACTION_GENERIC_ERROR;
2884 + goto out;
2885 }
2886 }
2881 - return 0;
2887 +
2888 +out:
2889 + strbuf_release(&referent);
2890 + return ret;
2891 }
2892
2893 /*