Git fork

Merge branch 'ps/leakfixes-part-9' into ps/leakfixes-part-10

* ps/leakfixes-part-9: (22 commits)
list-objects-filter-options: work around reported leak on error
builtin/merge: release output buffer after performing merge
dir: fix leak when parsing "status.showUntrackedFiles"
t/helper: fix leaking buffer in "dump-untracked-cache"
t/helper: stop re-initialization of `the_repository`
sparse-index: correctly free EWAH contents
dir: release untracked cache data
combine-diff: fix leaking lost lines
builtin/tag: fix leaking key ID on failure to sign
transport-helper: fix leaking import/export marks
builtin/commit: fix leaking cleanup config
trailer: fix leaking strbufs when formatting trailers
trailer: fix leaking trailer values
builtin/commit: fix leaking change data contents
upload-pack: fix leaking URI protocols
pretty: clear signature check
diff-lib: fix leaking diffopts in `do_diff_cache()`
revision: fix leaking bloom filters
builtin/grep: fix leak with `--max-count=0`
grep: fix leak in `grep_splice_or()`
...

+115 -35
+20 -6
builtin/commit.c
··· 135 135 * is specified explicitly. 136 136 */ 137 137 static enum commit_msg_cleanup_mode cleanup_mode; 138 - static char *cleanup_arg; 138 + static char *cleanup_config; 139 139 140 140 static enum commit_whence whence; 141 141 static int use_editor = 1, include_status = 1; ··· 728 728 repo_unuse_commit_buffer(the_repository, commit, buffer); 729 729 } 730 730 731 + static void change_data_free(void *util, const char *str UNUSED) 732 + { 733 + struct wt_status_change_data *d = util; 734 + free(d->rename_source); 735 + free(d); 736 + } 737 + 731 738 static int prepare_to_commit(const char *index_file, const char *prefix, 732 739 struct commit *current_head, 733 740 struct wt_status *s, ··· 991 998 s->use_color = 0; 992 999 committable = run_status(s->fp, index_file, prefix, 1, s); 993 1000 s->use_color = saved_color_setting; 994 - string_list_clear(&s->change, 1); 1001 + string_list_clear_func(&s->change, change_data_free); 995 1002 } else { 996 1003 struct object_id oid; 997 1004 const char *parent = "HEAD"; ··· 1379 1386 1380 1387 if (0 <= edit_flag) 1381 1388 use_editor = edit_flag; 1382 - 1383 - cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor); 1384 1389 1385 1390 handle_untracked_files_arg(s); 1386 1391 ··· 1629 1634 include_status = git_config_bool(k, v); 1630 1635 return 0; 1631 1636 } 1632 - if (!strcmp(k, "commit.cleanup")) 1633 - return git_config_string(&cleanup_arg, k, v); 1637 + if (!strcmp(k, "commit.cleanup")) { 1638 + FREE_AND_NULL(cleanup_config); 1639 + return git_config_string(&cleanup_config, k, v); 1640 + } 1634 1641 if (!strcmp(k, "commit.gpgsign")) { 1635 1642 sign_commit = git_config_bool(k, v) ? "" : NULL; 1636 1643 return 0; ··· 1651 1658 struct repository *repo UNUSED) 1652 1659 { 1653 1660 static struct wt_status s; 1661 + static const char *cleanup_arg = NULL; 1654 1662 static struct option builtin_commit_options[] = { 1655 1663 OPT__QUIET(&quiet, N_("suppress summary after successful commit")), 1656 1664 OPT__VERBOSE(&verbose, N_("show diff in commit message template")), ··· 1749 1757 prefix, current_head, &s); 1750 1758 if (verbose == -1) 1751 1759 verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose; 1760 + 1761 + if (cleanup_arg) { 1762 + free(cleanup_config); 1763 + cleanup_config = xstrdup(cleanup_arg); 1764 + } 1765 + cleanup_mode = get_cleanup_mode(cleanup_config, use_editor); 1752 1766 1753 1767 if (dry_run) 1754 1768 return dry_run_commit(argv, prefix, current_head, &s);
+10 -3
builtin/grep.c
··· 906 906 int dummy; 907 907 int use_index = 1; 908 908 int allow_revs; 909 + int ret; 909 910 910 911 struct option options[] = { 911 912 OPT_BOOL(0, "cached", &cached, ··· 1172 1173 * Optimize out the case where the amount of matches is limited to zero. 1173 1174 * We do this to keep results consistent with GNU grep(1). 1174 1175 */ 1175 - if (opt.max_count == 0) 1176 - return 1; 1176 + if (opt.max_count == 0) { 1177 + ret = 1; 1178 + goto out; 1179 + } 1177 1180 1178 1181 if (show_in_pager) { 1179 1182 if (num_threads > 1) ··· 1267 1270 hit |= wait_all(); 1268 1271 if (hit && show_in_pager) 1269 1272 run_pager(&opt, prefix); 1273 + 1274 + ret = !hit; 1275 + 1276 + out: 1270 1277 clear_pathspec(&pathspec); 1271 1278 string_list_clear(&path_list, 0); 1272 1279 free_grep_patterns(&opt); 1273 1280 object_array_clear(&list); 1274 1281 free_repos(); 1275 - return !hit; 1282 + return ret; 1276 1283 }
+1
builtin/ls-remote.c
··· 166 166 status = 0; /* we found something */ 167 167 } 168 168 169 + string_list_clear(&server_options, 0); 169 170 ref_sorting_release(sorting); 170 171 ref_array_clear(&ref_array); 171 172 if (transport_disconnect(transport))
+1
builtin/merge.c
··· 754 754 clean = merge_recursive(&o, head, remoteheads->item, 755 755 reversed, &result); 756 756 free_commit_list(reversed); 757 + strbuf_release(&o.obuf); 757 758 758 759 if (clean < 0) { 759 760 rollback_lock_file(&lock);
+1 -1
builtin/tag.c
··· 164 164 int ret = -1; 165 165 166 166 if (sign_buffer(buffer, &sig, keyid)) 167 - return -1; 167 + goto out; 168 168 169 169 if (compat) { 170 170 const struct git_hash_algo *algo = the_repository->hash_algo;
+3 -2
combine-diff.c
··· 1185 1185 result_file.ptr = result; 1186 1186 result_file.size = result_size; 1187 1187 1188 - /* Even p_lno[cnt+1] is valid -- that is for the end line number 1188 + /* 1189 + * Even p_lno[cnt+1] is valid -- that is for the end line number 1189 1190 * for deletion hunk at the end. 1190 1191 */ 1191 1192 CALLOC_ARRAY(sline[0].p_lno, st_mult(st_add(cnt, 2), num_parent)); ··· 1220 1221 } 1221 1222 free(result); 1222 1223 1223 - for (lno = 0; lno < cnt; lno++) { 1224 + for (lno = 0; lno < cnt + 2; lno++) { 1224 1225 if (sline[lno].lost) { 1225 1226 struct lline *ll = sline[lno].lost; 1226 1227 while (ll) {
+1
diff-lib.c
··· 661 661 662 662 repo_init_revisions(opt->repo, &revs, NULL); 663 663 copy_pathspec(&revs.prune_data, &opt->pathspec); 664 + diff_free(&revs.diffopt); 664 665 revs.diffopt = *opt; 665 666 revs.diffopt.no_free = 1; 666 667
+10 -2
dir.c
··· 1056 1056 { 1057 1057 int i; 1058 1058 dir->valid = 0; 1059 + for (size_t i = 0; i < dir->untracked_nr; i++) 1060 + free(dir->untracked[i]); 1059 1061 dir->untracked_nr = 0; 1060 1062 for (i = 0; i < dir->dirs_nr; i++) 1061 1063 do_invalidate_gitignore(dir->dirs[i]); ··· 1083 1085 uc->dir_invalidated++; 1084 1086 1085 1087 dir->valid = 0; 1088 + for (size_t i = 0; i < dir->untracked_nr; i++) 1089 + free(dir->untracked[i]); 1086 1090 dir->untracked_nr = 0; 1087 1091 for (i = 0; i < dir->dirs_nr; i++) 1088 1092 dir->dirs[i]->recurse = 0; ··· 2868 2872 static unsigned new_untracked_cache_flags(struct index_state *istate) 2869 2873 { 2870 2874 struct repository *repo = istate->repo; 2871 - char *val; 2875 + const char *val; 2872 2876 2873 2877 /* 2874 2878 * This logic is coordinated with the setting of these flags in 2875 2879 * wt-status.c#wt_status_collect_untracked(), and the evaluation 2876 2880 * of the config setting in commit.c#git_status_config() 2877 2881 */ 2878 - if (!repo_config_get_string(repo, "status.showuntrackedfiles", &val) && 2882 + if (!repo_config_get_string_tmp(repo, "status.showuntrackedfiles", &val) && 2879 2883 !strcmp(val, "all")) 2880 2884 return 0; 2881 2885 ··· 3573 3577 * for safety.. 3574 3578 */ 3575 3579 if (!untracked->valid) { 3580 + for (size_t i = 0; i < untracked->untracked_nr; i++) 3581 + free(untracked->untracked[i]); 3576 3582 untracked->untracked_nr = 0; 3577 3583 untracked->check_only = 0; 3578 3584 } ··· 3905 3911 { 3906 3912 uc->dir_invalidated++; 3907 3913 ucd->valid = 0; 3914 + for (size_t i = 0; i < ucd->untracked_nr; i++) 3915 + free(ucd->untracked[i]); 3908 3916 ucd->untracked_nr = 0; 3909 3917 } 3910 3918
+1
grep.c
··· 756 756 assert(x->node == GREP_NODE_OR); 757 757 if (x->u.binary.right && 758 758 x->u.binary.right->node == GREP_NODE_TRUE) { 759 + free(x->u.binary.right); 759 760 x->u.binary.right = y; 760 761 break; 761 762 }
+7 -10
list-objects-filter-options.c
··· 252 252 const char *arg) 253 253 { 254 254 struct strbuf errbuf = STRBUF_INIT; 255 - int parse_error; 256 255 257 256 if (!filter_options->filter_spec.buf) 258 257 BUG("filter_options not properly initialized"); 259 258 260 259 if (!filter_options->choice) { 260 + if (gently_parse_list_objects_filter(filter_options, arg, &errbuf)) 261 + die("%s", errbuf.buf); 261 262 strbuf_addstr(&filter_options->filter_spec, arg); 262 - 263 - parse_error = gently_parse_list_objects_filter( 264 - filter_options, arg, &errbuf); 265 263 } else { 266 264 struct list_objects_filter_options *sub; 267 265 ··· 271 269 */ 272 270 transform_to_combine_type(filter_options); 273 271 274 - strbuf_addch(&filter_options->filter_spec, '+'); 275 - filter_spec_append_urlencode(filter_options, arg); 276 272 ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1, 277 273 filter_options->sub_alloc); 278 274 sub = &filter_options->sub[filter_options->sub_nr - 1]; 279 275 280 276 list_objects_filter_init(sub); 281 - parse_error = gently_parse_list_objects_filter(sub, arg, 282 - &errbuf); 277 + if (gently_parse_list_objects_filter(sub, arg, &errbuf)) 278 + die("%s", errbuf.buf); 279 + 280 + strbuf_addch(&filter_options->filter_spec, '+'); 281 + filter_spec_append_urlencode(filter_options, arg); 283 282 } 284 - if (parse_error) 285 - die("%s", errbuf.buf); 286 283 } 287 284 288 285 int opt_parse_list_objects_filter(const struct option *opt,
+1
pretty.c
··· 2032 2032 2033 2033 free(context.commit_encoding); 2034 2034 repo_unuse_commit_buffer(r, commit, context.message); 2035 + signature_check_clear(&context.signature_check); 2035 2036 } 2036 2037 2037 2038 static void pp_header(struct pretty_print_context *pp,
+5
revision.c
··· 3227 3227 clear_decoration(&revs->treesame, free); 3228 3228 line_log_free(revs); 3229 3229 oidset_clear(&revs->missing_commits); 3230 + 3231 + for (int i = 0; i < revs->bloom_keys_nr; i++) 3232 + clear_bloom_key(&revs->bloom_keys[i]); 3233 + FREE_AND_NULL(revs->bloom_keys); 3234 + revs->bloom_keys_nr = 0; 3230 3235 } 3231 3236 3232 3237 static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child)
+5 -2
sparse-index.c
··· 2 2 3 3 #include "git-compat-util.h" 4 4 #include "environment.h" 5 + #include "ewah/ewok.h" 5 6 #include "gettext.h" 6 7 #include "name-hash.h" 7 8 #include "read-cache-ll.h" ··· 242 243 cache_tree_update(istate, 0); 243 244 244 245 istate->fsmonitor_has_run_once = 0; 245 - FREE_AND_NULL(istate->fsmonitor_dirty); 246 + ewah_free(istate->fsmonitor_dirty); 247 + istate->fsmonitor_dirty = NULL; 246 248 FREE_AND_NULL(istate->fsmonitor_last_update); 247 249 248 250 istate->sparse_index = INDEX_COLLAPSED; ··· 438 440 istate->cache_nr = full->cache_nr; 439 441 istate->cache_alloc = full->cache_alloc; 440 442 istate->fsmonitor_has_run_once = 0; 441 - FREE_AND_NULL(istate->fsmonitor_dirty); 443 + ewah_free(istate->fsmonitor_dirty); 444 + istate->fsmonitor_dirty = NULL; 442 445 FREE_AND_NULL(istate->fsmonitor_last_update); 443 446 444 447 strbuf_release(&base);
+2
t/helper/test-dump-untracked-cache.c
··· 68 68 printf("flags %08x\n", uc->dir_flags); 69 69 if (uc->root) 70 70 dump(uc->root, &base); 71 + 72 + strbuf_release(&base); 71 73 return 0; 72 74 }
+10
t/helper/test-reach.c
··· 127 127 exit(128); 128 128 printf("%s(A,X):\n", av[1]); 129 129 print_sorted_commit_ids(list); 130 + free_commit_list(list); 130 131 } else if (!strcmp(av[1], "reduce_heads")) { 131 132 struct commit_list *list = reduce_heads(X); 132 133 printf("%s(X):\n", av[1]); 133 134 print_sorted_commit_ids(list); 135 + free_commit_list(list); 134 136 } else if (!strcmp(av[1], "can_all_from_reach")) { 135 137 printf("%s(X,Y):%d\n", av[1], can_all_from_reach(X, Y, 1)); 136 138 } else if (!strcmp(av[1], "can_all_from_reach_with_flag")) { ··· 153 155 filter.with_commit_tag_algo = 0; 154 156 155 157 printf("%s(_,A,X,_):%d\n", av[1], commit_contains(&filter, A, X, &cache)); 158 + clear_contains_cache(&cache); 156 159 } else if (!strcmp(av[1], "get_reachable_subset")) { 157 160 const int reachable_flag = 1; 158 161 int i, count = 0; ··· 176 179 die(_("too many commits marked reachable")); 177 180 178 181 print_sorted_commit_ids(list); 182 + free_commit_list(list); 179 183 } 180 184 185 + object_array_clear(&X_obj); 186 + strbuf_release(&buf); 187 + free_commit_list(X); 188 + free_commit_list(Y); 189 + free(X_array); 190 + free(Y_array); 181 191 return 0; 182 192 }
-2
t/helper/test-read-cache.c
··· 11 11 int i, cnt = 1; 12 12 const char *name = NULL; 13 13 14 - initialize_repository(the_repository); 15 - 16 14 if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) { 17 15 argc--; 18 16 argv++;
+1
t/t4038-diff-combined.sh
··· 5 5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6 6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 . "$TEST_DIRECTORY"/lib-diff.sh 10 11
+1
t/t4202-log.sh
··· 5 5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6 6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 . "$TEST_DIRECTORY/lib-gpg.sh" 10 11 . "$TEST_DIRECTORY/lib-terminal.sh"
+1
t/t4216-log-bloom.sh
··· 4 4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 5 5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 6 6 7 + TEST_PASSES_SANITIZE_LEAK=true 7 8 . ./test-lib.sh 8 9 . "$TEST_DIRECTORY"/lib-chunk.sh 9 10
+1
t/t5702-protocol-v2.sh
··· 7 7 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 8 8 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 9 9 10 + TEST_PASSES_SANITIZE_LEAK=true 10 11 . ./test-lib.sh 11 12 12 13 # Test protocol v2 with 'git://' transport
+1
t/t5801-remote-helpers.sh
··· 8 8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 9 9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 10 10 11 + TEST_PASSES_SANITIZE_LEAK=true 11 12 . ./test-lib.sh 12 13 . "$TEST_DIRECTORY"/lib-gpg.sh 13 14
+1
t/t6112-rev-list-filters-objects.sh
··· 5 5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6 6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 10 11 # Test the blob:none filter.
+1
t/t6424-merge-unrelated-index-changes.sh
··· 2 2 3 3 test_description="merges with unrelated index changes" 4 4 5 + TEST_PASSES_SANITIZE_LEAK=true 5 6 . ./test-lib.sh 6 7 7 8 # Testcase for some simple merges
+1
t/t6600-test-reach.sh
··· 2 2 3 3 test_description='basic commit reachability tests' 4 4 5 + TEST_PASSES_SANITIZE_LEAK=true 5 6 . ./test-lib.sh 6 7 7 8 # Construct a grid-like commit graph with points (x,y)
+1
t/t7004-tag.sh
··· 10 10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 11 11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 12 12 13 + TEST_PASSES_SANITIZE_LEAK=true 13 14 . ./test-lib.sh 14 15 . "$TEST_DIRECTORY"/lib-gpg.sh 15 16 . "$TEST_DIRECTORY"/lib-terminal.sh
+1
t/t7031-verify-tag-signed-ssh.sh
··· 4 4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 5 5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 6 6 7 + TEST_PASSES_SANITIZE_LEAK=true 7 8 . ./test-lib.sh 8 9 . "$TEST_DIRECTORY/lib-gpg.sh" 9 10
+1
t/t7063-status-untracked-cache.sh
··· 5 5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6 6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 10 11 # On some filesystems (e.g. FreeBSD's ext2 and ufs) directory mtime
+1
t/t7500-commit-template-squash-signoff.sh
··· 7 7 8 8 Tests for template, signoff, squash and -F functions.' 9 9 10 + TEST_PASSES_SANITIZE_LEAK=true 10 11 . ./test-lib.sh 11 12 12 13 . "$TEST_DIRECTORY"/lib-rebase.sh
+1
t/t7502-commit-porcelain.sh
··· 5 5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 6 6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 10 11 commit_msg_is () {
+1
t/t7510-signed-commit.sh
··· 4 4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 5 5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 6 6 7 + TEST_PASSES_SANITIZE_LEAK=true 7 8 . ./test-lib.sh 8 9 GNUPGHOME_NOT_USED=$GNUPGHOME 9 10 . "$TEST_DIRECTORY/lib-gpg.sh"
+1
t/t7513-interpret-trailers.sh
··· 5 5 6 6 test_description='git interpret-trailers' 7 7 8 + TEST_PASSES_SANITIZE_LEAK=true 8 9 . ./test-lib.sh 9 10 10 11 # When we want one trailing space at the end of each line, let's use sed
+1
t/t7519-status-fsmonitor.sh
··· 2 2 3 3 test_description='git status with file system watcher' 4 4 5 + TEST_PASSES_SANITIZE_LEAK=true 5 6 . ./test-lib.sh 6 7 7 8 # Note, after "git reset --hard HEAD" no extensions exist other than 'TREE'
+1
t/t7528-signed-commit-ssh.sh
··· 4 4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 5 5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 6 6 7 + TEST_PASSES_SANITIZE_LEAK=true 7 8 . ./test-lib.sh 8 9 GNUPGHOME_NOT_USED=$GNUPGHOME 9 10 . "$TEST_DIRECTORY/lib-gpg.sh"
+1
t/t7610-mergetool.sh
··· 10 10 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 11 11 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 12 12 13 + TEST_PASSES_SANITIZE_LEAK=true 13 14 . ./test-lib.sh 14 15 15 16 # All the mergetool test work by checking out a temporary branch based
+1
t/t7810-grep.sh
··· 9 9 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 10 10 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 11 11 12 + TEST_PASSES_SANITIZE_LEAK=true 12 13 . ./test-lib.sh 13 14 14 15 test_invalid_grep_expression() {
+15 -7
trailer.c
··· 249 249 static void apply_item_command(struct trailer_item *in_tok, struct arg_item *arg_tok) 250 250 { 251 251 if (arg_tok->conf.command || arg_tok->conf.cmd) { 252 - const char *arg; 252 + char *value_to_free = NULL; 253 + char *arg; 254 + 253 255 if (arg_tok->value && arg_tok->value[0]) { 254 256 arg = arg_tok->value; 255 257 } else { ··· 257 259 arg = xstrdup(in_tok->value); 258 260 else 259 261 arg = xstrdup(""); 262 + value_to_free = arg_tok->value; 260 263 } 264 + 261 265 arg_tok->value = apply_command(&arg_tok->conf, arg); 262 - free((char *)arg); 266 + 267 + free(value_to_free); 268 + free(arg); 263 269 } 264 270 } 265 271 ··· 1105 1111 struct list_head *trailers, 1106 1112 struct strbuf *out) 1107 1113 { 1114 + struct strbuf tok = STRBUF_INIT; 1115 + struct strbuf val = STRBUF_INIT; 1108 1116 size_t origlen = out->len; 1109 1117 struct list_head *pos; 1110 1118 struct trailer_item *item; ··· 1112 1120 list_for_each(pos, trailers) { 1113 1121 item = list_entry(pos, struct trailer_item, list); 1114 1122 if (item->token) { 1115 - struct strbuf tok = STRBUF_INIT; 1116 - struct strbuf val = STRBUF_INIT; 1123 + strbuf_reset(&tok); 1117 1124 strbuf_addstr(&tok, item->token); 1125 + strbuf_reset(&val); 1118 1126 strbuf_addstr(&val, item->value); 1119 1127 1120 1128 /* ··· 1145 1153 if (!opts->separator) 1146 1154 strbuf_addch(out, '\n'); 1147 1155 } 1148 - strbuf_release(&tok); 1149 - strbuf_release(&val); 1150 - 1151 1156 } else if (!opts->only_trailers) { 1152 1157 if (opts->separator && out->len != origlen) { 1153 1158 strbuf_addbuf(out, opts->separator); ··· 1159 1164 strbuf_addch(out, '\n'); 1160 1165 } 1161 1166 } 1167 + 1168 + strbuf_release(&tok); 1169 + strbuf_release(&val); 1162 1170 } 1163 1171 1164 1172 void format_trailers_from_commit(const struct process_trailer_options *opts,
+2
transport-helper.c
··· 399 399 int res = 0; 400 400 struct helper_data *data = transport->data; 401 401 refspec_clear(&data->rs); 402 + free(data->import_marks); 403 + free(data->export_marks); 402 404 res = disconnect_helper(transport); 403 405 free(transport->data); 404 406 return res;
+1
upload-pack.c
··· 166 166 object_array_clear(&data->extra_edge_obj); 167 167 list_objects_filter_release(&data->filter_options); 168 168 string_list_clear(&data->allowed_filters, 0); 169 + string_list_clear(&data->uri_protocols, 0); 169 170 170 171 free((char *)data->pack_objects_hook); 171 172 }