diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 957786d1b3..0b162f8fab 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -67,6 +67,8 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix) return ret; write_in_full(STDOUT_FILENO, output.buf, output.len); + strbuf_release(&input); + strbuf_release(&output); free(inpath); return 0; } diff --git a/builtin/grep.c b/builtin/grep.c index dfc3c3e8bd..dda4582d64 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -1133,6 +1133,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) &oid, &oc)) { if (seen_dashdash) die(_("unable to resolve revision: %s"), arg); + object_context_release(&oc); break; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index c6e2852d3c..01479a9ccc 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -4669,6 +4669,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) cleanup: clear_packing_data(&to_pack); list_objects_filter_release(&filter_options); + string_list_clear(&keep_pack_list, 0); strvec_clear(&rp); return 0; diff --git a/builtin/push.c b/builtin/push.c index 7a67398124..0b123eb9c1 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -72,13 +72,15 @@ static void refspec_append_mapped(struct refspec *refspec, const char *ref, const char *branch_name; if (remote->push.nr) { - struct refspec_item query; - memset(&query, 0, sizeof(struct refspec_item)); - query.src = matched->name; + struct refspec_item query = { + .src = matched->name, + }; + if (!query_refspecs(&remote->push, &query) && query.dst) { refspec_appendf(refspec, "%s%s:%s", query.force ? "+" : "", query.src, query.dst); + free(query.dst); return; } } diff --git a/builtin/repack.c b/builtin/repack.c index 8bb875532b..3ee8cfa732 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -425,9 +425,11 @@ static void repack_promisor_objects(const struct pack_objects_args *args, free(promisor_name); } + fclose(out); if (finish_command(&cmd)) die(_("could not finish pack-objects to repack promisor objects")); + strbuf_release(&line); } struct pack_geometry { @@ -1541,6 +1543,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) } cleanup: + string_list_clear(&keep_pack_list, 0); string_list_clear(&names, 1); existing_packs_release(&existing); free_pack_geometry(&geometry); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 3e0b6c45c0..e5ba05ab8c 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2958,7 +2958,9 @@ static int push_check(int argc, const char **argv, const char *prefix UNUSED) rs->src); } } + refspec_clear(&refspec); + free_refs(local_refs); } free(head); diff --git a/builtin/tag.c b/builtin/tag.c index 607e48e311..59829aa26d 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -160,7 +160,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid, const struct git_hash_algo *compat = the_repository->compat_hash_algo; struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT; struct strbuf compat_buf = STRBUF_INIT; - const char *keyid = get_signing_key(); + char *keyid = get_signing_key(); int ret = -1; if (sign_buffer(buffer, &sig, keyid)) @@ -190,6 +190,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid, strbuf_release(&sig); strbuf_release(&compat_sig); strbuf_release(&compat_buf); + free(keyid); return ret; } diff --git a/commit.c b/commit.c index 3238772f52..34cac0e302 100644 --- a/commit.c +++ b/commit.c @@ -183,7 +183,7 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid) commit_graft_oid_access); } -static void unparse_commit(struct repository *r, const struct object_id *oid) +void unparse_commit(struct repository *r, const struct object_id *oid) { struct commit *c = lookup_commit(r, oid); @@ -324,18 +324,6 @@ int for_each_commit_graft(each_commit_graft_fn fn, void *cb_data) return ret; } -void reset_commit_grafts(struct repository *r) -{ - int i; - - for (i = 0; i < r->parsed_objects->grafts_nr; i++) { - unparse_commit(r, &r->parsed_objects->grafts[i]->oid); - free(r->parsed_objects->grafts[i]); - } - r->parsed_objects->grafts_nr = 0; - r->parsed_objects->commit_graft_prepared = 0; -} - struct commit_buffer { void *buffer; unsigned long size; @@ -1156,11 +1144,14 @@ int add_header_signature(struct strbuf *buf, struct strbuf *sig, const struct gi static int sign_commit_to_strbuf(struct strbuf *sig, struct strbuf *buf, const char *keyid) { + char *keyid_to_free = NULL; + int ret = 0; if (!keyid || !*keyid) - keyid = get_signing_key(); + keyid = keyid_to_free = get_signing_key(); if (sign_buffer(buf, sig, keyid)) - return -1; - return 0; + ret = -1; + free(keyid_to_free); + return ret; } int parse_signed_commit(const struct commit *commit, diff --git a/commit.h b/commit.h index 0e5fce543c..13098422c5 100644 --- a/commit.h +++ b/commit.h @@ -110,6 +110,8 @@ static inline int repo_parse_commit_no_graph(struct repository *r, void parse_commit_or_die(struct commit *item); +void unparse_commit(struct repository *r, const struct object_id *oid); + struct buffer_slab; struct buffer_slab *allocate_commit_buffer_slab(void); void free_commit_buffer_slab(struct buffer_slab *bs); @@ -242,7 +244,6 @@ int commit_graft_pos(struct repository *r, const struct object_id *oid); int register_commit_graft(struct repository *r, struct commit_graft *, int); void prepare_commit_graft(struct repository *r); struct commit_graft *lookup_commit_graft(struct repository *r, const struct object_id *oid); -void reset_commit_grafts(struct repository *r); struct commit *get_fork_point(const char *refname, struct commit *commit); diff --git a/fetch-pack.c b/fetch-pack.c index 983c560785..2c76bcad40 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -2227,7 +2227,10 @@ void negotiate_using_fetch(const struct oid_array *negotiation_tips, trace2_region_leave("fetch-pack", "negotiate_using_fetch", the_repository); trace2_data_intmax("negotiate_using_fetch", the_repository, "total_rounds", negotiation_round); + clear_common_flag(acked_commits); + object_array_clear(&nt_object_array); + negotiator.release(&negotiator); strbuf_release(&req_buf); } diff --git a/gpg-interface.c b/gpg-interface.c index 6587085cd1..cf6126b5aa 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -45,8 +45,8 @@ struct gpg_format { size_t signature_size); int (*sign_buffer)(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); - const char *(*get_default_key)(void); - const char *(*get_key_id)(void); + char *(*get_default_key)(void); + char *(*get_key_id)(void); }; static const char *openpgp_verify_args[] = { @@ -86,9 +86,9 @@ static int sign_buffer_gpg(struct strbuf *buffer, struct strbuf *signature, static int sign_buffer_ssh(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); -static const char *get_default_ssh_signing_key(void); +static char *get_default_ssh_signing_key(void); -static const char *get_ssh_key_id(void); +static char *get_ssh_key_id(void); static struct gpg_format gpg_format[] = { { @@ -847,7 +847,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key) } /* Returns the first public key from an ssh-agent to use for signing */ -static const char *get_default_ssh_signing_key(void) +static char *get_default_ssh_signing_key(void) { struct child_process ssh_default_key = CHILD_PROCESS_INIT; int ret = -1; @@ -899,12 +899,16 @@ static const char *get_default_ssh_signing_key(void) return default_key; } -static const char *get_ssh_key_id(void) { - return get_ssh_key_fingerprint(get_signing_key()); +static char *get_ssh_key_id(void) +{ + char *signing_key = get_signing_key(); + char *key_id = get_ssh_key_fingerprint(signing_key); + free(signing_key); + return key_id; } /* Returns a textual but unique representation of the signing key */ -const char *get_signing_key_id(void) +char *get_signing_key_id(void) { gpg_interface_lazy_init(); @@ -916,17 +920,17 @@ const char *get_signing_key_id(void) return get_signing_key(); } -const char *get_signing_key(void) +char *get_signing_key(void) { gpg_interface_lazy_init(); if (configured_signing_key) - return configured_signing_key; + return xstrdup(configured_signing_key); if (use_format->get_default_key) { return use_format->get_default_key(); } - return git_committer_info(IDENT_STRICT | IDENT_NO_DATE); + return xstrdup(git_committer_info(IDENT_STRICT | IDENT_NO_DATE)); } const char *gpg_trust_level_to_str(enum signature_trust_level level) diff --git a/gpg-interface.h b/gpg-interface.h index 7cd98161f7..e09f12e8d0 100644 --- a/gpg-interface.h +++ b/gpg-interface.h @@ -80,13 +80,13 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *gpg_trust_level_to_str(enum signature_trust_level level); void set_signing_key(const char *); -const char *get_signing_key(void); +char *get_signing_key(void); /* * Returns a textual unique representation of the signing key in use * Either a GPG KeyID or a SSH Key Fingerprint */ -const char *get_signing_key_id(void); +char *get_signing_key_id(void); int check_signature(struct signature_check *sigc, const char *signature, size_t slen); void print_signature_buffer(const struct signature_check *sigc, diff --git a/match-trees.c b/match-trees.c index f17c74d483..147b03abf1 100644 --- a/match-trees.c +++ b/match-trees.c @@ -294,18 +294,22 @@ void shift_tree(struct repository *r, unsigned short mode; if (!*del_prefix) - return; + goto out; if (get_tree_entry(r, hash2, del_prefix, shifted, &mode)) die("cannot find path %s in tree %s", del_prefix, oid_to_hex(hash2)); - return; + goto out; } if (!*add_prefix) - return; + goto out; splice_tree(hash1, add_prefix, hash2, shifted); + +out: + free(add_prefix); + free(del_prefix); } /* diff --git a/merge-ort.c b/merge-ort.c index 3752c7e595..0ed3cd06b1 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -2710,7 +2710,7 @@ static void apply_directory_rename_modifications(struct merge_options *opt, struct conflict_info *dir_ci; char *cur_dir = dirs_to_insert.items[i].string; - CALLOC_ARRAY(dir_ci, 1); + dir_ci = mem_pool_calloc(&opt->priv->pool, 1, sizeof(*dir_ci)); dir_ci->merged.directory_name = parent_name; len = strlen(parent_name); @@ -2838,6 +2838,8 @@ static void apply_directory_rename_modifications(struct merge_options *opt, * Finally, record the new location. */ pair->two->path = new_path; + + string_list_clear(&dirs_to_insert, 0); } /*** Function Grouping: functions related to regular rename detection ***/ diff --git a/negotiator/skipping.c b/negotiator/skipping.c index 6e61b3c5f1..abedb70a48 100644 --- a/negotiator/skipping.c +++ b/negotiator/skipping.c @@ -247,8 +247,11 @@ static int ack(struct fetch_negotiator *n, struct commit *c) static void release(struct fetch_negotiator *n) { - clear_prio_queue(&((struct data *)n->data)->rev_list); - FREE_AND_NULL(n->data); + struct data *data = n->data; + for (int i = 0; i < data->rev_list.nr; i++) + free(data->rev_list.array[i].data); + clear_prio_queue(&data->rev_list); + FREE_AND_NULL(data); } void skipping_negotiator_init(struct fetch_negotiator *negotiator) diff --git a/object.c b/object.c index d756c7f2ea..94ea8fb8d2 100644 --- a/object.c +++ b/object.c @@ -545,11 +545,12 @@ void repo_clear_commit_marks(struct repository *r, unsigned int flags) } } -struct parsed_object_pool *parsed_object_pool_new(void) +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo) { struct parsed_object_pool *o = xmalloc(sizeof(*o)); memset(o, 0, sizeof(*o)); + o->repo = repo; o->blob_state = allocate_alloc_state(); o->tree_state = allocate_alloc_state(); o->commit_state = allocate_alloc_state(); @@ -628,6 +629,16 @@ void raw_object_store_clear(struct raw_object_store *o) hashmap_clear(&o->pack_map); } +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o) +{ + for (int i = 0; i < o->grafts_nr; i++) { + unparse_commit(o->repo, &o->grafts[i]->oid); + free(o->grafts[i]); + } + o->grafts_nr = 0; + o->commit_graft_prepared = 0; +} + void parsed_object_pool_clear(struct parsed_object_pool *o) { /* @@ -659,6 +670,7 @@ void parsed_object_pool_clear(struct parsed_object_pool *o) free_commit_buffer_slab(o->buffer_slab); o->buffer_slab = NULL; + parsed_object_pool_reset_commit_grafts(o); clear_alloc_state(o->blob_state); clear_alloc_state(o->tree_state); clear_alloc_state(o->commit_state); diff --git a/object.h b/object.h index 05691486eb..17f32f1103 100644 --- a/object.h +++ b/object.h @@ -7,6 +7,7 @@ struct buffer_slab; struct repository; struct parsed_object_pool { + struct repository *repo; struct object **obj_hash; int nr_objs, obj_hash_size; @@ -31,8 +32,9 @@ struct parsed_object_pool { struct buffer_slab *buffer_slab; }; -struct parsed_object_pool *parsed_object_pool_new(void); +struct parsed_object_pool *parsed_object_pool_new(struct repository *repo); void parsed_object_pool_clear(struct parsed_object_pool *o); +void parsed_object_pool_reset_commit_grafts(struct parsed_object_pool *o); struct object_list { struct object *item; diff --git a/remote.c b/remote.c index 539e5ceae3..390a03c264 100644 --- a/remote.c +++ b/remote.c @@ -1123,6 +1123,7 @@ void free_one_ref(struct ref *ref) return; free_one_ref(ref->peer_ref); free(ref->remote_status); + free(ref->tracking_ref); free(ref->symref); free(ref); } @@ -2620,8 +2621,10 @@ static int remote_tracking(struct remote *remote, const char *refname, dst = apply_refspecs(&remote->fetch, refname); if (!dst) return -1; /* no tracking ref for refname at remote */ - if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) + if (refs_read_ref(get_main_ref_store(the_repository), dst, oid)) { + free(dst); return -1; /* we know what the tracking ref is but we cannot read it */ + } *dst_refname = dst; return 0; @@ -2771,6 +2774,7 @@ static void check_if_includes_upstream(struct ref *remote) if (is_reachable_in_reflog(local->name, remote) <= 0) remote->unreachable = 1; + free_one_ref(local); } static void apply_cas(struct push_cas_option *cas, diff --git a/repository.c b/repository.c index 9825a30899..e6fc2c6aa9 100644 --- a/repository.c +++ b/repository.c @@ -54,7 +54,7 @@ void initialize_repository(struct repository *repo) { repo->objects = raw_object_store_new(); repo->remote_state = remote_state_new(); - repo->parsed_objects = parsed_object_pool_new(); + repo->parsed_objects = parsed_object_pool_new(repo); ALLOC_ARRAY(repo->index, 1); index_state_init(repo->index, repo); diff --git a/send-pack.c b/send-pack.c index 5d0c23772a..6677c44e8a 100644 --- a/send-pack.c +++ b/send-pack.c @@ -353,7 +353,8 @@ static int generate_push_cert(struct strbuf *req_buf, { const struct ref *ref; struct string_list_item *item; - char *signing_key_id = xstrdup(get_signing_key_id()); + char *signing_key_id = get_signing_key_id(); + char *signing_key = get_signing_key(); const char *cp, *np; struct strbuf cert = STRBUF_INIT; int update_seen = 0; @@ -386,7 +387,7 @@ static int generate_push_cert(struct strbuf *req_buf, if (!update_seen) goto free_return; - if (sign_buffer(&cert, &cert, get_signing_key())) + if (sign_buffer(&cert, &cert, signing_key)) die(_("failed to sign the push certificate")); packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string); @@ -399,6 +400,7 @@ static int generate_push_cert(struct strbuf *req_buf, free_return: free(signing_key_id); + free(signing_key); strbuf_release(&cert); return update_seen; } @@ -506,14 +508,15 @@ int send_pack(struct send_pack_args *args, unsigned cmds_sent = 0; int ret; struct async demux; - const char *push_cert_nonce = NULL; + char *push_cert_nonce = NULL; struct packet_reader reader; int use_bitmaps; if (!remote_refs) { fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch.\n"); - return 0; + ret = 0; + goto out; } git_config_get_bool("push.negotiate", &push_negotiate); @@ -557,10 +560,11 @@ int send_pack(struct send_pack_args *args, if (args->push_cert != SEND_PACK_PUSH_CERT_NEVER) { size_t len; - push_cert_nonce = server_feature_value("push-cert", &len); - if (push_cert_nonce) { - reject_invalid_nonce(push_cert_nonce, len); - push_cert_nonce = xmemdupz(push_cert_nonce, len); + const char *nonce = server_feature_value("push-cert", &len); + + if (nonce) { + reject_invalid_nonce(nonce, len); + push_cert_nonce = xmemdupz(nonce, len); } else if (args->push_cert == SEND_PACK_PUSH_CERT_ALWAYS) { die(_("the receiving end does not support --signed push")); } else if (args->push_cert == SEND_PACK_PUSH_CERT_IF_ASKED) { @@ -623,12 +627,11 @@ int send_pack(struct send_pack_args *args, * atomically, abort the whole operation. */ if (use_atomic) { - strbuf_release(&req_buf); - strbuf_release(&cap_buf); reject_atomic_push(remote_refs, args->send_mirror); error("atomic push failed for ref %s. status: %d", ref->name, ref->status); - return args->porcelain ? 0 : -1; + ret = args->porcelain ? 0 : -1; + goto out; } /* else fallthrough */ default: @@ -692,8 +695,6 @@ int send_pack(struct send_pack_args *args, write_or_die(out, req_buf.buf, req_buf.len); packet_flush(out); } - strbuf_release(&req_buf); - strbuf_release(&cap_buf); if (use_sideband && cmds_sent) { memset(&demux, 0, sizeof(demux)); @@ -731,7 +732,9 @@ int send_pack(struct send_pack_args *args, finish_async(&demux); } fd[1] = -1; - return -1; + + ret = -1; + goto out; } if (!args->stateless_rpc) /* Closed by pack_objects() via start_command() */ @@ -756,10 +759,12 @@ int send_pack(struct send_pack_args *args, } if (ret < 0) - return ret; + goto out; - if (args->porcelain) - return 0; + if (args->porcelain) { + ret = 0; + goto out; + } for (ref = remote_refs; ref; ref = ref->next) { switch (ref->status) { @@ -768,8 +773,17 @@ int send_pack(struct send_pack_args *args, case REF_STATUS_OK: break; default: - return -1; + ret = -1; + goto out; } } - return 0; + + ret = 0; + +out: + oid_array_clear(&commons); + strbuf_release(&req_buf); + strbuf_release(&cap_buf); + free(push_cert_nonce); + return ret; } diff --git a/shallow.c b/shallow.c index b8cd051e3b..dcebc263d7 100644 --- a/shallow.c +++ b/shallow.c @@ -51,10 +51,12 @@ int unregister_shallow(const struct object_id *oid) int pos = commit_graft_pos(the_repository, oid); if (pos < 0) return -1; - if (pos + 1 < the_repository->parsed_objects->grafts_nr) + if (pos + 1 < the_repository->parsed_objects->grafts_nr) { + free(the_repository->parsed_objects->grafts[pos]); MOVE_ARRAY(the_repository->parsed_objects->grafts + pos, the_repository->parsed_objects->grafts + pos + 1, the_repository->parsed_objects->grafts_nr - pos - 1); + } the_repository->parsed_objects->grafts_nr--; return 0; } @@ -97,7 +99,7 @@ static void reset_repository_shallow(struct repository *r) { r->parsed_objects->is_shallow = -1; stat_validity_clear(r->parsed_objects->shallow_stat); - reset_commit_grafts(r); + parsed_object_pool_reset_commit_grafts(r->parsed_objects); } int commit_shallow_file(struct repository *r, struct shallow_lock *lk) @@ -487,6 +489,15 @@ void prepare_shallow_info(struct shallow_info *info, struct oid_array *sa) void clear_shallow_info(struct shallow_info *info) { + if (info->used_shallow) { + for (size_t i = 0; i < info->shallow->nr; i++) + free(info->used_shallow[i]); + free(info->used_shallow); + } + + free(info->need_reachability_test); + free(info->reachable); + free(info->shallow_ref); free(info->ours); free(info->theirs); } diff --git a/submodule.c b/submodule.c index 97516b0fec..97d0d47b56 100644 --- a/submodule.c +++ b/submodule.c @@ -1883,6 +1883,8 @@ int fetch_submodules(struct repository *r, out: free_submodules_data(&spf.changed_submodule_names); string_list_clear(&spf.seen_submodule_names, 0); + strbuf_release(&spf.submodules_with_errors); + free(spf.oid_fetch_tasks); return spf.result; } diff --git a/t/README b/t/README index 44c02d8129..8dcb778e26 100644 --- a/t/README +++ b/t/README @@ -386,6 +386,9 @@ GIT_TEST_PASSING_SANITIZE_LEAK=check when combined with "--immediate" will run to completion faster, and result in the same failing tests. +GIT_TEST_PASSING_SANITIZE_LEAK=check-failing behaves the same as "check", +but skips all tests which are already marked as leak-free. + GIT_TEST_PROTOCOL_VERSION=, when set, makes 'protocol.version' default to n. diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9d693eb57f..331778bd42 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -19,6 +19,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME TEST_CREATE_REPO_NO_TEMPLATE=1 +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 5e566205ba..2cfb5bd6bb 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -6,6 +6,7 @@ test_description='Recursive "git fetch" for submodules' GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh pwd=$(pwd) diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index f3fff55744..135823630a 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -8,6 +8,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5533-push-cas.sh b/t/t5533-push-cas.sh index cba26a872d..6365d99777 100755 --- a/t/t5533-push-cas.sh +++ b/t/t5533-push-cas.sh @@ -5,6 +5,7 @@ test_description='compare & swap push force/delete safety' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_srcdst_basic () { diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index c91a62b77a..d43aee0c32 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -5,6 +5,7 @@ test_description='signed push' 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-gpg.sh diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index 37f7547a4c..cae4d400f3 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -5,6 +5,7 @@ test_description='fetch/clone from a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh index e91fcc173e..6adc3a20a4 100755 --- a/t/t5538-push-shallow.sh +++ b/t/t5538-push-shallow.sh @@ -5,6 +5,7 @@ test_description='push from/to a shallow clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit() { diff --git a/t/t5549-fetch-push-http.sh b/t/t5549-fetch-push-http.sh index 2cdebcb735..6377fb6d99 100755 --- a/t/t5549-fetch-push-http.sh +++ b/t/t5549-fetch-push-http.sh @@ -5,6 +5,7 @@ test_description='fetch/push functionality using the HTTP protocol' 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-httpd.sh start_httpd diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh index b55a9f65e6..4f2e5ae8df 100755 --- a/t/t5552-skipping-fetch-negotiator.sh +++ b/t/t5552-skipping-fetch-negotiator.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test skipping fetch negotiator' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'fetch.negotiationalgorithm config' ' diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 8415884754..c53e93be2f 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -5,6 +5,7 @@ test_description='git partial clone' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # create a normal "src" repo where we can later create new commits. diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh index 9fdafeb1e9..f31c09c056 100755 --- a/t/t6132-pathspec-exclude.sh +++ b/t/t6132-pathspec-exclude.sh @@ -2,6 +2,7 @@ test_description='test case exclude pathspec' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index 120dcd74a5..794bc7daf0 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test labels in pathspecs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a tree' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 5a221f8ef1..ac57b0e4ae 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -8,6 +8,7 @@ test_description='fmt-merge-msg test' 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-gpg.sh" diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh index e9ba6f1690..528615b981 100755 --- a/t/t6409-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh @@ -5,6 +5,7 @@ test_description='subtree merge strategy' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh index 88d1cf2cde..4aaaf38be6 100755 --- a/t/t6423-merge-rename-directories.sh +++ b/t/t6423-merge-rename-directories.sh @@ -25,6 +25,7 @@ test_description="recursive merge with directory renames" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 5378455968..ee074b99b7 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -3,6 +3,7 @@ test_description='basic git gc tests ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index 9fc1626fbf..8877aea98b 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -2,6 +2,7 @@ test_description='git repack --geometric works correctly' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh GIT_TEST_MULTI_PACK_INDEX=0 diff --git a/t/test-lib.sh b/t/test-lib.sh index 278d1215f1..e718efe4c6 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1558,8 +1558,16 @@ then passes_sanitize_leak=t fi - if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" + if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || + test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" then + if test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" && + test -n "$passes_sanitize_leak" + then + skip_all="skipping leak-free $this_test under GIT_TEST_PASSING_SANITIZE_LEAK=check-failing" + test_done + fi + sanitize_leak_check=t if test -n "$invert_exit_code" then @@ -1597,6 +1605,7 @@ then export LSAN_OPTIONS elif test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check" || + test "$GIT_TEST_PASSING_SANITIZE_LEAK" = "check-failing" || test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false then BAIL_OUT_ENV_NEEDS_SANITIZE_LEAK "GIT_TEST_PASSING_SANITIZE_LEAK=true" diff --git a/upload-pack.c b/upload-pack.c index f03ba3e98b..c84c3c3b1f 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -709,10 +709,13 @@ static int get_reachable_list(struct upload_pack_data *data, struct object *o; char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */ const unsigned hexsz = the_hash_algo->hexsz; + int ret; if (do_reachable_revlist(&cmd, &data->shallows, reachable, - data->allow_uor) < 0) - return -1; + data->allow_uor) < 0) { + ret = -1; + goto out; + } while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) { struct object_id oid; @@ -736,10 +739,16 @@ static int get_reachable_list(struct upload_pack_data *data, } close(cmd.out); - if (finish_command(&cmd)) - return -1; + if (finish_command(&cmd)) { + ret = -1; + goto out; + } - return 0; + ret = 0; + +out: + child_process_clear(&cmd); + return ret; } static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) @@ -749,7 +758,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) int i; if (do_reachable_revlist(&cmd, src, NULL, allow_uor) < 0) - return 1; + goto error; /* * The commits out of the rev-list are not ancestors of @@ -775,6 +784,7 @@ static int has_unreachable(struct object_array *src, enum allow_uor allow_uor) error: if (cmd.out >= 0) close(cmd.out); + child_process_clear(&cmd); return 1; }