summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderaadt <deraadt@openbsd.org>2007-09-11 23:30:30 +0000
committerderaadt <deraadt@openbsd.org>2007-09-11 23:30:30 +0000
commit39c88d90d8def6402a1985c47d39ffcceb011169 (patch)
tree994daa7eb245e1c912d6a790b15396f3971f5548
parentmacro argument unused, using local instead; spotted by mpf (diff)
downloadwireguard-openbsd-39c88d90d8def6402a1985c47d39ffcceb011169.tar.xz
wireguard-openbsd-39c88d90d8def6402a1985c47d39ffcceb011169.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 easier ones; range check written by mpf; ok mpf
-rw-r--r--usr.sbin/ifstated/parse.y79
1 files changed, 45 insertions, 34 deletions
diff --git a/usr.sbin/ifstated/parse.y b/usr.sbin/ifstated/parse.y
index 8caed9314b5..4211dc86107 100644
--- a/usr.sbin/ifstated/parse.y
+++ b/usr.sbin/ifstated/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.15 2006/10/25 18:57:34 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.17 2007/09/11 23:30:30 deraadt Exp $ */
/*
* Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
@@ -72,7 +72,6 @@ struct sym {
void link_states(struct ifsd_action *);
int symset(const char *, const char *, int);
char *symget(const char *);
-int atoul(char *, u_long *);
void set_expression_depth(struct ifsd_expression *, int);
void init_state(struct ifsd_state *);
struct ifsd_ifstate *new_ifstate(u_short, int);
@@ -80,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;
@@ -102,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
@@ -119,19 +118,6 @@ grammar : /* empty */
| grammar error '\n' { errors++; }
;
-number : STRING {
- u_long ulval;
-
- if (atoul($1, &ulval) == -1) {
- yyerror("%s is not a number", $1);
- free($1);
- YYERROR;
- } else
- $$ = ulval;
- free($1);
- }
- ;
-
string : string STRING {
if (asprintf(&$$, "%s %s", $1, $2) == -1) {
free($1);
@@ -270,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);
}
@@ -573,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 != '}' && \
@@ -781,22 +808,6 @@ symget(const char *nam)
return (NULL);
}
-int
-atoul(char *s, u_long *ulvalp)
-{
- u_long ulval;
- char *ep;
-
- errno = 0;
- ulval = strtoul(s, &ep, 0);
- if (s[0] == '\0' || *ep != '\0')
- return (-1);
- if (errno == ERANGE && ulval == ULONG_MAX)
- return (-1);
- *ulvalp = ulval;
- return (0);
-}
-
void
set_expression_depth(struct ifsd_expression *expression, int depth)
{