From: Thibault Godouet Date: Tue, 15 Apr 2014 23:05:50 +0000 (+0100) Subject: fcrontab no longer crashes if mailto is empty -- fixed issues with string options X-Git-Tag: ver3_1_3~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e53f9b35b6e951e584138b343a0fecc02c58013d;p=thirdparty%2Ffcron.git fcrontab no longer crashes if mailto is empty -- fixed issues with string options --- diff --git a/conf.c b/conf.c index 00228f4..8db0f2b 100644 --- a/conf.c +++ b/conf.c @@ -464,7 +464,7 @@ read_file(const char *file_name, cf_t * cf, int is_system_startup) } /* check if this file is owned by root : otherwise, all runas fields - * of this field should be set to the owner */ + * of this file should be set to the owner */ rc = fstat(fileno(ff), &file_stat); if (rc != 0) { error_e("Could not stat %s", file_name); diff --git a/doc/en/changes.sgml b/doc/en/changes.sgml index f22892e..78b8e92 100644 --- a/doc/en/changes.sgml +++ b/doc/en/changes.sgml @@ -29,6 +29,9 @@ A copy of the license is included in gfdl.sgml. fcrondyn no longer crashes when receiving an EOF when using readline (thanks Wade Carpenter for the patch) + + fcrontab no longer crash if mailto is empty (thanks Olaf for reporting the issue) + diff --git a/fileconf.c b/fileconf.c index d478008..7a6c6d4 100644 --- a/fileconf.c +++ b/fileconf.c @@ -42,6 +42,7 @@ int read_shortcut(char *ptr, cf_t * cf); void read_env(char *ptr, cf_t * cf); char *read_opt(char *ptr, cl_t * cl); char *check_username(char *ptr, cf_t * cf, cl_t * cl); +size_t option_strlen(char *value); char need_correction; cl_t default_line; /* default options for a line */ @@ -403,33 +404,45 @@ get_nice(char *ptr, int *nice) } -int -assign_option_string(char **var, char *value) -/* Read the value of an option, and assign it to the var. - * Returns the length of the value, or -1 on error. */ +size_t +option_strlen(char *value) +/* return the length of the string value of an option */ { char *ptr = value; - char *start = value; - char *end = value; - int len = 0; - - Free_safe(*var); + size_t len = 0; /* look for the end of the option value */ - while (ptr != NULL && *ptr != ')') { + while (ptr != NULL && *ptr != ')' && *ptr != '\0') { ptr++; len++; } + return len; +} + +int +assign_option_string(char **var, char *value) +/* Read the value of an option: if non-empty, assign it to the var, + * otherwise set to NULL. + * Returns the length of the value (0 if empty), or -1 on error. */ +{ + char start = value[0]; + char end = '\0'; + size_t len = 0; + + Free_safe(*var); + + len = option_strlen(value); + if (len <= 0) { return len; } - end = ptr - 1; + end = value[len - 1]; /* spaces and quotes are not allowed before or after the value */ - if (isspace((int)*start) || isspace((int)*end) - || *start == '\'' || *start == '\"' || *end == '\'' || *end == '\"') { + if (isspace((int)start) || isspace((int)end) + || start == '\'' || start == '"' || end == '\'' || end == '"') { return -1; } @@ -550,6 +563,8 @@ read_opt(char *ptr, cl_t * cl) Handle_err; } + /* assign_option_string() will set cl_tz to NULL is the value is empty, + * which means "use the system timezone" */ len = assign_option_string(&(cl->cl_tz), ptr); if (len < 0) { Handle_err; @@ -860,18 +875,29 @@ read_opt(char *ptr, cl_t * cl) Handle_err; } - /* please note that we check if the mailto is valid in conf.c */ - len = assign_option_string(&(cl->cl_mailto), ptr); - if (len < 0) { - Handle_err; - } - else if (len == 0) { + /* assign_option_string() set the value to NULL if the length is zero. + * However cl_mailto must not be NULL (as expected in + * conf.c:add_line_to_file()), so we check if the length is >= 0 + * before calling assign_option_string() */ + /* Also please note that we check if the mailto is valid in conf.c */ + len = option_strlen(ptr); + if (len <= 0) { clear_mail(cl->cl_option); clear_mailzerolength(cl->cl_option); + if (debug_opt) { + fprintf(stderr, " Opt : \"mail\" 0\n"); + fprintf(stderr, " Opt : \"forcemail\" 0\n"); + } } else { - ptr += len; - set_mail(cl->cl_option); + len = assign_option_string(&(cl->cl_mailto), ptr); + if (len < 0) { + Handle_err; + } + else { + ptr += len; + set_mail(cl->cl_option); + } } if (debug_opt) @@ -963,7 +989,7 @@ read_opt(char *ptr, cl_t * cl) } len = assign_option_string(&runas, ptr); - if (len < 0) { + if (len <= 0) { Handle_err; } else { diff --git a/mem.c b/mem.c index 2ce0107..6a9d3e3 100644 --- a/mem.c +++ b/mem.c @@ -70,6 +70,7 @@ strndup2(const char *str, size_t n) if (str == NULL) return NULL; + /* note: if n==0 then ptr will be an empty string (non-NULL) */ ptr = strndup(str, n); if (!ptr) diff --git a/save.c b/save.c index 7084c4e..c708d36 100644 --- a/save.c +++ b/save.c @@ -62,7 +62,7 @@ int save_str(int fd, short int type, char *str, char *write_buf, int *buf_used) /* save a string of type "type" in a binary fcrontab file */ { - short int size = strlen(str); + short int size = (str != NULL) ? strlen(str) : 0; int write_len = sizeof(type) + sizeof(size) + size; if (write_len > WRITE_BUF_LEN - *buf_used)