diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2003-03-11 17:54:07 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2003-03-11 17:54:07 +0000 |
commit | 947bc085d1b0cd44f6caa671493997810b164f75 (patch) | |
tree | 18b6007e9a080d78498be867adbf427d1b8e9d0b /usr.sbin/cron | |
parent | 64f827090085ae77934662a0b8b0e813a28ed877 (diff) |
Catch more syntax errors that were previously ignored. I've rewritten
get_number() to be more careful about what it accepts and to take
a string of terminating characters so it knows what is valid. Also
added a range check so that ranges like "60-50" where the first
number is greater than the second are now flagged.
Thanks to mpech@ for testing finding ways to abuse the parser :-)
Diffstat (limited to 'usr.sbin/cron')
-rw-r--r-- | usr.sbin/cron/entry.c | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/usr.sbin/cron/entry.c b/usr.sbin/cron/entry.c index 3931d5f7e78..42205690698 100644 --- a/usr.sbin/cron/entry.c +++ b/usr.sbin/cron/entry.c @@ -1,4 +1,4 @@ -/* $OpenBSD: entry.c,v 1.22 2003/03/10 15:18:25 millert Exp $ */ +/* $OpenBSD: entry.c,v 1.23 2003/03/11 17:54:06 millert Exp $ */ /* * Copyright 1988,1990,1993,1994 by Paul Vixie @@ -23,7 +23,7 @@ */ #if !defined(lint) && !defined(LINT) -static char const rcsid[] = "$OpenBSD: entry.c,v 1.22 2003/03/10 15:18:25 millert Exp $"; +static char const rcsid[] = "$OpenBSD: entry.c,v 1.23 2003/03/11 17:54:06 millert Exp $"; #endif /* vix 26jan87 [RCS'd; rest of log is in RCS file] @@ -56,7 +56,7 @@ static const char *ecodes[] = static char get_list(bitstr_t *, int, int, const char *[], char, FILE *), get_range(bitstr_t *, int, int, const char *[], char, FILE *), - get_number(int *, int, const char *[], char, FILE *); + get_number(int *, int, const char *[], char, FILE *, const char *); static int set_element(bitstr_t *, int, int, int); void @@ -461,7 +461,8 @@ get_range(bitstr_t *bits, int low, int high, const char *names[], if (ch == EOF) return (EOF); } else { - if (EOF == (ch = get_number(&num1, low, names, ch, file))) + ch = get_number(&num1, low, names, ch, file, ",- \t\n"); + if (ch == EOF) return (EOF); if (ch != '-') { @@ -481,7 +482,7 @@ get_range(bitstr_t *bits, int low, int high, const char *names[], /* get the number following the dash */ - ch = get_number(&num2, low, names, ch, file); + ch = get_number(&num2, num1, names, ch, file, "/, \t\n"); if (ch == EOF) return (EOF); } @@ -501,7 +502,7 @@ get_range(bitstr_t *bits, int low, int high, const char *names[], * element id, it's a step size. 'low' is * sent as a 0 since there is no offset either. */ - ch = get_number(&num3, 0, PPC_NULL, ch, file); + ch = get_number(&num3, 0, PPC_NULL, ch, file, " \t\n"); if (ch == EOF || num3 == 0) return (EOF); } else { @@ -525,51 +526,54 @@ get_range(bitstr_t *bits, int low, int high, const char *names[], } static char -get_number(int *numptr, int low, const char *names[], char ch, FILE *file) { +get_number(int *numptr, int low, const char *names[], char ch, FILE *file, + const char *terms) { char temp[MAX_TEMPSTR], *pc; - int len, i, all_digits; + int len, i; - /* collect alphanumerics into our fixed-size temp array - */ pc = temp; len = 0; - all_digits = TRUE; - while (isalnum((unsigned char)ch)) { + + /* first look for a number */ + while (isdigit((unsigned char)ch)) { if (++len >= MAX_TEMPSTR) goto bad; - *pc++ = ch; - - if (!isdigit((unsigned char)ch)) - all_digits = FALSE; - ch = get_char(file); } *pc = '\0'; - if (len == 0) - goto bad; + if (len != 0) { + /* got a number, check for valid terminator */ + if (!strchr(terms, ch)) + goto bad; + *numptr = atoi(temp); + if (*numptr < low) + goto bad; + return (ch); + } - /* try to find the name in the name list - */ + /* no numbers, look for a string if we have any */ if (names) { - for (i = 0; names[i] != NULL; i++) { - Debug(DPARS|DEXT, - ("get_num, compare(%s,%s)\n", names[i], temp)) - if (!strcasecmp(names[i], temp)) { - *numptr = i+low; - return (ch); + while (isalpha((unsigned char)ch)) { + if (++len >= MAX_TEMPSTR) + goto bad; + *pc++ = ch; + ch = get_char(file); + } + *pc = '\0'; + if (len != 0 && strchr(terms, ch)) { + for (i = 0; names[i] != NULL; i++) { + Debug(DPARS|DEXT, + ("get_num, compare(%s,%s)\n", names[i], + temp)) + if (!strcasecmp(names[i], temp)) { + *numptr = i+low; + return (ch); + } } } } - /* no name list specified, or there is one and our string isn't - * in it. either way: if it's all digits, use its magnitude. - * otherwise, it's an error. - */ - if (all_digits) { - *numptr = atoi(temp); - return (ch); - } bad: unget_char(ch, file); return (EOF); |