]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fuzz-calendarspec: increase coverage by calculating occurences
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 9 May 2022 07:49:27 +0000 (09:49 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 10 May 2022 11:06:32 +0000 (13:06 +0200)
Coverage data shows that we didn't test calendar_spec_next_usec() and
associated functions at all.

The input samples so far were only used until the first NUL. We take advantage
of that by using the part until the second NUL as the starting timestamp,
retaining backwards compatibility for how the first part is used.

src/fuzz/fuzz-calendarspec.c
test/fuzz/fuzz-calendarspec/input1 [new file with mode: 0644]

index 07d3fbca7f053dad7de68ff8e051dc1eb56c02ba..ea027b8f66e7b2d8d8d554893f645734a46b4bfd 100644 (file)
@@ -4,19 +4,54 @@
 #include "calendarspec.h"
 #include "fd-util.h"
 #include "fuzz.h"
+#include "string-util.h"
+#include "time-util.h"
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(calendar_spec_freep) CalendarSpec *cspec = NULL;
-        _cleanup_free_ char *str = NULL, *p = NULL;
+        _cleanup_free_ char *str = NULL;
+        int r;
 
         if (!getenv("SYSTEMD_LOG_LEVEL"))
                 log_set_max_level(LOG_CRIT);
 
         str = memdup_suffix0(data, size);
 
-        if (calendar_spec_from_string(str, &cspec) >= 0) {
-                (void) calendar_spec_valid(cspec);
-                (void) calendar_spec_to_string(cspec, &p);
+        size_t l1 = strlen(str);
+        const char* usecs = l1 < size ? str + l1 + 1 : "";
+
+        r = calendar_spec_from_string(str, &cspec);
+        if (r < 0) {
+                log_debug_errno(r, "Failed to parse \"%s\": %m", str);
+                return 0;
+        }
+
+        _cleanup_free_ char *p = NULL;
+        assert_se(calendar_spec_valid(cspec));
+        assert_se(calendar_spec_to_string(cspec, &p) == 0);
+        assert(p);
+
+        log_debug("spec: %s → %s", str, p);
+
+        _cleanup_(calendar_spec_freep) CalendarSpec *cspec2 = NULL;
+        assert_se(calendar_spec_from_string(p, &cspec2) >= 0);
+        assert_se(calendar_spec_valid(cspec2));
+
+        usec_t usec = 0;
+        (void) parse_time(usecs, &usec, 1);
+
+        /* If timezone is set, calendar_spec_next_usec() would fork, bleh :(
+         * Let's not try that. */
+        cspec->timezone = mfree(cspec->timezone);
+
+        log_debug("00: %s", strna(FORMAT_TIMESTAMP(usec)));
+        for (unsigned i = 1; i <= 20; i++) {
+                r = calendar_spec_next_usec(cspec, usec, &usec);
+                if (r < 0) {
+                        log_debug_errno(r, "%02u: %m", i);
+                        break;
+                }
+                log_debug("%02u: %s", i, FORMAT_TIMESTAMP(usec));
         }
 
         return 0;
diff --git a/test/fuzz/fuzz-calendarspec/input1 b/test/fuzz/fuzz-calendarspec/input1
new file mode 100644 (file)
index 0000000..00522a7
Binary files /dev/null and b/test/fuzz/fuzz-calendarspec/input1 differ