]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
* sexp.c (sexp_iterator_simple): Bugfixes. Check earlier that
authorNiels Möller <nisse@lysator.liu.se>
Sat, 28 Sep 2002 15:41:08 +0000 (17:41 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sat, 28 Sep 2002 15:41:08 +0000 (17:41 +0200)
length doesn't grow too large.
(sexp_iterator_next): Skip the current list only if type is
SEXP_LIST. Handle ')'.
(sexp_iterator_enter_list): Set type to SEXP_START.
(sexp_iterator_exit_list): Likewise. Don't skip the ')' here.
(sexp_iterator_assoc): Bug fix.

Rev: src/nettle/sexp.c:1.2

sexp.c

diff --git a/sexp.c b/sexp.c
index 9869d135582fc4554597e218ef2d23c4d9e1f495..194e23cff413f25b959aad196602011d93c490ae 100644 (file)
--- a/sexp.c
+++ b/sexp.c
@@ -59,24 +59,27 @@ sexp_iterator_simple(struct sexp_iterator *iterator,
   
   if (EMPTY(iterator)) return 0;
   c = NEXT(iterator);
+  if (EMPTY(iterator)) return 0;
 
   if (c >= '1' && c <= '9')
     do
       {
        length = length * 10 + (c - '0');
+       if (length > (iterator->length - iterator->pos))
+         return 0;
 
        if (EMPTY(iterator)) return 0;
        c = NEXT(iterator);
       }
-    while (c < '0' || c > '9');
-
-  else if (c != '0')
-    return 0;
+    while (c >= '0' && c <= '9');
 
-  if (EMPTY(iterator) || NEXT(iterator) != ':')
+  else if (c == '0')
+    /* There can be only one */
+    c = NEXT(iterator);
+  else 
     return 0;
 
-  if (length > (iterator->length - iterator->pos))
+  if (c != ':')
     return 0;
 
   *size = length;
@@ -104,11 +107,21 @@ sexp_iterator_next(struct sexp_iterator *iterator)
   switch (iterator->buffer[iterator->pos])
     {
     case '(': /* A list */
-      if (iterator->type == SEXP_START)
-       iterator->type = SEXP_LIST;
-      else
+      if (iterator->type == SEXP_LIST)
+       /* Skip this list */
        return sexp_iterator_enter_list(iterator)
-         && sexp_iterator_exit_list(iterator);
+         && sexp_iterator_exit_list(iterator)
+         && sexp_iterator_next(iterator);
+      else
+       {
+         iterator->type = SEXP_LIST;
+         return 1;
+       }
+    case ')':
+      iterator->pos++;
+      iterator->type = SEXP_END;
+      return 1;
+      
     case '[': /* Atom with display type */
       iterator->pos++;
       if (!sexp_iterator_simple(iterator,
@@ -121,6 +134,8 @@ sexp_iterator_next(struct sexp_iterator *iterator)
       break;
 
     default:
+      /* Must be either a decimal digit or a syntax error.
+       * Errors are detected by sexp_iterator_simple. */
       iterator->display_length = 0;
       iterator->display = NULL;
 
@@ -146,6 +161,7 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator)
     abort();
 
   iterator->level++;
+  iterator->type = SEXP_START;
   return 1;
 }
 
@@ -156,15 +172,18 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator)
   if (!iterator->level)
     return 0;
 
-  while (sexp_iterator_next(iterator))
-    if (iterator->type == SEXP_END)
-      {
-       if (NEXT(iterator) != ')')
-         return 0;
-       iterator->level--;
-       return 1;
-      }
-  return 0;
+  for (;;)
+    {
+      if (!sexp_iterator_next(iterator))
+       return 0;
+      
+      if (iterator->type == SEXP_END)
+       {
+         iterator->type = SEXP_START;    
+         iterator->level--;
+         return 1;
+       }
+    }
 }
 
 int
@@ -185,8 +204,8 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
        {
        case SEXP_LIST:
          
-         if (sexp_iterator_enter_list(iterator)
-             && sexp_iterator_next(iterator))
+         if (! (sexp_iterator_enter_list(iterator)
+                && sexp_iterator_next(iterator)))
            return 0;
          
          if (iterator->type == SEXP_ATOM
@@ -200,10 +219,6 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
                      && !memcmp(keys[i].name, iterator->atom,
                                 keys[i].length))
                    {
-                     /* Match found. NOTE: We allow multiple matches. */
-                     if (!sexp_iterator_next(iterator))
-                       return 0;
-
                      /* Record this position. */
                      values[i] = *iterator;