]> git.ipfire.org Git - thirdparty/git.git/commitdiff
builtin/format-patch: fix various trivial memory leaks
authorPatrick Steinhardt <ps@pks.im>
Wed, 14 Aug 2024 06:52:44 +0000 (08:52 +0200)
committerJunio C Hamano <gitster@pobox.com>
Wed, 14 Aug 2024 17:08:01 +0000 (10:08 -0700)
There are various memory leaks hit by git-format-patch(1). Basically all
of them are trivial, except that un-setting `diffopt.no_free` requires
us to unset the `diffopt.file` because we manually close it already.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/log.c
t/t4014-format-patch.sh

index a73a76760658fe8870cf14c540c229c748b81077..f5cb00c64301e0d5110ffbe6c78189ce33b0d53d 100644 (file)
@@ -1827,12 +1827,14 @@ static struct commit *get_base_commit(const struct format_config *cfg,
                                if (die_on_failure) {
                                        die(_("failed to find exact merge base"));
                                } else {
+                                       free_commit_list(merge_base);
                                        free(rev);
                                        return NULL;
                                }
                        }
 
                        rev[i] = merge_base->item;
+                       free_commit_list(merge_base);
                }
 
                if (rev_nr % 2)
@@ -2023,6 +2025,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
        const char *rfc = NULL;
        int creation_factor = -1;
        const char *signature = git_version_string;
+       char *signature_to_free = NULL;
        char *signature_file_arg = NULL;
        struct keep_callback_data keep_callback_data = {
                .cfg = &cfg,
@@ -2443,7 +2446,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 
                if (strbuf_read_file(&buf, signature_file, 128) < 0)
                        die_errno(_("unable to read signature file '%s'"), signature_file);
-               signature = strbuf_detach(&buf, NULL);
+               signature = signature_to_free = strbuf_detach(&buf, NULL);
        } else if (cfg.signature) {
                signature = cfg.signature;
        }
@@ -2548,12 +2551,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                        else
                                print_signature(signature, rev.diffopt.file);
                }
-               if (output_directory)
+               if (output_directory) {
                        fclose(rev.diffopt.file);
+                       rev.diffopt.file = NULL;
+               }
        }
        stop_progress(&progress);
        free(list);
-       free(branch_name);
        if (ignore_if_in_upstream)
                free_patch_ids(&ids);
 
@@ -2565,11 +2569,14 @@ done:
        strbuf_release(&rdiff_title);
        free(description_file);
        free(signature_file_arg);
+       free(signature_to_free);
+       free(branch_name);
        free(to_free);
        free(rev.message_id);
        if (rev.ref_message_ids)
                string_list_clear(rev.ref_message_ids, 0);
        free(rev.ref_message_ids);
+       rev.diffopt.no_free = 0;
        release_revisions(&rev);
        format_config_release(&cfg);
        return 0;
index 884f83fb8a45fe927f6763342a3e1b8a8a04c624..1c46e963e4326b281e7e5912d70d04c564774dde 100755 (executable)
@@ -8,6 +8,7 @@ test_description='various format-patch tests'
 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-terminal.sh