Now that the random range changes are committed I would like to
revisit this diff.

This fixes two issues with the parsing of random values:

1) Garbage after a random value is now detected.  This fixes a bug
   in the random range parsing that handles the optional final
   number.  For example:

    ~foo    * * * * echo invalid
    0~59bar * * * * echo invalid
    10~%$!  * * * * echo invalid

  These kind of syntax errors are already detected for normal ranges.

2) Bounds check the high and low numbers in a random range.
   Previously, only the final randomized number was bounds-checked
   (which is usually too late).  The bounds are checked for normal
   ranges in set_element() but in the case of random ranges this
   is too late.  The following invalid entry is now rejected.

    0~60  * * * * echo max minute is 59

   Whereas before it would work most (but not all!) of the time.

OK?

 - todd

Index: usr.sbin/cron/entry.c
===================================================================
RCS file: /cvs/src/usr.sbin/cron/entry.c,v
retrieving revision 1.54
diff -u -p -u -r1.54 entry.c
--- usr.sbin/cron/entry.c       6 May 2023 23:06:27 -0000       1.54
+++ usr.sbin/cron/entry.c       6 May 2023 23:36:56 -0000
@@ -499,12 +499,24 @@ get_range(bitstr_t *bits, int low, int h
                        /* get the (optional) number following the tilde
                         */
                        ch = get_number(&num2, low, names, ch, file, "/, \t\n");
-                       if (ch == EOF)
+                       if (ch == EOF) {
+                               /* no second number, check for valid terminator
+                                */
                                ch = get_char(file);
+                               if (!strchr("/, \t\n", ch)) {
+                                       unget_char(ch, file);
+                                       return (EOF);
+                               }
+                       }
                        if (ch == EOF || num1 > num2) {
                                unget_char(ch, file);
                                return (EOF);
                        }
+
+                       /* we must perform the bounds checking ourselves
+                        */
+                       if (num1 < low || num2 > high)
+                               return (EOF);
 
                        if (ch == '/') {
                                /* randomize the step value instead of num1

Reply via email to