summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 23:30:31 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2007-09-11 23:30:31 +0000
commit9b985ce0f6e0e2d64505e198c81bb3dc50e6892a (patch)
tree2449c4fc1f77b63b883459244a2571c7778e132b
parentd4f37d4bd18236ed2817ff6284f7691613646176 (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.y64
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 != '}' && \