]> granicus.if.org Git - fcron/commitdiff
fcrontab no longer crashes if mailto is empty -- fixed issues with string options
authorThibault Godouet <fcron@free.fr>
Tue, 15 Apr 2014 23:05:50 +0000 (00:05 +0100)
committerThibault Godouet <fcron@free.fr>
Tue, 15 Apr 2014 23:05:50 +0000 (00:05 +0100)
conf.c
doc/en/changes.sgml
fileconf.c
mem.c
save.c

diff --git a/conf.c b/conf.c
index 00228f4d0d56da3cb2a96c29cedbccad66838a2c..8db0f2b63bce857be5d3408314f75f8e41fe3463 100644 (file)
--- 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);
index f22892e0bc81051ec245d62e931ba552846d403b..78b8e92077e962afc2bcfebe012f508fd57cbf18 100644 (file)
@@ -29,6 +29,9 @@ A copy of the license is included in gfdl.sgml.
            <listitem>
               <para>fcrondyn no longer crashes when receiving an EOF when using readline (thanks Wade Carpenter for the patch)</para>
            </listitem>
+           <listitem>
+              <para>fcrontab no longer crash if mailto is empty (thanks Olaf for reporting the issue)</para>
+           </listitem>
       </itemizedlist>
 
       <itemizedlist>
index d478008b7643ce7710f73ec2939690d94d0d931c..7a6c6d4aeab2a6e20ebec35c73c9c07acd6a2aae 100644 (file)
@@ -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 2ce01072474dac788a258f8fcebce181b12d6e5f..6a9d3e3a15fa5e7f50ef1209224dc88533c86dce 100644 (file)
--- 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 7084c4e3295c2bb7508621a87c81aa7086355b11..c708d36a13b104f2af56a3f6dc564a06e44ce7a9 100644 (file)
--- 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)