Skip to content

Commit bd1a32d

Browse files
committed
Merge branch 'jk/fsck-gitmodules-gently'
Recent "security fix" to pay attention to contents of ".gitmodules" while accepting "git push" was a bit overly strict than necessary, which has been adjusted. * jk/fsck-gitmodules-gently: fsck: downgrade gitmodulesParse default to "info" fsck: split ".gitmodules too large" error from parse failure fsck: silence stderr when parsing .gitmodules config: add options parameter to git_config_from_mem config: add CONFIG_ERROR_SILENT handler config: turn die_on_error into caller-facing enum
2 parents 37aac3e + 64eb14d commit bd1a32d

File tree

5 files changed

+56
-15
lines changed

5 files changed

+56
-15
lines changed

config.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct config_source {
3232
enum config_origin_type origin_type;
3333
const char *name;
3434
const char *path;
35-
int die_on_error;
35+
enum config_error_action default_error_action;
3636
int linenr;
3737
int eof;
3838
struct strbuf value;
@@ -810,10 +810,21 @@ static int git_parse_source(config_fn_t fn, void *data,
810810
cf->linenr, cf->name);
811811
}
812812

813-
if (cf->die_on_error)
813+
switch (opts && opts->error_action ?
814+
opts->error_action :
815+
cf->default_error_action) {
816+
case CONFIG_ERROR_DIE:
814817
die("%s", error_msg);
815-
else
818+
break;
819+
case CONFIG_ERROR_ERROR:
816820
error_return = error("%s", error_msg);
821+
break;
822+
case CONFIG_ERROR_SILENT:
823+
error_return = -1;
824+
break;
825+
case CONFIG_ERROR_UNSET:
826+
BUG("config error action unset");
827+
}
817828

818829
free(error_msg);
819830
return error_return;
@@ -1521,7 +1532,7 @@ static int do_config_from_file(config_fn_t fn,
15211532
top.origin_type = origin_type;
15221533
top.name = name;
15231534
top.path = path;
1524-
top.die_on_error = 1;
1535+
top.default_error_action = CONFIG_ERROR_DIE;
15251536
top.do_fgetc = config_file_fgetc;
15261537
top.do_ungetc = config_file_ungetc;
15271538
top.do_ftell = config_file_ftell;
@@ -1559,8 +1570,10 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
15591570
return git_config_from_file_with_options(fn, filename, data, NULL);
15601571
}
15611572

