summaryrefslogtreecommitdiff
path: root/sexp.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2002-09-28 17:41:08 +0200
committerNiels Möller <nisse@lysator.liu.se>2002-09-28 17:41:08 +0200
commit2b7af82f26ceeb7fb5b1474f32867e3cb734e49d (patch)
treee3b09d3db18a947ffcdd85be9dbed748ad59b43e /sexp.c
parent104e79bce7802b112c1ccbae5e40abaffb21e612 (diff)
downloadnettle-2b7af82f26ceeb7fb5b1474f32867e3cb734e49d.tar.gz
* sexp.c (sexp_iterator_simple): Bugfixes. Check earlier that
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
Diffstat (limited to 'sexp.c')
-rw-r--r--sexp.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/sexp.c b/sexp.c
index 9869d135..194e23cf 100644
--- 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;