From: Ben Pfaff Date: Mon, 6 Apr 2009 22:38:30 +0000 (-0700) Subject: cfg: Prevent infinite loop in cfg_del_section(). X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ac8ff00502eeb02786dbdb3b049313fa36df210c;p=openvswitch 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). --- 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 *);