Fixed settings lookup if the section/key contains dots
authorMartin Willi <martin@revosec.ch>
Thu, 29 Jul 2010 10:00:21 +0000 (12:00 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 29 Jul 2010 10:14:32 +0000 (12:14 +0200)
src/libstrongswan/settings.c

index 610e2b8..f71b042 100644 (file)
@@ -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, &current))
        {
-               if (streq(current->name, name))
+               if (streq(current->name, buf))
                {
                        found = current;
                        break;
@@ -123,37 +123,55 @@ 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;
-       enumerator_t *enumerator;
-       kv_t *kv;
-       section_t *current, *found = NULL;
+       char buf[128], keybuf[512];
 
-       if (section == NULL)
+       if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf))
        {
                return NULL;
        }
+       return find_section_buffered(section, keybuf, args, buf, sizeof(buf));
+}
 
-       if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name))
+/**
+ * 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;
+
+       if (section == NULL)
        {
                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, &current))
                {
-                       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;
@@ -182,6 +204,20 @@ static char *find_value(section_t *section, char *key, va_list args)
 }
 
 /**
+ * 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.
  */
 static char* get_str(private_settings_t *this, char *key, char *def, ...)