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
/*