1562-
int git_config_from_mem(config_fn_t fn, const enum config_origin_type origin_type,
1563-
const char *name, const char *buf, size_t len, void *data)
1573+
int git_config_from_mem(config_fn_t fn,
1574+
const enum config_origin_type origin_type,
1575+
const char *name, const char *buf, size_t len,
1576+
void *data, const struct config_options *opts)
15641577
{
15651578
struct config_source top;
15661579

@@ -1570,12 +1583,12 @@ int git_config_from_mem(config_fn_t fn, const enum config_origin_type origin_typ
15701583
top.origin_type = origin_type;
15711584
top.name = name;
15721585
top.path = NULL;
1573-
top.die_on_error = 0;
1586+
top.default_error_action = CONFIG_ERROR_ERROR;
15741587
top.do_fgetc = config_buf_fgetc;
15751588
top.do_ungetc = config_buf_ungetc;
15761589
top.do_ftell = config_buf_ftell;
15771590

1578-
return do_config_from(&top, fn, data, NULL);
1591+
return do_config_from(&top, fn, data, opts);
15791592
}
15801593

15811594
int git_config_from_blob_oid(config_fn_t fn,
@@ -1596,7 +1609,8 @@ int git_config_from_blob_oid(config_fn_t fn,
15961609
return error("reference '%s' does not point to a blob", name);
15971610
}
15981611

1599-
ret = git_config_from_mem(fn, CONFIG_ORIGIN_BLOB, name, buf, size, data);
1612+
ret = git_config_from_mem(fn, CONFIG_ORIGIN_BLOB, name, buf, size,
1613+
data, NULL);
16001614
free(buf);
16011615

16021616
return ret;

config.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ struct config_options {
5454
const char *git_dir;
5555
config_parser_event_fn_t event_fn;
5656
void *event_fn_data;
57+
enum config_error_action {
58+
CONFIG_ERROR_UNSET = 0, /* use source-specific default */
59+
CONFIG_ERROR_DIE, /* die() on error */
60+
CONFIG_ERROR_ERROR, /* error() on error, return -1 */
61+
CONFIG_ERROR_SILENT, /* return -1 */
62+
} error_action;
5763
};
5864

5965
typedef int (*config_fn_t)(const char *, const char *, void *);
@@ -62,8 +68,11 @@ extern int git_config_from_file(config_fn_t fn, const char *, void *);
6268
extern int git_config_from_file_with_options(config_fn_t fn, const char *,
6369
void *,
6470
const struct config_options *);
65-
extern int git_config_from_mem(config_fn_t fn, const enum config_origin_type,
66-
const char *name, const char *buf, size_t len, void *data);
71+
extern int git_config_from_mem(config_fn_t fn,
72+
const enum config_origin_type,
73+
const char *name,
74+
const char *buf, size_t len,
75+
void *data, const struct config_options *opts);
6776
extern int git_config_from_blob_oid(config_fn_t fn, const char *name,
6877
const struct object_id *oid, void *data);
6978
extern void git_config_push_parameter(const char *text);

fsck.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static struct oidset gitmodules_done = OIDSET_INIT;
6363
FUNC(ZERO_PADDED_DATE, ERROR) \
6464
FUNC(GITMODULES_MISSING, ERROR) \
6565
FUNC(GITMODULES_BLOB, ERROR) \
66-
FUNC(GITMODULES_PARSE, ERROR) \
66+
FUNC(GITMODULES_LARGE, ERROR) \
6767
FUNC(GITMODULES_NAME, ERROR) \
6868
FUNC(GITMODULES_SYMLINK, ERROR) \
6969
/* warnings */ \
@@ -77,6 +77,7 @@ static struct oidset gitmodules_done = OIDSET_INIT;
7777
FUNC(ZERO_PADDED_FILEMODE, WARN) \
7878
FUNC(NUL_IN_COMMIT, WARN) \
7979
/* infos (reported as warnings, but ignored by default) */ \
80+
FUNC(GITMODULES_PARSE, INFO) \
8081
FUNC(BAD_TAG_NAME, INFO) \
8182
FUNC(MISSING_TAGGER_ENTRY, INFO)
8283

@@ -999,6 +1000,7 @@ static int fsck_blob(struct blob *blob, const char *buf,
9991000
unsigned long size, struct fsck_options *options)
10001001
{
10011002
struct fsck_gitmodules_data data;
1003+
struct config_options config_opts = { 0 };
10021004

10031005
if (!oidset_contains(&gitmodules_found, &blob->object.oid))
10041006
return 0;
@@ -1014,15 +1016,16 @@ static int fsck_blob(struct blob *blob, const char *buf,
10141016
* that an error.
10151017
*/
10161018
return report(options, &blob->object,
1017-
FSCK_MSG_GITMODULES_PARSE,
1019+
FSCK_MSG_GITMODULES_LARGE,
10181020
".gitmodules too large to parse");
10191021
}
10201022

10211023
data.obj = &blob->object;
10221024
data.options = options;
10231025
data.ret = 0;
1026+
config_opts.error_action = CONFIG_ERROR_SILENT;
10241027
if (git_config_from_mem(fsck_gitmodules_fn, CONFIG_ORIGIN_BLOB,
1025-
".gitmodules", buf, size, &data))
1028+
".gitmodules", buf, size, &data, &config_opts))
10261029
data.ret |= report(options, &blob->object,
10271030
FSCK_MSG_GITMODULES_PARSE,
10281031
"could not parse gitmodules blob");

submodule-config.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ static const struct submodule *config_from(struct submodule_cache *cache,
562562
parameter.gitmodules_oid = &oid;
563563
parameter.overwrite = 0;
564564
git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,
565-
config, config_size, &parameter);
565+
config, config_size, &parameter, NULL);
566566
strbuf_release(&rev);
567567
free(config);
568568

t/t7415-submodule-names.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,19 @@ test_expect_success 'fsck detects non-blob .gitmodules' '
176176
)
177177
'
178178

179+
test_expect_success 'fsck detects corrupt .gitmodules' '
180+
git init corrupt &&
181+
(
182+
cd corrupt &&
183+
184+
echo "[broken" >.gitmodules &&
185+
git add .gitmodules &&
186+
git commit -m "broken gitmodules" &&
187+
188+
git fsck 2>output &&
189+
grep gitmodulesParse output &&
190+
test_i18ngrep ! "bad config" output
191+
)
192+
'
193+
179194
test_done

0 commit comments

Comments
 (0)