summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hankins <dhankins@isc.org>2005-03-01 16:26:20 +0000
committerDavid Hankins <dhankins@isc.org>2005-03-01 16:26:20 +0000
commitf72a1bcdda33808a4454741828ddcd0a100e86d9 (patch)
treed7da959f687fdf42552d5e83cc21a2d0aea9d40b
parent2c5971122958e7b8d991b4ff1b56ae2ebe4fc90f (diff)
downloadisc-dhcp-f72a1bcdda33808a4454741828ddcd0a100e86d9.tar.gz
- pull up rt13481.
-rw-r--r--RELNOTES8
-rw-r--r--common/conflex.c66
-rw-r--r--common/parse.c60
3 files changed, 96 insertions, 38 deletions
diff --git a/RELNOTES b/RELNOTES
index 6befd67e..f7e3f01c 100644
--- a/RELNOTES
+++ b/RELNOTES
@@ -101,6 +101,14 @@ and for prodding me into improving it.
cause an internal function to overflow heap. Thanks to Jason Vas Dias
at Redhat.
+- Some inconsistencies in treating numbers that the lexer parsed as 'NUMBER'
+ or 'NUMBER_OR_NAME' was repaired. Hexadecimal and octal parsing are
+ affected, and should work better.
+
+- In several cases, parse warnings were being issued before the lexical
+ token had been advanced to the token whose value was causing an error...
+ causing parse warnings to claim the problem is on the wrong token.
+
Changes since 3.0.2rc3
- A previously undocumented configuration directive, 'local-address',
diff --git a/common/conflex.c b/common/conflex.c
index 7c809f94..0d451022 100644
--- a/common/conflex.c
+++ b/common/conflex.c
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: conflex.c,v 1.92.2.9 2004/11/24 17:39:15 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: conflex.c,v 1.92.2.10 2005/03/01 16:26:19 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -410,22 +410,60 @@ static enum dhcp_token read_number (c, cfile)
int c;
struct parse *cfile;
{
+#ifdef OLD_LEXER
int seenx = 0;
+#endif
int i = 0;
int token = NUMBER;
cfile -> tokbuf [i++] = c;
for (; i < sizeof cfile -> tokbuf; i++) {
c = get_char (cfile);
- if (!seenx && c == 'x') {
- seenx = 1;
+
#ifndef OLD_LEXER
- } else if (isascii (c) && !isxdigit (c) &&
- (c == '-' || c == '_' || isalpha (c))) {
- token = NAME;
- } else if (isascii (c) && !isdigit (c) && isxdigit (c)) {
+ /* Promote NUMBER -> NUMBER_OR_NAME -> NAME, never demote.
+ * Except in the case of '0x' syntax hex, which gets called
+ * a NAME at '0x', and returned to NUMBER_OR_NAME once it's
+ * verified to be at least 0xf or less.
+ */
+ switch(token) {
+ case NUMBER:
+ if(isascii(c) && isdigit(c))
+ break;
token = NUMBER_OR_NAME;
-#endif
+ /* FALLTHROUGH */
+ case NUMBER_OR_NAME:
+ if(isascii(c) && isxdigit(c))
+ break;
+ token = NAME;
+ /* FALLTHROUGH */
+ case NAME:
+ if((i == 2) && isascii(c) && isxdigit(c) &&
+ (cfile->tokbuf[0] == '0') &&
+ ((cfile->tokbuf[1] == 'x') ||
+ (cfile->tokbuf[1] == 'X'))) {
+ token = NUMBER_OR_NAME;
+ break;
+ } else if((c == '-') || (c == '_') ||
+ (isascii(c) && isalnum(c)))
+ break;
+
+ /* At this point c is either EOF or part of the next
+ * token. If not EOF, rewind the file one byte so
+ * the next token is read from there.
+ */
+ if(c != EOF) {
+ cfile->bufix--;
+ cfile->ugflag = 1;
+ }
+ goto end_read;
+
+ default:
+ log_fatal("read_number():%s:%d: impossible case", MDL);
+ }
+#else /* OLD_LEXER */
+ if (!seenx && (c == 'x') {
+ seenx = 1;
} else if (!isascii (c) || !isxdigit (c)) {
if (c != EOF) {
cfile -> bufix--;
@@ -433,16 +471,28 @@ static enum dhcp_token read_number (c, cfile)
}
break;
}
+#endif /* OLD_LEXER */
+
cfile -> tokbuf [i] = c;
}
+
if (i == sizeof cfile -> tokbuf) {
parse_warn (cfile,
"numeric token larger than internal buffer");
--i;
}
+
+ end_read:
cfile -> tokbuf [i] = 0;
cfile -> tlen = i;
cfile -> tval = cfile -> tokbuf;
+
+ /* Check for octal after the fact - octal cannot be a NUMBER as
+ * atoi() will not parse it properly.
+ */
+ if ((token == NUMBER) && (cfile->tokbuf[0] == '0') && (i > 1))
+ token = NUMBER_OR_NAME;
+
return token;
}
diff --git a/common/parse.c b/common/parse.c
index e29fdcff..f95cb65b 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -34,7 +34,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.104.2.20 2004/09/30 20:38:31 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.104.2.21 2005/03/01 16:26:20 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -720,7 +720,7 @@ TIME parse_date (cfile)
return (TIME)0;
}
- /* Month... */
+ /* Day of month... */
token = next_token (&val, (unsigned *)0, cfile);
if (token != NUMBER) {
parse_warn (cfile, "numeric day of month expected.");
@@ -4320,15 +4320,15 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
switch (**fmt) {
case 'U':
- token = peek_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
if (!is_identifier (token)) {
if ((*fmt) [1] != 'o') {
parse_warn (cfile, "expecting identifier.");
- skip_to_semi (cfile);
+ if (token != SEMI)
+ skip_to_semi (cfile);
}
return 0;
}
- token = next_token (&val, &len, cfile);
if (!make_const_data (&t, (const unsigned char *)val,
len, 1, 1, MDL))
log_fatal ("No memory for %s", val);
@@ -4353,18 +4353,21 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
return 0;
}
t -> op = expr_const_data;
- } else if (token == STRING) {
- token = next_token (&val, &len, cfile);
- if (!make_const_data (&t, (const unsigned char *)val,
- len, 1, 1, MDL))
- log_fatal ("No memory for \"%s\"", val);
} else {
- if ((*fmt) [1] != 'o') {
+ token = next_token (&val, &len, cfile);
+
+ if(token == STRING) {
+ if (!make_const_data (&t,
+ (const unsigned char *)val,
+ len, 1, 1, MDL))
+ log_fatal ("No memory for \"%s\"", val);
+ } else if ((*fmt) [1] != 'o') {
parse_warn (cfile, "expecting string %s.",
"or hexadecimal data");
skip_to_semi (cfile);
+ } else {
+ return 0;
}
- return 0;
}
break;
@@ -4379,7 +4382,7 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
goto make_string;
case 't': /* Text string... */
- token = peek_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
if (token != STRING && !is_identifier (token)) {
if ((*fmt) [1] != 'o') {
parse_warn (cfile, "expecting string.");
@@ -4388,7 +4391,6 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
return 0;
}
- token = next_token (&val, &len, cfile);
make_string:
if (!make_const_data (&t, (const unsigned char *)val,
len, 1, 1, MDL))
@@ -4435,10 +4437,9 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
break;
case 'T': /* Lease interval. */
- token = peek_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
if (token != INFINITE)
goto check_number;
- token = next_token (&val, (unsigned *)0, cfile);
putLong (buf, -1);
if (!make_const_data (&t, buf, 4, 0, 1, MDL))
return 0;
@@ -4446,9 +4447,9 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
case 'L': /* Unsigned 32-bit integer... */
case 'l': /* Signed 32-bit integer... */
- token = peek_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
check_number:
- if (token != NUMBER) {
+ if ((token != NUMBER) && (token != NUMBER_OR_NAME)) {
need_number:
if ((*fmt) [1] != 'o') {
parse_warn (cfile, "expecting number.");
@@ -4457,7 +4458,6 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
}
return 0;
}
- token = next_token (&val, (unsigned *)0, cfile);
convert_num (cfile, buf, val, 0, 32);
if (!make_const_data (&t, buf, 4, 0, 1, MDL))
return 0;
@@ -4465,10 +4465,9 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
case 's': /* Signed 16-bit integer. */
case 'S': /* Unsigned 16-bit integer. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
token = next_token (&val, (unsigned *)0, cfile);
+ if ((token != NUMBER) && (token != NUMBER_OR_NAME))
+ goto need_number;
convert_num (cfile, buf, val, 0, 16);
if (!make_const_data (&t, buf, 2, 0, 1, MDL))
return 0;
@@ -4476,17 +4475,16 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
case 'b': /* Signed 8-bit integer. */
case 'B': /* Unsigned 8-bit integer. */
- token = peek_token (&val, (unsigned *)0, cfile);
- if (token != NUMBER)
- goto need_number;
token = next_token (&val, (unsigned *)0, cfile);
+ if ((token != NUMBER) && (token != NUMBER_OR_NAME))
+ goto need_number;
convert_num (cfile, buf, val, 0, 8);
if (!make_const_data (&t, buf, 1, 0, 1, MDL))
return 0;
break;
case 'f': /* Boolean flag. */
- token = peek_token (&val, (unsigned *)0, cfile);
+ token = next_token (&val, (unsigned *)0, cfile);
if (!is_identifier (token)) {
if ((*fmt) [1] != 'o')
parse_warn (cfile, "expecting identifier.");
@@ -4510,7 +4508,6 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
parse_warn (cfile, "expecting boolean.");
goto bad_flag;
}
- token = next_token (&val, (unsigned *)0, cfile);
if (!make_const_data (&t, buf, 1, 0, 1, MDL))
return 0;
break;
@@ -4650,7 +4647,8 @@ int parse_option_decl (oc, cfile)
case 'l': /* Signed 32-bit integer... */
token = next_token (&val,
(unsigned *)0, cfile);
- if (token != NUMBER) {
+ if ((token != NUMBER) &&
+ (token != NUMBER_OR_NAME)) {
need_number:
parse_warn (cfile,
"expecting number.");
@@ -4667,7 +4665,8 @@ int parse_option_decl (oc, cfile)
case 'S': /* Unsigned 16-bit integer. */
token = next_token (&val,
(unsigned *)0, cfile);
- if (token != NUMBER)
+ if ((token != NUMBER) &&
+ (token != NUMBER_OR_NAME))
goto need_number;
convert_num (cfile, buf, val, 0, 16);
len = 2;
@@ -4678,7 +4677,8 @@ int parse_option_decl (oc, cfile)
case 'B': /* Unsigned 8-bit integer. */
token = next_token (&val,
(unsigned *)0, cfile);
- if (token != NUMBER)
+ if ((token != NUMBER) &&
+ (token != NUMBER_OR_NAME))
goto need_number;
convert_num (cfile, buf, val, 0, 8);
len = 1;