]> gitweb.factorcode.org Git - factor.git/commitdiff
crontab: better input validation for stuff like Feb 30 or Apr 31.
authorJohn Benediktsson <mrjbq7@gmail.com>
Sun, 24 Mar 2019 20:32:57 +0000 (13:32 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Sun, 24 Mar 2019 20:32:57 +0000 (13:32 -0700)
extra/crontab/crontab-tests.factor
extra/crontab/crontab.factor

index e85b638e04d3fdf84e4325e7f26367fdcc73fa7c..4f03eab421e58aae31fea15ea3be904e7a6b3ca1 100644 (file)
@@ -7,6 +7,9 @@ IN: crontab.tests
     now "*/1 * * * *" parse-cronentry next-time <=>
 ] unit-test
 
+[ "0 0 30 2 *" parse-cronentry ] [ invalid-cronentry? ] must-fail-with
+[ "0 0 31 4 *" parse-cronentry ] [ invalid-cronentry? ] must-fail-with
+
 CONSTANT: start-timestamp T{ timestamp
     { year 2019 }
     { month 3 }
index 2ea27a821e39859e572dbf2013c679598c0091ff..329b2982a5ed09e8dba5e5b2a4b264999fbbb15f 100644 (file)
@@ -2,11 +2,14 @@
 ! See http://factorcode.org/license.txt for BSD license
 
 USING: accessors arrays ascii assocs calendar calendar.english
-calendar.private combinators io kernel literals locals math
-math.order math.parser math.ranges sequences splitting ;
+calendar.private combinators combinators.short-circuit io kernel
+literals locals math math.order math.parser math.ranges
+sequences splitting ;
 
 IN: crontab
 
+ERROR: invalid-cronentry value ;
+
 :: parse-value ( value quot: ( value -- value' ) seq -- value )
     value {
         { [ CHAR: , over member? ] [
@@ -42,6 +45,20 @@ CONSTANT: aliases H{
     { "@hourly"   "0 * * * *" }
 }
 
+: check-cronentry ( cronentry -- cronentry )
+    dup {
+        [ days-of-week>> [ 0 6 between? ] all? ]
+        [ months>> [ 1 12 between? ] all? ]
+        [
+            [ days>> 1 ] [ months>> ] bi
+            dup { 2 } sequence= [ drop 29 ] [
+                [ day-counts nth ] map supremum
+            ] if [ between? ] 2curry all?
+        ]
+        [ minutes>> [ 0 59 between? ] all? ]
+        [ hours>> [ 0 23 between? ] all? ]
+    } 1&& [ invalid-cronentry ] unless ;
+
 : parse-cronentry ( entry -- cronentry )
     " " split1 [ aliases ?at drop ] dip " " glue
     " " split1 " " split1 " " split1 " " split1 " " split1 {
@@ -51,7 +68,7 @@ CONSTANT: aliases H{
         [ [ parse-month ] T{ range f 1 12 1 } parse-value ]
         [ [ parse-day ] T{ range f 0 7 1 } parse-value ]
         [ ]
-    } spread cronentry boa ;
+    } spread cronentry boa check-cronentry ;
 
 <PRIVATE