send-pack: free cas options before exit

The send-pack --force-with-lease option populates a push_cas_option struct with allocated strings. Exiting without cleaning this up will cause leak-checkers to complain. We can fix this by calling clear_cas_option(), after making it publicly available. Previously it was used only for resetting the list when we saw --no-force-with-lease. The git-push command has the same "leak", though in this case it won't trigger a leak-checker since it stores the push_cas_option struct as a global rather than on the stack (and is thus reachable even after main() exits). I've added cleanup for it here anyway, though, as future-proofing. The leak is triggered by t5541 (it tests --force-with-lease over http, which requires a separate send-pack process under the hood), but we can't mark it as leak-free yet. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 24, 2024 at 17:55 UTC 05372c28bedbd2ae067e695805590b7eea947e10
4 files changed +4 -1
builtin/push.c
+1
@@ -669,6 +669,7 @@ int cmd_push(int argc,
669 rc = do_push(flags, push_options, remote);
670 string_list_clear(&push_options_cmdline, 0);
671 string_list_clear(&push_options_config, 0);
672 + clear_cas_option(&cas);
673 if (rc == -1)
674 usage_with_options(push_usage, options);
675 else
builtin/send-pack.c
+1
@@ -344,5 +344,6 @@ int cmd_send_pack(int argc,
344 free_refs(local_refs);
345 refspec_clear(&rs);
346 oid_array_clear(&shallow);
347 + clear_cas_option(&cas);
348 return ret;
349 }
remote.c
+1 -1
@@ -2544,7 +2544,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map)
2544 /*
2545 * Compare-and-swap
2546 */
2547 -static void clear_cas_option(struct push_cas_option *cas)
2547 +void clear_cas_option(struct push_cas_option *cas)
2548 {
2549 int i;
2550
remote.h
+1
@@ -409,6 +409,7 @@ struct push_cas_option {
409 };
410
411 int parseopt_push_cas_option(const struct option *, const char *arg, int unset);
412 +void clear_cas_option(struct push_cas_option *);
413
414 int is_empty_cas(const struct push_cas_option *);
415 void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);