fsck: handle NULL value when parsing message config

When parsing fsck.*, receive.fsck.*, or fetch.fsck.*, we don't check for an implicit bool. So any of: [fsck] badTree [receive "fsck"] badTree [fetch "fsck"] badTree will cause us to segfault. We can fix it with config_error_nonbool() in the usual way, but we have to make a few more changes to get good error messages. The problem is that all three spots do: if (skip_prefix(var, "fsck.", &var)) to match and parse the actual message id. But that means that "var" now just says "badTree" instead of "receive.fsck.badTree", making the resulting message confusing. We can fix that by storing the parsed message id in its own separate variable. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Dec 7, 2023 at 02:11 UTC d49cb162fa752d62cf20548ae057471d348e42ae
3 files changed +21 -10
builtin/receive-pack.c
+7 -4
@@ -142,6 +142,7 @@ static enum deny_action parse_deny_action(const char *var, const char *value)
142 static int receive_pack_config(const char *var, const char *value,
143 const struct config_context *ctx, void *cb)
144 {
145 + const char *msg_id;
146 int status = parse_hide_refs_config(var, value, "receive", &hidden_refs);
147
148 if (status)
@@ -178,12 +179,14 @@ static int receive_pack_config(const char *var, const char *value,
179 return 0;
180 }
181
181 - if (skip_prefix(var, "receive.fsck.", &var)) {
182 - if (is_valid_msg_type(var, value))
182 + if (skip_prefix(var, "receive.fsck.", &msg_id)) {
183 + if (!value)
184 + return config_error_nonbool(var);
185 + if (is_valid_msg_type(msg_id, value))
186 strbuf_addf(&fsck_msg_types, "%c%s=%s",
184 - fsck_msg_types.len ? ',' : '=', var, value);
187 + fsck_msg_types.len ? ',' : '=', msg_id, value);
188 else
186 - warning("skipping unknown msg id '%s'", var);
189 + warning("skipping unknown msg id '%s'", msg_id);
190 return 0;
191 }
192
fetch-pack.c
+8 -4
@@ -1862,6 +1862,8 @@ static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
1862 static int fetch_pack_config_cb(const char *var, const char *value,
1863 const struct config_context *ctx, void *cb)
1864 {
1865 + const char *msg_id;
1866 +
1867 if (strcmp(var, "fetch.fsck.skiplist") == 0) {
1868 const char *path;
1869
@@ -1873,12 +1875,14 @@ static int fetch_pack_config_cb(const char *var, const char *value,
1875 return 0;
1876 }
1877
1876 - if (skip_prefix(var, "fetch.fsck.", &var)) {
1877 - if (is_valid_msg_type(var, value))
1878 + if (skip_prefix(var, "fetch.fsck.", &msg_id)) {
1879 + if (!value)
1880 + return config_error_nonbool(var);
1881 + if (is_valid_msg_type(msg_id, value))
1882 strbuf_addf(&fsck_msg_types, "%c%s=%s",
1879 - fsck_msg_types.len ? ',' : '=', var, value);
1883 + fsck_msg_types.len ? ',' : '=', msg_id, value);
1884 else
1881 - warning("Skipping unknown msg id '%s'", var);
1885 + warning("Skipping unknown msg id '%s'", msg_id);
1886 return 0;
1887 }
1888
fsck.c
+6 -2
@@ -1403,6 +1403,8 @@ int git_fsck_config(const char *var, const char *value,
1403 const struct config_context *ctx, void *cb)
1404 {
1405 struct fsck_options *options = cb;
1406 + const char *msg_id;
1407 +
1408 if (strcmp(var, "fsck.skiplist") == 0) {
1409 const char *path;
1410 struct strbuf sb = STRBUF_INIT;
@@ -1416,8 +1418,10 @@ int git_fsck_config(const char *var, const char *value,
1418 return 0;
1419 }
1420
1419 - if (skip_prefix(var, "fsck.", &var)) {
1420 - fsck_set_msg_type(options, var, value);
1421 + if (skip_prefix(var, "fsck.", &msg_id)) {
1422 + if (!value)
1423 + return config_error_nonbool(var);
1424 + fsck_set_msg_type(options, msg_id, value);
1425 return 0;
1426 }
1427