diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-09-11 23:30:31 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2007-09-11 23:30:31 +0000 |
commit | 9b985ce0f6e0e2d64505e198c81bb3dc50e6892a (patch) | |
tree | 2449c4fc1f77b63b883459244a2571c7778e132b | |
parent | d4f37d4bd18236ed2817ff6284f7691613646176 (diff) |
extend lex to spot numbers in the stream, without impacting the parsing
of ip addresses and such. this change is being pushed into all the pfctl
derived parsers, starting with the easier ones; range check written by
mpf; ok mpf
-rw-r--r-- | usr.sbin/ifstated/parse.y | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/usr.sbin/ifstated/parse.y b/usr.sbin/ifstated/parse.y index 4b9673ddc19..4211dc86107 100644 --- a/usr.sbin/ifstated/parse.y +++ b/usr.sbin/ifstated/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.16 2006/10/25 18:58:42 henning Exp $ */ +/* $OpenBSD: parse.y,v 1.17 2007/09/11 23:30:30 deraadt Exp $ */ /* * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org> @@ -79,7 +79,7 @@ struct ifsd_external *new_external(char *, u_int32_t); typedef struct { union { - u_int32_t number; + int64_t number; char *string; struct in_addr addr; u_short interface; @@ -101,7 +101,7 @@ typedef struct { %left UNARY %token ERROR %token <v.string> STRING -%type <v.number> number +%token <v.number> NUMBER %type <v.string> string %type <v.interface> interface %type <v.ifstate> if_test @@ -118,21 +118,6 @@ grammar : /* empty */ | grammar error '\n' { errors++; } ; -number : STRING { - u_int32_t uval; - const char *errstr; - - uval = strtonum($1, 0, UINT_MAX, &errstr); - if (errstr) { - yyerror("number %s is %s", $1, errstr); - free($1); - YYERROR; - } else - $$ = uval; - free($1); - } - ; - string : string STRING { if (asprintf(&$$, "%s %s", $1, $2) == -1) { free($1); @@ -271,7 +256,12 @@ if_test : interface '.' LINK '.' UP { } ; -ext_test : STRING EVERY number { +ext_test : STRING EVERY NUMBER { + if ($3 <= 0) { + yyerror("invalid interval: %d", $3); + free($1); + YYERROR; + } $$ = new_external($1, $3); free($1); } @@ -574,6 +564,42 @@ top: return (STRING); } +#define allowed_to_end_number(x) \ + (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}') + + if (c == '-' || isdigit(c)) { + do { + *p++ = c; + if ((unsigned)(p-buf) >= sizeof(buf)) { + yyerror("string too long"); + return (findeol()); + } + } while ((c = lgetc(fin)) != EOF && isdigit(c)); + lungetc(c); + if (p == buf + 1 && buf[0] == '-') + goto nodigits; + if (c == EOF || allowed_to_end_number(c)) { + const char *errstr = NULL; + + *p = '\0'; + yylval.v.number = strtonum(buf, LLONG_MIN, + LLONG_MAX, &errstr); + if (errstr) { + yyerror("\"%s\" invalid number: %s", + buf, errstr); + return (findeol()); + } + return (NUMBER); + } else { +nodigits: + while (p > buf + 1) + lungetc(*--p); + c = *--p; + if (c == '-') + return (c); + } + } + #define allowed_in_string(x) \ (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ x != '{' && x != '}' && \ |