Improved parsing of resolver configuration files
authorYang Tse <yangsita@gmail.com>
Mon, 5 May 2008 17:48:25 +0000 (17:48 +0000)
committerYang Tse <yangsita@gmail.com>
Mon, 5 May 2008 17:48:25 +0000 (17:48 +0000)
ares/CHANGES
ares/RELEASE-NOTES
ares/ares_init.c

index 0003217..d721dd5 100644 (file)
@@ -1,5 +1,9 @@
   Changelog for the c-ares project
 
+* May 5 2008 (Yang Tse)
+
+- Improved parsing of resolver configuration files.
+
 * April 4 2008 (Daniel Stenberg)
 
 - Eino Tuominen improved the code when a file is used to seed the randomizer.
index aff018a..5387ae9 100644 (file)
@@ -1,9 +1,9 @@
 This is what's new and changed in the c-ares 1.5.2 release:
 
- o 
+ o improved parsing of resolver configuration files
 
 Thanks go to these friendly people for their efforts and contributions:
 
+ Yang Tse
 
 Have fun!
index 583f98f..9b655a8 100644 (file)
@@ -1245,16 +1245,61 @@ static int set_options(ares_channel channel, const char *str)
 static char *try_config(char *s, const char *opt)
 {
   size_t len;
+  ssize_t i;
+  ssize_t j;
+  char *p;
 
-  len = strlen(opt);
-  if (strncmp(s, opt, len) != 0 || !ISSPACE(s[len]))
+  if (!s || !opt)
+    /* no line or no option */
+    return NULL;
+
+  /* trim line comment */
+  for (i = 0; s[i] && s[i] != '#'; ++i);
+  s[i] = '\0';
+
+  /* trim trailing whitespace */
+  for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
+  s[++j] = '\0';
+
+  /* skip leading whitespace */
+  for (i = 0; s[i] && ISSPACE(s[i]); ++i);
+  p = &s[i];
+
+  if (!*p)
+    /* empty line */
+    return NULL;
+
+  if ((len = strlen(opt)) == 0)
+    /* empty option */
+    return NULL;
+
+  if (strncmp(p, opt, len) != 0)
+    /* line and option do not match */
     return NULL;
-  s += len;
-  while (ISSPACE(*s))
-    s++;
-  return s;
-}
 
+  /* skip over given option name */
+  p += len;
+
+  if (!*p)
+    /* no option value */
+    return NULL;
+
+  if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
+    /* whitespace between option name and value is mandatory
+       for given option names which do not end with ':' or '=' */
+    return NULL;
+
+  /* skip over whitespace */
+  while (*p && ISSPACE(*p))
+    p++;
+
+  if (!*p)
+    /* no option value */
+    return NULL;
+
+  /* return pointer to option value */
+  return p;
+}
 #endif
 
 static const char *try_option(const char *p, const char *q, const char *opt)