diff options
author | David Hankins <dhankins@isc.org> | 2005-03-01 16:26:20 +0000 |
---|---|---|
committer | David Hankins <dhankins@isc.org> | 2005-03-01 16:26:20 +0000 |
commit | f72a1bcdda33808a4454741828ddcd0a100e86d9 (patch) | |
tree | d7da959f687fdf42552d5e83cc21a2d0aea9d40b | |
parent | 2c5971122958e7b8d991b4ff1b56ae2ebe4fc90f (diff) | |
download | isc-dhcp-f72a1bcdda33808a4454741828ddcd0a100e86d9.tar.gz |
- pull up rt13481.
-rw-r--r-- | RELNOTES | 8 | ||||
-rw-r--r-- | common/conflex.c | 66 | ||||
-rw-r--r-- | common/parse.c | 60 |
3 files changed, 96 insertions, 38 deletions
@@ -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; |