From: Emily Shaffer <emilyshaffer@xxxxxxxxxx> Teach bugreport to gather the values of config options which are present in 'bugreport-config-safelist.h'. Many config options are sensitive, and many Git add-ons use config options which git-core does not know about; it is better only to gather config options which we know to be safe, rather than excluding options which we know to be unsafe. Taking the build-time generated array and putting it into a set saves us time - since git_config_bugreport() is called for every option the user has configured, performing option lookup in constant time is a useful optimization. Signed-off-by: Emily Shaffer <emilyshaffer@xxxxxxxxxx> --- Makefile | 2 +- bugreport.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2bc9f112ea..eb17ece120 100644 --- a/Makefile +++ b/Makefile @@ -2465,7 +2465,7 @@ endif git-%$X: %.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) -git-bugreport$X: bugreport.o GIT-LDFLAGS $(GITLIBS) +git-bugreport$X: bugreport-config-safelist.h bugreport.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \ $(LIBS) diff --git a/bugreport.c b/bugreport.c index 07b84b9c94..7a9fd36b60 100644 --- a/bugreport.c +++ b/bugreport.c @@ -6,6 +6,9 @@ #include "help.h" #include "compat/compiler.h" #include "run-command.h" +#include "config.h" +#include "bugreport-config-safelist.h" +#include "khash.h" static void get_curl_version_info(struct strbuf *curl_info) { @@ -18,6 +21,40 @@ static void get_curl_version_info(struct strbuf *curl_info) strbuf_addstr(curl_info, "'git-remote-https --build-info' not supported\n"); } +KHASH_INIT(cfg_set, const char*, int, 0, kh_str_hash_func, kh_str_hash_equal); + +struct cfgset { + kh_cfg_set_t set; +}; + +struct cfgset safelist; + +static void cfgset_init(struct cfgset *set, size_t initial_size) +{ + memset(&set->set, 0, sizeof(set->set)); + if (initial_size) + kh_resize_cfg_set(&set->set, initial_size); +} + +static int cfgset_insert(struct cfgset *set, const char *cfg_key) +{ + int added; + kh_put_cfg_set(&set->set, cfg_key, &added); + return !added; +} + +static int cfgset_contains(struct cfgset *set, const char *cfg_key) +{ + khiter_t pos = kh_get_cfg_set(&set->set, cfg_key); + return pos != kh_end(&set->set); +} + +static void cfgset_clear(struct cfgset *set) +{ + kh_release_cfg_set(&set->set); + cfgset_init(set, 0); +} + static void get_system_info(struct strbuf *sys_info) { struct strbuf version_info = STRBUF_INIT; @@ -54,6 +91,36 @@ static void get_system_info(struct strbuf *sys_info) strbuf_complete_line(sys_info); } +static void gather_safelist(void) +{ + int index; + int safelist_len = sizeof(bugreport_config_safelist) / sizeof(const char *); + cfgset_init(&safelist, safelist_len); + for (index = 0; index < safelist_len; index++) + cfgset_insert(&safelist, bugreport_config_safelist[index]); + +} + +static int git_config_bugreport(const char *var, const char *value, void *cb) +{ + struct strbuf *config_info = (struct strbuf *)cb; + + if (cfgset_contains(&safelist, var)) + strbuf_addf(config_info, + "%s (%s) : %s\n", + var, config_scope_to_string(current_config_scope()), + value); + + return 0; +} + +static void get_safelisted_config(struct strbuf *config_info) +{ + gather_safelist(); + git_config(git_config_bugreport, config_info); + cfgset_clear(&safelist); +} + static const char * const bugreport_usage[] = { N_("git bugreport [-o|--output <file>]"), NULL @@ -94,12 +161,17 @@ int cmd_main(int argc, const char **argv) FILE *report; time_t now = time(NULL); char *option_output = NULL; + int nongit_ok = 0; const struct option bugreport_options[] = { OPT_STRING('o', "output", &option_output, N_("path"), N_("specify a destination for the bugreport file")), OPT_END() }; + + /* Prerequisite for hooks and config checks */ + setup_git_directory_gently(&nongit_ok); + argc = parse_options(argc, argv, "", bugreport_options, bugreport_usage, 0); @@ -118,6 +190,9 @@ int cmd_main(int argc, const char **argv) get_header(&buffer, "System Info"); get_system_info(&buffer); + get_header(&buffer, "Safelisted Config Info"); + get_safelisted_config(&buffer); + report = fopen_for_writing(report_path.buf); strbuf_write(&buffer, report); fclose(report); -- 2.25.0.341.g760bfbb309-goog