summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2007-09-11 22:15:17 +0000
committerderaadt <deraadt@openbsd.org>2007-09-11 22:15:17 +0000
commit06f703ebdd8ff3da888458bd0f64fdccf9d16101 (patch)
tree9cf619b48e496b945b0bca3e1e234dee74bf9a88
parentKNF. "go for it" deraadt@ (diff)
downloadwireguard-openbsd-06f703ebdd8ff3da888458bd0f64fdccf9d16101.tar.xz
wireguard-openbsd-06f703ebdd8ff3da888458bd0f64fdccf9d16101.zip
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 easy ones; ok claudio michele
-rw-r--r--usr.sbin/dvmrpd/parse.y76
-rw-r--r--usr.sbin/ripd/parse.y64
2 files changed, 92 insertions, 48 deletions
diff --git a/usr.sbin/dvmrpd/parse.y b/usr.sbin/dvmrpd/parse.y
index b521adad2a1..22f785cd6b1 100644
--- a/usr.sbin/dvmrpd/parse.y
+++ b/usr.sbin/dvmrpd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.4 2007/03/21 19:33:48 michele Exp $ */
+/* $OpenBSD: parse.y,v 1.5 2007/09/11 22:15:20 deraadt Exp $ */
/*
* Copyright (c) 2004, 2005, 2006 Esben Norby <norby@openbsd.org>
@@ -92,7 +92,7 @@ struct iface *new_group(void);
typedef struct {
union {
- u_int32_t number;
+ int64_t number;
char *string;
} v;
int lineno;
@@ -109,7 +109,8 @@ typedef struct {
%token IGMPVERSION
%token ERROR
%token <v.string> STRING
-%type <v.number> number yesno
+%token <v.number> NUMBER
+%type <v.number> yesno
%type <v.string> string
%%
@@ -123,21 +124,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);
@@ -183,7 +169,7 @@ conf_main : FIBUPDATE yesno {
| defaults
;
-defaults : LASTMEMBERQUERYCNT number {
+defaults : LASTMEMBERQUERYCNT NUMBER {
if ($2 < MIN_LAST_MEMBER_QUERY_CNT ||
$2 > MAX_LAST_MEMBER_QUERY_CNT) {
yyerror("last-member-query-count out of "
@@ -194,7 +180,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->last_member_query_cnt = $2;
}
- | LASTMEMBERQUERYINTERVAL number {
+ | LASTMEMBERQUERYINTERVAL NUMBER {
if ($2 < MIN_LAST_MEMBER_QUERY_INTERVAL ||
$2 > MAX_LAST_MEMBER_QUERY_INTERVAL) {
yyerror("last-member-query-interval out of "
@@ -205,7 +191,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->last_member_query_interval = $2;
}
- | METRIC number {
+ | METRIC NUMBER {
if ($2 < MIN_METRIC || $2 > MAX_METRIC) {
yyerror("metric out of range (%d-%d)",
MIN_METRIC, MAX_METRIC);
@@ -213,7 +199,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->metric = $2;
}
- | QUERYINTERVAL number {
+ | QUERYINTERVAL NUMBER {
if ($2 < MIN_QUERY_INTERVAL ||
$2 > MAX_QUERY_INTERVAL) {
yyerror("query-interval out of range (%d-%d)",
@@ -222,7 +208,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->query_interval = $2;
}
- | QUERYRESPINTERVAL number {
+ | QUERYRESPINTERVAL NUMBER {
if ($2 < MIN_QUERY_RESP_INTERVAL ||
$2 > MAX_QUERY_RESP_INTERVAL) {
yyerror("query-response-interval out of "
@@ -233,7 +219,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->query_resp_interval = $2;
}
- | ROBUSTNESS number {
+ | ROBUSTNESS NUMBER {
if ($2 < MIN_ROBUSTNESS || $2 > MAX_ROBUSTNESS) {
yyerror("robustness out of range (%d-%d)",
MIN_ROBUSTNESS, MAX_ROBUSTNESS);
@@ -241,7 +227,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->robustness = $2;
}
- | STARTUPQUERYCNT number {
+ | STARTUPQUERYCNT NUMBER {
if ($2 < MIN_STARTUP_QUERY_CNT ||
$2 > MAX_STARTUP_QUERY_CNT) {
yyerror("startup-query-count out of "
@@ -252,7 +238,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->startup_query_cnt = $2;
}
- | STARTUPQUERYINTERVAL number {
+ | STARTUPQUERYINTERVAL NUMBER {
if ($2 < MIN_STARTUP_QUERY_INTERVAL ||
$2 > MAX_STARTUP_QUERY_INTERVAL) {
yyerror("startup-query-interval out of "
@@ -263,7 +249,7 @@ defaults : LASTMEMBERQUERYCNT number {
}
defs->startup_query_interval = $2;
}
- | IGMPVERSION number {
+ | IGMPVERSION NUMBER {
if ($2 < MIN_IGMP_VERSION ||
$2 > MAX_IGMP_VERSION) {
yyerror("igmp-version out of range (%d-%d)",
@@ -566,6 +552,42 @@ top:
return (STRING);
}
+#define allowed_to_end_number(x) \
+ (isspace(x) || c == ')' || c ==',' || c == '/' || c == '}')
+
+ 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 != '}' && \
diff --git a/usr.sbin/ripd/parse.y b/usr.sbin/ripd/parse.y
index 93b1728519c..16f8de40b51 100644
--- a/usr.sbin/ripd/parse.y
+++ b/usr.sbin/ripd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.6 2007/01/15 18:23:43 michele Exp $ */
+/* $OpenBSD: parse.y,v 1.7 2007/09/11 22:15:17 deraadt Exp $ */
/*
* Copyright (c) 2006 Michele Marchetto <mydecay@openbeer.it>
@@ -86,7 +86,7 @@ struct iface *conf_get_if(struct kif *);
typedef struct {
union {
- u_int32_t number;
+ int64_t number;
char *string;
} v;
int lineno;
@@ -101,7 +101,8 @@ typedef struct {
%token YES NO
%token ERROR
%token <v.string> STRING
-%type <v.number> number yesno no
+%token <v.number> NUMBER
+%type <v.number> yesno no
%type <v.string> string
%%
@@ -113,21 +114,6 @@ grammar : /* empty */
| grammar interface '\n'
;
-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);
@@ -239,7 +225,7 @@ conf_main : SPLIT_HORIZON STRING {
| defaults
;
-authmd : AUTHMD number STRING {
+authmd : AUTHMD NUMBER STRING {
if ($2 < MIN_MD_ID || $2 > MAX_MD_ID) {
yyerror("auth-md key-id out of range "
"(%d-%d)", MIN_MD_ID, MAX_MD_ID);
@@ -257,7 +243,7 @@ authmd : AUTHMD number STRING {
free($3);
}
-authmdkeyid : AUTHMDKEYID number {
+authmdkeyid : AUTHMDKEYID NUMBER {
if ($2 < MIN_MD_ID || $2 > MAX_MD_ID) {
yyerror("auth-md-keyid out of range "
"(%d-%d)", MIN_MD_ID, MAX_MD_ID);
@@ -298,7 +284,7 @@ authkey : AUTHKEY STRING {
}
;
-defaults : COST number {
+defaults : COST NUMBER {
if ($2 < 1 || $2 > INFINITY) {
yyerror("cost out of range (%d-%d)", 1,
INFINITY);
@@ -573,6 +559,42 @@ top:
return (STRING);
}
+#define allowed_to_end_number(x) \
+ (isspace(x) || c == ')' || c ==',' || c == '/' || c == '}')
+
+ 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 != '}' && \