Commit 2b7af82f authored by Niels Möller's avatar Niels Möller
Browse files

* 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
parent 104e79bc
...@@ -59,24 +59,27 @@ sexp_iterator_simple(struct sexp_iterator *iterator, ...@@ -59,24 +59,27 @@ sexp_iterator_simple(struct sexp_iterator *iterator,
if (EMPTY(iterator)) return 0; if (EMPTY(iterator)) return 0;
c = NEXT(iterator); c = NEXT(iterator);
if (EMPTY(iterator)) return 0;
if (c >= '1' && c <= '9') if (c >= '1' && c <= '9')
do do
{ {
length = length * 10 + (c - '0'); length = length * 10 + (c - '0');
if (length > (iterator->length - iterator->pos))
return 0;
if (EMPTY(iterator)) return 0; if (EMPTY(iterator)) return 0;
c = NEXT(iterator); c = NEXT(iterator);
} }
while (c < '0' || c > '9'); while (c >= '0' && c <= '9');
else if (c != '0')
return 0;
if (EMPTY(iterator) || NEXT(iterator) != ':') else if (c == '0')
/* There can be only one */
c = NEXT(iterator);
else
return 0; return 0;
if (length > (iterator->length - iterator->pos)) if (c != ':')
return 0; return 0;
*size = length; *size = length;
...@@ -104,11 +107,21 @@ sexp_iterator_next(struct sexp_iterator *iterator) ...@@ -104,11 +107,21 @@ sexp_iterator_next(struct sexp_iterator *iterator)
switch (iterator->buffer[iterator->pos]) switch (iterator->buffer[iterator->pos])
{ {
case '(': /* A list */ case '(': /* A list */
if (iterator->type == SEXP_START) if (iterator->type == SEXP_LIST)
iterator->type = SEXP_LIST; /* Skip this list */
else
return sexp_iterator_enter_list(iterator) 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 */ case '[': /* Atom with display type */
iterator->pos++; iterator->pos++;
if (!sexp_iterator_simple(iterator, if (!sexp_iterator_simple(iterator,
...@@ -121,6 +134,8 @@ sexp_iterator_next(struct sexp_iterator *iterator) ...@@ -121,6 +134,8 @@ sexp_iterator_next(struct sexp_iterator *iterator)
break; break;
default: default:
/* Must be either a decimal digit or a syntax error.
* Errors are detected by sexp_iterator_simple. */
iterator->display_length = 0; iterator->display_length = 0;
iterator->display = NULL; iterator->display = NULL;
...@@ -146,6 +161,7 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator) ...@@ -146,6 +161,7 @@ sexp_iterator_enter_list(struct sexp_iterator *iterator)
abort(); abort();
iterator->level++; iterator->level++;
iterator->type = SEXP_START;
return 1; return 1;
} }
...@@ -156,15 +172,18 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator) ...@@ -156,15 +172,18 @@ sexp_iterator_exit_list(struct sexp_iterator *iterator)
if (!iterator->level) if (!iterator->level)
return 0; return 0;
while (sexp_iterator_next(iterator)) for (;;)
if (iterator->type == SEXP_END) {
{ if (!sexp_iterator_next(iterator))
if (NEXT(iterator) != ')') return 0;
return 0;
iterator->level--; if (iterator->type == SEXP_END)
return 1; {
} iterator->type = SEXP_START;
return 0; iterator->level--;
return 1;
}
}
} }
int int
...@@ -185,8 +204,8 @@ sexp_iterator_assoc(struct sexp_iterator *iterator, ...@@ -185,8 +204,8 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
{ {
case SEXP_LIST: case SEXP_LIST:
if (sexp_iterator_enter_list(iterator) if (! (sexp_iterator_enter_list(iterator)
&& sexp_iterator_next(iterator)) && sexp_iterator_next(iterator)))
return 0; return 0;
if (iterator->type == SEXP_ATOM if (iterator->type == SEXP_ATOM
...@@ -200,10 +219,6 @@ sexp_iterator_assoc(struct sexp_iterator *iterator, ...@@ -200,10 +219,6 @@ sexp_iterator_assoc(struct sexp_iterator *iterator,
&& !memcmp(keys[i].name, iterator->atom, && !memcmp(keys[i].name, iterator->atom,
keys[i].length)) keys[i].length))
{ {
/* Match found. NOTE: We allow multiple matches. */
if (!sexp_iterator_next(iterator))
return 0;
/* Record this position. */ /* Record this position. */
values[i] = *iterator; values[i] = *iterator;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment