diff --git a/src/libstrongswan/settings.c b/src/libstrongswan/settings.c index 610e2b8ea..f71b04245 100644 --- a/src/libstrongswan/settings.c +++ b/src/libstrongswan/settings.c @@ -88,11 +88,12 @@ struct kv_t { }; /** - * find a section by a given key + * find a section by a given key, using buffered key, reusable buffer */ -static section_t *find_section(section_t *section, char *key, va_list args) +static section_t *find_section_buffered(section_t *section, char *key, + va_list args, char *buf, int len) { - char name[512], *pos; + char *pos; enumerator_t *enumerator; section_t *current, *found = NULL; @@ -100,21 +101,20 @@ static section_t *find_section(section_t *section, char *key, va_list args) { return NULL; } - if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name)) - { - return NULL; - } - - pos = strchr(name, '.'); + pos = strchr(key, '.'); if (pos) { *pos = '\0'; pos++; } + if (vsnprintf(buf, len, key, args) >= len) + { + return NULL; + } enumerator = section->sections->create_enumerator(section->sections); while (enumerator->enumerate(enumerator, ¤t)) { - if (streq(current->name, name)) + if (streq(current->name, buf)) { found = current; break; @@ -123,14 +123,32 @@ static section_t *find_section(section_t *section, char *key, va_list args) enumerator->destroy(enumerator); if (found && pos) { - return find_section(found, pos, args); + return find_section_buffered(found, pos, args, buf, len); } return found; } -static char *find_value(section_t *section, char *key, va_list args) +/** + * find a section by a given key + */ +static section_t *find_section(section_t *section, char *key, va_list args) { - char name[512], *pos, *value = NULL; + char buf[128], keybuf[512]; + + if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf)) + { + return NULL; + } + return find_section_buffered(section, keybuf, args, buf, sizeof(buf)); +} + +/** + * Find the string value for a key, using buffered key, reusable buffer + */ +static char *find_value_buffered(section_t *section, char *key, va_list args, + char *buf, int len) +{ + char *pos, *value = NULL; enumerator_t *enumerator; kv_t *kv; section_t *current, *found = NULL; @@ -140,20 +158,20 @@ static char *find_value(section_t *section, char *key, va_list args) return NULL; } - if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name)) - { - return NULL; - } - - pos = strchr(name, '.'); + pos = strchr(key, '.'); if (pos) { *pos = '\0'; pos++; + + if (vsnprintf(buf, len, key, args) >= len) + { + return NULL; + } enumerator = section->sections->create_enumerator(section->sections); while (enumerator->enumerate(enumerator, ¤t)) { - if (streq(current->name, name)) + if (streq(current->name, buf)) { found = current; break; @@ -162,15 +180,19 @@ static char *find_value(section_t *section, char *key, va_list args) enumerator->destroy(enumerator); if (found) { - return find_value(found, pos, args); + return find_value_buffered(found, pos, args, buf, len); } } else { + if (vsnprintf(buf, len, key, args) >= len) + { + return NULL; + } enumerator = section->kv->create_enumerator(section->kv); while (enumerator->enumerate(enumerator, &kv)) { - if (streq(kv->key, name)) + if (streq(kv->key, buf)) { value = kv->value; break; @@ -181,6 +203,20 @@ static char *find_value(section_t *section, char *key, va_list args) return value; } +/** + * Find the string value for a key + */ +static char *find_value(section_t *section, char *key, va_list args) +{ + char buf[128], keybuf[512]; + + if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf)) + { + return NULL; + } + return find_value_buffered(section, keybuf, args, buf, sizeof(buf)); +} + /** * Implementation of settings_t.get. */