From: Timo Sirainen Date: Fri, 7 Aug 2015 12:32:14 +0000 (+0300) Subject: lib-master: Make sure we can't accidentally add duplicate getopt args. X-Git-Tag: 2.2.19.rc1~269 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9b0f6b90ff8d1d6efd718b0d7cbe01b2454e9fd6;p=thirdparty%2Fdovecot%2Fcore.git lib-master: Make sure we can't accidentally add duplicate getopt args. --- diff --git a/src/lib-master/master-service.c b/src/lib-master/master-service.c index 93b1527b9a..fa2d74ced9 100644 --- a/src/lib-master/master-service.c +++ b/src/lib-master/master-service.c @@ -251,6 +251,8 @@ int master_getopt(struct master_service *service) { int c; + i_assert(master_getopt_str_is_valid(service->getopt_str)); + while ((c = getopt(service->argc, service->argv, service->getopt_str)) > 0) { if (!master_service_parse_option(service, c, optarg)) @@ -259,6 +261,23 @@ int master_getopt(struct master_service *service) return c; } +bool master_getopt_str_is_valid(const char *str) +{ + unsigned int i, j; + + /* make sure there are no duplicates. there are few enough characters + that this should be fast enough. */ + for (i = 0; str[i] != '\0'; i++) { + if (str[i] == ':' || str[i] == '+' || str[i] == '-') + continue; + for (j = i+1; str[j] != '\0'; j++) { + if (str[i] == str[j]) + return FALSE; + } + } + return TRUE; +} + void master_service_init_log(struct master_service *service, const char *prefix) { diff --git a/src/lib-master/master-service.h b/src/lib-master/master-service.h index 45470b0c8d..27aad5365d 100644 --- a/src/lib-master/master-service.h +++ b/src/lib-master/master-service.h @@ -63,6 +63,9 @@ master_service_init(const char *name, enum master_service_flags flags, /* Call getopt() and handle internal parameters. Return values are the same as getopt()'s. */ int master_getopt(struct master_service *service); +/* Returns TRUE if str is a valid getopt_str. Currently this only checks for + duplicate args so they aren't accidentally added. */ +bool master_getopt_str_is_valid(const char *str); /* Parser command line option. Returns TRUE if processed. */ bool master_service_parse_option(struct master_service *service, int opt, const char *arg);