From ac8ff00502eeb02786dbdb3b049313fa36df210c Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 6 Apr 2009 15:38:30 -0700 Subject: [PATCH] cfg: Prevent infinite loop in cfg_del_section(). When the last entry in the file was deleted, cfg_del_section() would loop forever because *p was never set to NULL by svec_del(). (Alternatively, it could segfault because we were accessing freed memory.) This better implementation is also O(N) instead of O(N**2). --- lib/cfg.c | 13 ++++++------- lib/svec.c | 13 +++++++++++++ lib/svec.h | 1 + 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/lib/cfg.c b/lib/cfg.c index 916cb932..4495f670 100644 --- a/lib/cfg.c +++ b/lib/cfg.c @@ -526,16 +526,15 @@ cfg_del_section(const char *section_, ...) ds_put_char(§ion, '.'); va_end(args); - for (p = cfg.names; *p; ) { /* XXX this is inefficient */ + for (p = cfg.names; *p; p++) { if (!strncmp(section.string, *p, section.length)) { - /* Delete this matching entry in-place, so don't move on to - * the next entry. */ - svec_del(&cfg, *p); - } else { - /* Move onto the next entry. */ - p++; + free(*p); + *p = NULL; } } + svec_compact(&cfg); + svec_terminate(&cfg); + ds_destroy(§ion); dirty = true; } diff --git a/lib/svec.c b/lib/svec.c index e0489304..e635d499 100644 --- a/lib/svec.c +++ b/lib/svec.c @@ -171,6 +171,19 @@ svec_unique(struct svec *svec) } } +void +svec_compact(struct svec *svec) +{ + size_t i, j; + + for (i = j = 0; i < svec->n; i++) { + if (svec->names[i] != NULL) { + svec->names[j++] = svec->names[i]; + } + } + svec->n = j; +} + void svec_diff(const struct svec *a, const struct svec *b, struct svec *a_only, struct svec *both, struct svec *b_only) diff --git a/lib/svec.h b/lib/svec.h index 0af162d9..981d43b9 100644 --- a/lib/svec.h +++ b/lib/svec.h @@ -57,6 +57,7 @@ void svec_terminate(struct svec *); void svec_sort(struct svec *); void svec_sort_unique(struct svec *); void svec_unique(struct svec *); +void svec_compact(struct svec *); void svec_diff(const struct svec *a, const struct svec *b, struct svec *a_only, struct svec *both, struct svec *b_only); bool svec_contains(const struct svec *, const char *); -- 2.30.2