Welcome to little lamb

Code » slicd » commit 8e43d0f

Add job_ensure_valid() and call it on load()

author Olivier Brunel
2015-12-28 18:14:16 UTC
committer Olivier Brunel
2016-01-12 14:33:47 UTC
parent 8bf0e70a1fe35dfa94eef4510ef1b8c90f0bb255

Add job_ensure_valid() and call it on load()

On slicd_load() we also ensure the offset is within the str.

src/include/slicd/err.h +2 -0
src/include/slicd/job.h +3 -0
src/libslicd/deps-lib/slicd +1 -0
src/libslicd/errmsg.c +3 -1
src/libslicd/slicd_add_job_from_cronline.c +27 -70
src/libslicd/slicd_job_ensure_valid.c +89 -0
src/libslicd/slicd_load.c +21 -0

diff --git a/src/include/slicd/err.h b/src/include/slicd/err.h
index 6674675..733d11a 100644
--- a/src/include/slicd/err.h
+++ b/src/include/slicd/err.h
@@ -36,6 +36,8 @@ enum
     SLICD_ERR_DAYS_COMBO,
     SLICD_ERR_IMPOSSIBLE_DATE,
     SLICD_ERR_NO_USERNAME,
+    SLICD_ERR_NO_MATCH,
+    SLICD_ERR_INVALID_JOB,
     _SLICD_NB_ERR
 };
 
diff --git a/src/include/slicd/job.h b/src/include/slicd/job.h
index 7cf41b5..08e5a27 100644
--- a/src/include/slicd/job.h
+++ b/src/include/slicd/job.h
@@ -67,4 +67,7 @@ extern int slicd_job_first          (slicd_job_t    *job,
                                      int             to,
                                      int             what);
 
+
+extern int slicd_job_ensure_valid   (slicd_job_t    *job);
+
 #endif /* SLICD_JOB_H */
diff --git a/src/libslicd/deps-lib/slicd b/src/libslicd/deps-lib/slicd
index fb9cf1f..7410daa 100644
--- a/src/libslicd/deps-lib/slicd
+++ b/src/libslicd/deps-lib/slicd
@@ -7,6 +7,7 @@ slicd_die_usage.o
 slicd_die_version.o
 slicd_free.o
 slicd_job.o
+slicd_job_ensure_valid.o
 slicd_job_next_run.o
 slicd_load.o
 slicd_save.o
diff --git a/src/libslicd/errmsg.c b/src/libslicd/errmsg.c
index e61e728..2e2000b 100644
--- a/src/libslicd/errmsg.c
+++ b/src/libslicd/errmsg.c
@@ -33,5 +33,7 @@ const char const *slicd_errmsg[_SLICD_NB_ERR] = {
     "Syntax error",
     "Out of range days alongside days of the week",
     "Impossible date matching (e.g. Feb 31)",
-    "No username specified"
+    "No username specified",
+    "No possible match (field without any selection)",
+    "Invalid job data"
 };
