]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Fix userparse function
authorAlan T. DeKok <aland@freeradius.org>
Wed, 6 Mar 2013 14:03:30 +0000 (09:03 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 6 Mar 2013 14:05:56 +0000 (09:05 -0500)
Remove quadratic addition of vp to list.  Instead, keep track
of the current tail, insert it there, and then add the entire list
in one swell foop.

Also check if we're returning T_OP_INVALID, and if so, free the
intermediate VPs.  This ensures that we either return something,
or an error and nothing else.

It also means that the caller doesn't have to worry about freeing
intermediate VPs if there's a parse error on later ones

src/lib/valuepair.c

index 9a30921d02af12325b1dc9b37742f71fe47bbd7c..c87f596f30d089122cc42a98943d0cab9ef91997 100644 (file)
@@ -1833,7 +1833,7 @@ VALUE_PAIR *pairread(const char **ptr, FR_TOKEN *eol)
  */
 FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
 {
-       VALUE_PAIR      *vp;
+       VALUE_PAIR      *vp, *head, **tail;
        const char      *p;
        FR_TOKEN        last_token = T_OP_INVALID;
        FR_TOKEN        previous_token;
@@ -1844,20 +1844,30 @@ FR_TOKEN userparse(const char *buffer, VALUE_PAIR **first_pair)
        if (buffer[0] == 0)
                return T_EOL;
 
+       head = NULL;
+       tail = &head;
+
        p = buffer;
        do {
                previous_token = last_token;
                if ((vp = pairread(&p, &last_token)) == NULL) {
-                       return last_token;
+                       break;
                }
-               pairadd(first_pair, vp);
+               *tail = vp;
+               tail = &((*tail)->next);
        } while (*p && (last_token == T_COMMA));
 
        /*
         *      Don't tell the caller that there was a comment.
         */
        if (last_token == T_HASH) {
-               return previous_token;
+               last_token = previous_token;
+       }
+
+       if (last_token == T_OP_INVALID) {
+               pairfree(&head);
+       } else {
+               pairadd(first_pair, head);
        }
 
        /*