config: clarify memory ownership in `git_config_string()`
The out parameter of `git_config_string()` is a `const char **` even though we transfer ownership of memory to the caller. This is quite misleading and has led to many memory leaks all over the place. Adapt the parameter to instead be `char **`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
May 27, 2024 at 13:46 UTC
1b261c20ed28ad26ddbcd3dff94a248ac6866ac8
30 files changed
+96
-92
alias.c
+1
-1
@@ -22,7 +22,7 @@ static int config_alias_cb(const char *key, const char *value,
22
23
if (data->alias) {
24
if (!strcasecmp(p, data->alias))
25
- return git_config_string((const char **)&data->v,
25
+ return git_config_string(&data->v,
26
key, value);
27
} else if (data->list) {
28
string_list_append(data->list, p);
attr.c
+1
-1
@@ -25,7 +25,7 @@
25
#include "tree-walk.h"
26
#include "object-name.h"
27
28
-const char *git_attr_tree;
28
+char *git_attr_tree;
29
30
const char git_attr__true[] = "(builtin)true";
31
const char git_attr__false[] = "\0(builtin)false";
attr.h
+1
-1
@@ -236,6 +236,6 @@ const char *git_attr_global_file(void);
236
/* Return whether the system gitattributes file is enabled and should be used. */
237
int git_attr_system_is_enabled(void);
238
239
-extern const char *git_attr_tree;
239
+extern char *git_attr_tree;
240
241
#endif /* ATTR_H */
builtin/commit.c
+1
-1
@@ -133,7 +133,7 @@ static struct strvec trailer_args = STRVEC_INIT;
133
* is specified explicitly.
134
*/
135
static enum commit_msg_cleanup_mode cleanup_mode;
136
-static const char *cleanup_arg;
136
+static char *cleanup_arg;
137
138
static enum commit_whence whence;
139
static int use_editor = 1, include_status = 1;
builtin/log.c
+6
-6
@@ -582,11 +582,11 @@ static int git_log_config(const char *var, const char *value,
582
583
if (!strcmp(var, "format.pretty")) {
584
FREE_AND_NULL(cfg->fmt_pretty);
585
- return git_config_string((const char **) &cfg->fmt_pretty, var, value);
585
+ return git_config_string(&cfg->fmt_pretty, var, value);
586
}
587
if (!strcmp(var, "format.subjectprefix")) {
588
FREE_AND_NULL(cfg->fmt_patch_subject_prefix);
589
- return git_config_string((const char **) &cfg->fmt_patch_subject_prefix, var, value);
589
+ return git_config_string(&cfg->fmt_patch_subject_prefix, var, value);
590
}
591
if (!strcmp(var, "format.filenamemaxlength")) {
592
cfg->fmt_patch_name_max = git_config_int(var, value, ctx->kvi);
@@ -602,7 +602,7 @@ static int git_log_config(const char *var, const char *value,
602
}
603
if (!strcmp(var, "log.date")) {
604
FREE_AND_NULL(cfg->default_date_mode);
605
- return git_config_string((const char **) &cfg->default_date_mode, var, value);
605
+ return git_config_string(&cfg->default_date_mode, var, value);
606
}
607
if (!strcmp(var, "log.decorate")) {
608
cfg->decoration_style = parse_decoration_style(value);
@@ -1076,7 +1076,7 @@ static int git_format_config(const char *var, const char *value,
1076
}
1077
if (!strcmp(var, "format.suffix")) {
1078
FREE_AND_NULL(cfg->fmt_patch_suffix);
1079
- return git_config_string((const char **) &cfg->fmt_patch_suffix, var, value);
1079
+ return git_config_string(&cfg->fmt_patch_suffix, var, value);
1080
}
1081
if (!strcmp(var, "format.to")) {
1082
if (!value)
@@ -1133,7 +1133,7 @@ static int git_format_config(const char *var, const char *value,
1133
}
1134
if (!strcmp(var, "format.signature")) {
1135
FREE_AND_NULL(cfg->signature);
1136
- return git_config_string((const char **) &cfg->signature, var, value);
1136
+ return git_config_string(&cfg->signature, var, value);
1137
}
1138
if (!strcmp(var, "format.signaturefile")) {
1139
FREE_AND_NULL(cfg->signature_file);
@@ -1149,7 +1149,7 @@ static int git_format_config(const char *var, const char *value,
1149
}
1150
if (!strcmp(var, "format.outputdirectory")) {
1151
FREE_AND_NULL(cfg->config_output_directory);
1152
- return git_config_string((const char **) &cfg->config_output_directory, var, value);
1152
+ return git_config_string(&cfg->config_output_directory, var, value);
1153
}
1154
if (!strcmp(var, "format.useautobase")) {
1155
if (value && !strcasecmp(value, "whenAble")) {
builtin/merge.c
+2
-2
@@ -100,7 +100,7 @@ static struct strategy all_strategy[] = {
100
{ "subtree", NO_FAST_FORWARD | NO_TRIVIAL },
101
};
102
103
-static const char *pull_twohead, *pull_octopus;
103
+static char *pull_twohead, *pull_octopus;
104
105
enum ff_type {
106
FF_NO,
@@ -110,7 +110,7 @@ enum ff_type {
110
111
static enum ff_type fast_forward = FF_ALLOW;
112
113
-static const char *cleanup_arg;
113
+static char *cleanup_arg;
114
static enum commit_msg_cleanup_mode cleanup_mode;
115
116
static int option_parse_message(const struct option *opt,
builtin/rebase.c
+1
-1
@@ -83,7 +83,7 @@ static const char *action_names[] = {
83
struct rebase_options {
84
enum rebase_type type;
85
enum empty_type empty;
86
- const char *default_backend;
86
+ char *default_backend;
87
const char *state_dir;
88
struct commit *upstream;
89
const char *upstream_name;
builtin/receive-pack.c
+1
-1
@@ -88,7 +88,7 @@ static struct strbuf push_cert = STRBUF_INIT;
88
static struct object_id push_cert_oid;
89
static struct signature_check sigcheck;
90
static const char *push_cert_nonce;
91
-static const char *cert_nonce_seed;
91
+static char *cert_nonce_seed;
92
static struct strvec hidden_refs = STRVEC_INIT;
93
94
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
builtin/repack.c
+4
-4
@@ -48,10 +48,10 @@ static const char incremental_bitmap_conflict_error[] = N_(
48
);
49
50
struct pack_objects_args {
51
- const char *window;
52
- const char *window_memory;
53
- const char *depth;
54
- const char *threads;
51
+ char *window;
52
+ char *window_memory;
53
+ char *depth;
54
+ char *threads;
55
unsigned long max_pack_size;
56
int no_reuse_delta;
57
int no_reuse_object;
config.c
+3
-3
@@ -1338,7 +1338,7 @@ int git_config_bool(const char *name, const char *value)
1338
return v;
1339
}
1340
1341
-int git_config_string(const char **dest, const char *var, const char *value)
1341
+int git_config_string(char **dest, const char *var, const char *value)
1342
{
1343
if (!value)
1344
return config_error_nonbool(var);
@@ -1566,7 +1566,7 @@ static int git_default_core_config(const char *var, const char *value,
1566
1567
if (!strcmp(var, "core.checkroundtripencoding")) {
1568
FREE_AND_NULL(check_roundtrip_encoding);
1569
- return git_config_string((const char **) &check_roundtrip_encoding, var, value);
1569
+ return git_config_string(&check_roundtrip_encoding, var, value);
1570
}
1571
1572
if (!strcmp(var, "core.notesref")) {
@@ -2418,7 +2418,7 @@ int git_configset_get_string(struct config_set *set, const char *key, char **des
2418
{
2419
const char *value;
2420
if (!git_configset_get_value(set, key, &value, NULL))
2421
- return git_config_string((const char **)dest, key, value);
2421
+ return git_config_string(dest, key, value);
2422
else
2423
return 1;
2424
}
config.h
+1
-1
@@ -280,7 +280,7 @@ int git_config_bool(const char *, const char *);
280
* Allocates and copies the value string into the `dest` parameter; if no
281
* string is given, prints an error message and returns -1.
282
*/
283
-int git_config_string(const char **, const char *, const char *);
283
+int git_config_string(char **, const char *, const char *);
284
285
/**
286
* Similar to `git_config_string`, but expands `~` or `~user` into the
convert.c
+3
-3
@@ -981,9 +981,9 @@ done:
981
static struct convert_driver {
982
const char *name;
983
struct convert_driver *next;
984
- const char *smudge;
985
- const char *clean;
986
- const char *process;
984
+ char *smudge;
985
+ char *clean;
986
+ char *process;
987
int required;
988
} *user_convert, **user_convert_tail;
989
delta-islands.c
+1
-1
@@ -313,7 +313,7 @@ struct island_load_data {
313
size_t nr;
314
size_t alloc;
315
};
316
-static const char *core_island_name;
316
+static char *core_island_name;
317
318
static void free_config_regexes(struct island_load_data *ild)
319
{
diff.c
+4
-4
@@ -56,8 +56,8 @@ static int diff_color_moved_default;
56
static int diff_color_moved_ws_default;
57
static int diff_context_default = 3;
58
static int diff_interhunk_context_default;
59
-static const char *diff_word_regex_cfg;
60
-static const char *external_diff_cmd_cfg;
59
+static char *diff_word_regex_cfg;
60
+static char *external_diff_cmd_cfg;
61
static char *diff_order_file_cfg;
62
int diff_auto_refresh_index = 1;
63
static int diff_mnemonic_prefix;
@@ -412,11 +412,11 @@ int git_diff_ui_config(const char *var, const char *value,
412
}
413
if (!strcmp(var, "diff.srcprefix")) {
414
FREE_AND_NULL(diff_src_prefix);
415
- return git_config_string((const char **) &diff_src_prefix, var, value);
415
+ return git_config_string(&diff_src_prefix, var, value);
416
}
417
if (!strcmp(var, "diff.dstprefix")) {
418
FREE_AND_NULL(diff_dst_prefix);
419
- return git_config_string((const char **) &diff_dst_prefix, var, value);
419
+ return git_config_string(&diff_dst_prefix, var, value);
420
}
421
if (!strcmp(var, "diff.relative")) {
422
diff_relative = git_config_bool(var, value);
environment.c
+4
-4
@@ -42,8 +42,8 @@ int is_bare_repository_cfg = -1; /* unspecified */
42
int warn_ambiguous_refs = 1;
43
int warn_on_object_refname_ambiguity = 1;
44
int repository_format_precious_objects;
45
-const char *git_commit_encoding;
46
-const char *git_log_output_encoding;
45
+char *git_commit_encoding;
46
+char *git_log_output_encoding;
47
char *apply_default_whitespace;
48
char *apply_default_ignorewhitespace;
49
char *git_attributes_file;
@@ -58,8 +58,8 @@ size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE;
58
size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT;
59
size_t delta_base_cache_limit = 96 * 1024 * 1024;
60
unsigned long big_file_threshold = 512 * 1024 * 1024;
61
-const char *editor_program;
62
-const char *askpass_program;
61
+char *editor_program;
62
+char *askpass_program;
63
char *excludes_file;
64
enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
65
enum eol core_eol = EOL_UNSET;
environment.h
+4
-4
@@ -224,11 +224,11 @@ int odb_pack_keep(const char *name);
224
const char *get_log_output_encoding(void);
225
const char *get_commit_output_encoding(void);
226
227
-extern const char *git_commit_encoding;
228
-extern const char *git_log_output_encoding;
227
+extern char *git_commit_encoding;
228
+extern char *git_log_output_encoding;
229
230
-extern const char *editor_program;
231
-extern const char *askpass_program;
230
+extern char *editor_program;
231
+extern char *askpass_program;
232
extern char *excludes_file;
233
234
/*
gpg-interface.c
+2
-2
@@ -27,14 +27,14 @@ static void gpg_interface_lazy_init(void)
27
}
28
29
static char *configured_signing_key;
30
-static const char *ssh_default_key_command;
30
+static char *ssh_default_key_command;
31
static char *ssh_allowed_signers;
32
static char *ssh_revocation_file;
33
static enum signature_trust_level configured_min_trust_level = TRUST_UNDEFINED;
34
35
struct gpg_format {
36
const char *name;
37
- const char *program;
37
+ char *program;
38
const char **verify_args;
39
const char **sigs;
40
int (*verify_signed_buffer)(struct signature_check *sigc,
http.c
+12
-12
@@ -38,11 +38,11 @@ char curl_errorstr[CURL_ERROR_SIZE];
38
39
static int curl_ssl_verify = -1;
40
static int curl_ssl_try;
41
-static const char *curl_http_version = NULL;
41
+static char *curl_http_version;
42
static char *ssl_cert;
43
static char *ssl_cert_type;
44
-static const char *ssl_cipherlist;
45
-static const char *ssl_version;
44
+static char *ssl_cipherlist;
45
+static char *ssl_version;
46
static struct {
47
const char *name;
48
long ssl_version;
@@ -95,7 +95,7 @@ static struct {
95
*/
96
};
97
#ifdef CURLGSSAPI_DELEGATION_FLAG
98
-static const char *curl_deleg;
98
+static char *curl_deleg;
99
static struct {
100
const char *name;
101
long curl_deleg_param;
@@ -383,11 +383,11 @@ static int http_options(const char *var, const char *value,
383
if (!strcmp("http.sslcert", var))
384
return git_config_pathname(&ssl_cert, var, value);
385
if (!strcmp("http.sslcerttype", var))
386
- return git_config_string((const char **)&ssl_cert_type, var, value);
386
+ return git_config_string(&ssl_cert_type, var, value);
387
if (!strcmp("http.sslkey", var))
388
return git_config_pathname(&ssl_key, var, value);
389
if (!strcmp("http.sslkeytype", var))
390
- return git_config_string((const char **)&ssl_key_type, var, value);
390
+ return git_config_string(&ssl_key_type, var, value);
391
if (!strcmp("http.sslcapath", var))
392
return git_config_pathname(&ssl_capath, var, value);
393
if (!strcmp("http.sslcainfo", var))
@@ -440,19 +440,19 @@ static int http_options(const char *var, const char *value,
440
return 0;
441
}
442
if (!strcmp("http.proxy", var))
443
- return git_config_string((const char **)&curl_http_proxy, var, value);
443
+ return git_config_string(&curl_http_proxy, var, value);
444
445
if (!strcmp("http.proxyauthmethod", var))
446
- return git_config_string((const char **)&http_proxy_authmethod, var, value);
446
+ return git_config_string(&http_proxy_authmethod, var, value);
447
448
if (!strcmp("http.proxysslcert", var))
449
- return git_config_string((const char **)&http_proxy_ssl_cert, var, value);
449
+ return git_config_string(&http_proxy_ssl_cert, var, value);
450
451
if (!strcmp("http.proxysslkey", var))
452
- return git_config_string((const char **)&http_proxy_ssl_key, var, value);
452
+ return git_config_string(&http_proxy_ssl_key, var, value);
453
454
if (!strcmp("http.proxysslcainfo", var))
455
- return git_config_string((const char **)&http_proxy_ssl_ca_info, var, value);
455
+ return git_config_string(&http_proxy_ssl_ca_info, var, value);
456
457
if (!strcmp("http.proxysslcertpasswordprotected", var)) {
458
proxy_ssl_cert_password_required = git_config_bool(var, value);
@@ -476,7 +476,7 @@ static int http_options(const char *var, const char *value,
476
}
477
478
if (!strcmp("http.useragent", var))
479
- return git_config_string((const char **)&user_agent, var, value);
479
+ return git_config_string(&user_agent, var, value);
480
481
if (!strcmp("http.emptyauth", var)) {
482
if (value && !strcmp("auto", value))
imap-send.c
+6
-6
@@ -70,16 +70,16 @@ static char *next_arg(char **);
70
71
struct imap_server_conf {
72
const char *name;
73
- const char *tunnel;
74
- const char *host;
73
+ char *tunnel;
74
+ char *host;
75
int port;
76
- const char *folder;
77
- const char *user;
78
- const char *pass;
76
+ char *folder;
77
+ char *user;
78
+ char *pass;
79
int use_ssl;
80
int ssl_verify;
81
int use_html;
82
- const char *auth_method;
82
+ char *auth_method;
83
};
84
85
static struct imap_server_conf server = {
mailmap.c
+1
-1
@@ -7,7 +7,7 @@
7
#include "setup.h"
8
9
char *git_mailmap_file;
10
-const char *git_mailmap_blob;
10
+char *git_mailmap_blob;
11
12
struct mailmap_info {
13
char *name;
mailmap.h
+1
-1
@@ -4,7 +4,7 @@
4
struct string_list;
5
6
extern char *git_mailmap_file;
7
-extern const char *git_mailmap_blob;
7
+extern char *git_mailmap_blob;
8
9
int read_mailmap(struct string_list *map);
10
void clear_mailmap(struct string_list *map);
merge-ll.c
+3
-3
@@ -27,9 +27,9 @@ typedef enum ll_merge_result (*ll_merge_fn)(const struct ll_merge_driver *,
27
28
struct ll_merge_driver {
29
const char *name;
30
- const char *description;
30
+ char *description;
31
ll_merge_fn fn;
32
- const char *recursive;
32
+ char *recursive;
33
struct ll_merge_driver *next;
34
char *cmdline;
35
};
@@ -268,7 +268,7 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
268
* merge.default and merge.driver configuration items
269
*/
270
static struct ll_merge_driver *ll_user_merge, **ll_user_merge_tail;
271
-static const char *default_ll_merge;
271
+static char *default_ll_merge;
272
273
static int read_merge_config(const char *var, const char *value,
274
const struct config_context *ctx UNUSED,
pager.c
+1
-1
@@ -13,7 +13,7 @@ int pager_use_color = 1;
13
#endif
14
15
static struct child_process pager_process;
16
-static const char *pager_program;
16
+static char *pager_program;
17
18
/* Is the value coming back from term_columns() just a guess? */
19
static int term_columns_guessed;
pretty.c
+9
-5
@@ -62,7 +62,7 @@ static int git_pretty_formats_config(const char *var, const char *value,
62
{
63
struct cmt_fmt_map *commit_format = NULL;
64
const char *name;
65
- const char *fmt;
65
+ char *fmt;
66
int i;
67
68
if (!skip_prefix(var, "pretty.", &name))
@@ -93,13 +93,17 @@ static int git_pretty_formats_config(const char *var, const char *value,
93
if (git_config_string(&fmt, var, value))
94
return -1;
95
96
- if (skip_prefix(fmt, "format:", &fmt))
96
+ if (skip_prefix(fmt, "format:", &commit_format->user_format)) {
97
commit_format->is_tformat = 0;
98
- else if (skip_prefix(fmt, "tformat:", &fmt) || strchr(fmt, '%'))
98
+ } else if (skip_prefix(fmt, "tformat:", &commit_format->user_format)) {
99
commit_format->is_tformat = 1;
100
- else
100
+ } else if (strchr(fmt, '%')) {
101
+ commit_format->is_tformat = 1;
102
+ commit_format->user_format = fmt;
103
+ } else {
104
commit_format->is_alias = 1;
102
- commit_format->user_format = fmt;
105
+ commit_format->user_format = fmt;
106
+ }
107
108
return 0;
109
}
promisor-remote.h
+1
-1
@@ -13,7 +13,7 @@ struct object_id;
13
*/
14
struct promisor_remote {
15
struct promisor_remote *next;
16
- const char *partial_clone_filter;
16
+ char *partial_clone_filter;
17
const char name[FLEX_ARRAY];
18
};
19
remote.c
+10
-10
@@ -428,29 +428,29 @@ static int handle_config(const char *key, const char *value,
428
else if (!strcmp(subkey, "prunetags"))
429
remote->prune_tags = git_config_bool(key, value);
430
else if (!strcmp(subkey, "url")) {
431
- const char *v;
431
+ char *v;
432
if (git_config_string(&v, key, value))
433
return -1;
434
add_url(remote, v);
435
} else if (!strcmp(subkey, "pushurl")) {
436
- const char *v;
436
+ char *v;
437
if (git_config_string(&v, key, value))
438
return -1;
439
add_pushurl(remote, v);
440
} else if (!strcmp(subkey, "push")) {
441
- const char *v;
441
+ char *v;
442
if (git_config_string(&v, key, value))
443
return -1;
444
refspec_append(&remote->push, v);
445
- free((char *)v);
445
+ free(v);
446
} else if (!strcmp(subkey, "fetch")) {
447
- const char *v;
447
+ char *v;
448
if (git_config_string(&v, key, value))
449
return -1;
450
refspec_append(&remote->fetch, v);
451
- free((char *)v);
451
+ free(v);
452
} else if (!strcmp(subkey, "receivepack")) {
453
- const char *v;
453
+ char *v;
454
if (git_config_string(&v, key, value))
455
return -1;
456
if (!remote->receivepack)
@@ -458,7 +458,7 @@ static int handle_config(const char *key, const char *value,
458
else
459
error(_("more than one receivepack given, using the first"));
460
} else if (!strcmp(subkey, "uploadpack")) {
461
- const char *v;
461
+ char *v;
462
if (git_config_string(&v, key, value))
463
return -1;
464
if (!remote->uploadpack)
@@ -471,10 +471,10 @@ static int handle_config(const char *key, const char *value,
471
else if (!strcmp(value, "--tags"))
472
remote->fetch_tags = 2;
473
} else if (!strcmp(subkey, "proxy")) {
474
- return git_config_string((const char **)&remote->http_proxy,
474
+ return git_config_string(&remote->http_proxy,
475
key, value);
476
} else if (!strcmp(subkey, "proxyauthmethod")) {
477
- return git_config_string((const char **)&remote->http_proxy_authmethod,
477
+ return git_config_string(&remote->http_proxy_authmethod,
478
key, value);
479
} else if (!strcmp(subkey, "vcs")) {
480
return git_config_string(&remote->foreign_vcs, key, value);
remote.h
+4
-4
@@ -46,7 +46,7 @@ struct remote_state {
46
struct hashmap branches_hash;
47
48
struct branch *current_branch;
49
- const char *pushremote_name;
49
+ char *pushremote_name;
50
51
struct rewrites rewrites;
52
struct rewrites rewrites_push;
@@ -65,7 +65,7 @@ struct remote {
65
66
int origin, configured_in_repo;
67
68
- const char *foreign_vcs;
68
+ char *foreign_vcs;
69
70
/* An array of all of the url_nr URLs configured for the remote */
71
const char **url;
@@ -309,9 +309,9 @@ struct branch {
309
const char *refname;
310
311
/* The name of the remote listed in the configuration. */
312
- const char *remote_name;
312
+ char *remote_name;
313
314
- const char *pushremote_name;
314
+ char *pushremote_name;
315
316
/* An array of the "merge" lines in the configuration. */
317
const char **merge_name;
sequencer.c
+1
-1
@@ -306,7 +306,7 @@ static int git_sequencer_config(const char *k, const char *v,
306
}
307
308
if (!opts->default_strategy && !strcmp(k, "pull.twohead")) {
309
- int ret = git_config_string((const char**)&opts->default_strategy, k, v);
309
+ int ret = git_config_string(&opts->default_strategy, k, v);
310
if (ret == 0) {
311
/*
312
* pull.twohead is allowed to be multi-valued; we only
upload-pack.c
+1
-1
@@ -94,7 +94,7 @@ struct upload_pack_data {
94
95
struct packet_writer writer;
96
97
- const char *pack_objects_hook;
97
+ char *pack_objects_hook;
98
99
unsigned stateless_rpc : 1; /* v0 only */
100
unsigned no_done : 1; /* v0 only */
userdiff.h
+6
-6
@@ -7,19 +7,19 @@ struct index_state;
7
struct repository;
8
9
struct userdiff_funcname {
10
- const char *pattern;
10
+ char *pattern;
11
int cflags;
12
};
13
14
struct userdiff_driver {
15
const char *name;
16
- const char *external;
17
- const char *algorithm;
16
+ char *external;
17
+ char *algorithm;
18
int binary;
19
struct userdiff_funcname funcname;
20
- const char *word_regex;
21
- const char *word_regex_multi_byte;
22
- const char *textconv;
20
+ char *word_regex;
21
+ char *word_regex_multi_byte;
22
+ char *textconv;
23
struct notes_cache *textconv_cache;
24
int textconv_want_cache;
25
};