]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/pack-objects.c: don't leak memory via arguments
authorTaylor Blau <me@ttaylorr.com>
Tue, 26 Oct 2021 21:01:13 +0000 (17:01 -0400)
committerJunio C Hamano <gitster@pobox.com>
Wed, 27 Oct 2021 23:26:37 +0000 (16:26 -0700)
When constructing arguments to pass to setup_revision(), pack-objects
only frees the memory used by that array after calling
get_object_list().

Ensure that we call strvec_clear() whether or not we use the arguments
array by cleaning up whenever we exit the function (and rewriting one
early return to jump to a label which frees the memory and then
returns).

We could avoid setting this array up altogether unless we are in the
if-else block that calls get_object_list(), but setting up the argument
array is intermingled with lots of other side-effects, e.g.:

    if (exclude_promisor_objects) {
      use_internal_rev_list = 1;
      fetch_if_missing = 0;
      strvec_push(&rp, "--exclude-promisor-objects");
    }

So it would be awkward to check exclude_promisor_objects twice: first to
set use_internal_rev_list and fetch_if_missing, and then again above
get_object_list() to push the relevant argument onto the array.

Instead, leave the array's construction alone and make sure to free it
unconditionally.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/pack-objects.c

index 1a3dd445f83f4852f695b1caacab80764fb0ac79..857be7826f3aba2c22c9fbe97e29f786ae8ef3c4 100644 (file)
@@ -4148,11 +4148,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                read_packs_list_from_stdin();
                if (rev_list_unpacked)
                        add_unreachable_loose_objects();
-       } else if (!use_internal_rev_list)
+       } else if (!use_internal_rev_list) {
                read_object_list_from_stdin();
-       else {
+       else {
                get_object_list(rp.nr, rp.v);
-               strvec_clear(&rp);
        }
        cleanup_preferred_base();
        if (include_tag && nr_result)
@@ -4162,7 +4161,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                            the_repository);
 
        if (non_empty && !nr_result)
-               return 0;
+               goto cleanup;
        if (nr_result) {
                trace2_region_enter("pack-objects", "prepare-pack",
                                    the_repository);
@@ -4183,5 +4182,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                             " pack-reused %"PRIu32),
                           written, written_delta, reused, reused_delta,
                           reuse_packfile_objects);
+
+cleanup:
+       strvec_clear(&rp);
+
        return 0;
 }