diff options
-rw-r--r-- | usr.sbin/dvmrpd/parse.y | 76 | ||||
-rw-r--r-- | usr.sbin/ripd/parse.y | 64 |
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 != '}' && \ |