diff --git a/src/libslicd/slicd_add_job_from_cronline.c b/src/libslicd/slicd_add_job_from_cronline.c
index c82890d..363c227 100644
--- a/src/libslicd/slicd_add_job_from_cronline.c
+++ b/src/libslicd/slicd_add_job_from_cronline.c
@@ -169,6 +169,7 @@ slicd_add_job_from_cronline (slicd_t     *slicd,
 {
     slicd_job_t j = { 0, };
     const char *s = cronline;
+    int len;
     int r;
     int i;
 
@@ -186,81 +187,37 @@ slicd_add_job_from_cronline (slicd_t     *slicd,
             return r;
     }
 
-    /* special case: days combo */
-    if (slicd_job_first (&j, SLICD_DAYS_OF_WEEK, 0, 6, 0) <= 6)
-    {
-        /* there is a restriction on DOW, now let's check how the first 6 days
-         * are set:
-         * - all set    = same as '*', no restriction on DAYS
-         * - none set   = invalid
-         * - a mix      = DAYS_COMBO
-         */
-
-        if (slicd_job_first (&j, SLICD_DAYS, 1, 6, 0) == 7)
-            slicd_job_set (&j, SLICD_DAYS, 1, 31);
-        else if (slicd_job_first (&j, SLICD_DAYS, 1, 6, 1) == 7)
-            return -SLICD_ERR_DAYS_COMBO;
-        else
-            slicd_job_set_days_combo (&j, 1);
-    }
+    r = slicd_job_ensure_valid (&j);
+    if (r < 0)
+        return r;
 
-    /* ensure date validity/coherence */
-    if (slicd_job_first (&j, SLICD_DAYS, 1, 29, 1) == 30)
+    if (username)
+        i = strlen (username);
+    else
     {
-        /* none of the first 29 days are set, so we need to do some checking:
-         * if day 30 is set, that there's another month than Feb,
-         * else (i.e. day 31 is set) that there's at least one matching month
-         */
-        if (slicd_job_has (&j, SLICD_DAYS, 30))
-        {
-            if (!(slicd_job_has (&j, SLICD_MONTHS, 1)
-                        || slicd_job_first (&j, SLICD_MONTHS, 3, 12, 1) <= 12))
-                return -SLICD_ERR_IMPOSSIBLE_DATE;
-        }
-        else
-        {
-            if (!(slicd_job_has (&j, SLICD_MONTHS, 1)
-                        || slicd_job_has (&j, SLICD_MONTHS, 3)
-                        || slicd_job_has (&j, SLICD_MONTHS, 5)
-                        || slicd_job_has (&j, SLICD_MONTHS, 7)
-                        || slicd_job_has (&j, SLICD_MONTHS, 8)
-                        || slicd_job_has (&j, SLICD_MONTHS, 10)
-                        || slicd_job_has (&j, SLICD_MONTHS, 12)))
-                return -SLICD_ERR_IMPOSSIBLE_DATE;
-        }
+        username = s;
+        for (i = 0; *s != '\0' && !is_blank (*s); ++s, ++i)
+            ;
+        skip_blanks (s);
     }
+    if (i == 0)
+        return -SLICD_ERR_NO_USERNAME;
+    if (*s == '\0')
+        return -SLICD_ERR_SYNTAX;
 
-    {
-        int len;
-
-        if (username)
-            i = strlen (username);
-        else
-        {
-            username = s;
-            for (i = 0; *s != '\0' && !is_blank (*s); ++s, ++i)
-                ;
-            skip_blanks (s);
-        }
-        if (i == 0)
-            return -SLICD_ERR_NO_USERNAME;
-        if (*s == '\0')
-            return -SLICD_ERR_SYNTAX;
-
-        for (len = strlen (s); is_blank (s[len - 1]); --len)
-            ;
+    for (len = strlen (s); is_blank (s[len - 1]); --len)
+        ;
 
-        if (!stralloc_readyplus (&slicd->str, i + 1 + len + 1)
-                || !genalloc_readyplus (slicd_job_t, &slicd->jobs, 1))
-            return -SLICD_ERR_MEMORY;
+    if (!stralloc_readyplus (&slicd->str, i + 1 + len + 1)
+            || !genalloc_readyplus (slicd_job_t, &slicd->jobs, 1))
+        return -SLICD_ERR_MEMORY;
 
-        j.offset = slicd->str.len;
-        stralloc_catb (&slicd->str, username, i);
-        stralloc_catb (&slicd->str, ":", 1);
-        stralloc_catb (&slicd->str, s, len);
-        stralloc_0 (&slicd->str);
-        genalloc_catb (slicd_job_t, &slicd->jobs, &j, 1);
+    j.offset = slicd->str.len;
+    stralloc_catb (&slicd->str, username, i);
+    stralloc_catb (&slicd->str, ":", 1);
+    stralloc_catb (&slicd->str, s, len);
+    stralloc_0 (&slicd->str);
+    genalloc_append (slicd_job_t, &slicd->jobs, &j);
 
-        return 1;
-    }
+    return 1;
 }
diff --git a/src/libslicd/slicd_job_ensure_valid.c b/src/libslicd/slicd_job_ensure_valid.c
new file mode 100644
index 0000000..2eda4b3
--- /dev/null
+++ b/src/libslicd/slicd_job_ensure_valid.c
@@ -0,0 +1,89 @@
+/*
+ * slicd - Copyright (C) 2015 Olivier Brunel
+ *
+ * slicd_job_ensure_valid.c
+ * Copyright (C) 2015 Olivier Brunel <jjk@jjacky.com>
+ *
+ * This file is part of slicd.
+ *
+ * slicd is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * slicd is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * slicd. If not, see http://www.gnu.org/licenses/
+ */
+
+#include <slicd/job.h>
+#include <slicd/fields.h>
+#include <slicd/err.h>
+
+
+int
+slicd_job_ensure_valid (slicd_job_t *job)
+{
+    int i;
+
+    for (i = 0; i < 5; ++i)
+        if (slicd_job_first (job, i, _slicd_fields[i].adjust,
+                    _slicd_fields[i].max + _slicd_fields[i].adjust, 1)
+                > _slicd_fields[i].max + _slicd_fields[i].adjust)
+            return -SLICD_ERR_NO_MATCH;
+
+    /* special case: days combo */
+    if (slicd_job_first (job, SLICD_DAYS_OF_WEEK, 0, 6, 0) <= 6)
+    {
+        /* there is a restriction on DOW, now let's check how the first 6 days
+         * are set:
+         * - all set    = same as '*', no restriction on DAYS
+         * - none set   = invalid
+         * - a mix      = DAYS_COMBO
+         */
+
+        if (slicd_job_first (job, SLICD_DAYS, 1, 6, 0) == 7)
+        {
+            slicd_job_set (job, SLICD_DAYS, 1, 31);
+            slicd_job_set_days_combo (job, 0);
+        }
+        else if (slicd_job_first (job, SLICD_DAYS, 1, 6, 1) == 7)
+            return -SLICD_ERR_DAYS_COMBO;
+        else
+            slicd_job_set_days_combo (job, 1);
+    }
+    else
+        slicd_job_set_days_combo (job, 0);
+
+    /* ensure date validity/coherence */
+    if (slicd_job_first (job, SLICD_DAYS, 1, 29, 1) == 30)
+    {
+        /* none of the first 29 days are set, so we need to do some checking:
+         * if day 30 is set, that there's a month other than Feb,
+         * else (i.e. day 31 is set) that there's at least one matching month
+         */
+        if (slicd_job_has (job, SLICD_DAYS, 30))
+        {
+            if (!(slicd_job_has (job, SLICD_MONTHS, 1)
+                        || slicd_job_first (job, SLICD_MONTHS, 3, 12, 1) <= 12))
+                return -SLICD_ERR_IMPOSSIBLE_DATE;
+        }
+        else
+        {
+            if (!(slicd_job_has (job, SLICD_MONTHS, 1)
+                        || slicd_job_has (job, SLICD_MONTHS, 3)
+                        || slicd_job_has (job, SLICD_MONTHS, 5)
+                        || slicd_job_has (job, SLICD_MONTHS, 7)
+                        || slicd_job_has (job, SLICD_MONTHS, 8)
+                        || slicd_job_has (job, SLICD_MONTHS, 10)
+                        || slicd_job_has (job, SLICD_MONTHS, 12)))
+                return -SLICD_ERR_IMPOSSIBLE_DATE;
+        }
+    }
+
+    return 0;
+}
diff --git a/src/libslicd/slicd_load.c b/src/libslicd/slicd_load.c
index 9ce9d17..32ad9bd 100644
--- a/src/libslicd/slicd_load.c
+++ b/src/libslicd/slicd_load.c
@@ -25,6 +25,7 @@
 #include <skalibs/uint32.h>
 #include <skalibs/djbunix.h>
 #include <slicd/slicd.h>
+#include <slicd/job.h>
 #include <slicd/err.h>
 
 int
@@ -101,6 +102,26 @@ slicd_load (slicd_t *slicd, const char *file)
         slicd->jobs.len += r;
     }
 
+    /* ensure loaded data are valid */
+    {
+        int i;
+
+        for (i = 0; i < genalloc_len (slicd_job_t, &slicd->jobs); ++i)
+        {
+            slicd_job_t *job = &genalloc_s (slicd_job_t, &slicd->jobs)[i];
+
+            if (job->offset >= slicd->str.len)
+            {
+                r = -SLICD_ERR_INVALID_JOB;
+                goto err;
+            }
+
+            r = slicd_job_ensure_valid (job);
+            if (r < 0)
+                goto err;
+        }
+    }
+
 err:
     {
         int e = errno;