]> diplodocus.org Git - nmh/blobdiff - sbr/datetime.c
Fix invalid pointer arithmetic.
[nmh] / sbr / datetime.c
index bcf1a9a62c343831206a04a376cf7ac5d3273cc3..a7906a52063bd5c23ad7b12adf509be5dabd5943 100644 (file)
@@ -88,8 +88,6 @@ parse_datetime (const char *datetime, const char *zone, bool dst,
        the entire day.  The time fields of the tws struct were
        initialized to 0 by the memset() above. */
     if (items_matched >= 6  ||  items_matched == 3) {
-        int offset = atoi (zone ? zone : "0");
-
         /* struct tws defines tw_mon over [0, 11]. */
         --tws->tw_mon;
 
@@ -106,7 +104,11 @@ parse_datetime (const char *datetime, const char *zone, bool dst,
            - the only flag in tw_flags used is TW_DST
          */
         tws->tw_yday = tws->tw_clock = 0;
-        tws->tw_zone = 60 * (offset / 100)  +  offset % 100;
+        if (zone) {
+            int offset = atoi(zone);
+            tws->tw_zone = 60 * (offset / 100)  +  offset % 100;
+        } else
+            tws->tw_zone = 0;
         if (dst) {
             tws->tw_zone -= 60;  /* per dlocaltime() */
             tws->tw_flags |= TW_DST;
@@ -171,19 +173,19 @@ load_timezones (const contentline *clines) {
 
                 if (in_standard) { in_standard = false; }
                 else if (in_daylight) { in_daylight = false; }
-                if (parse_datetime (params->dtstart, params->offsetfrom,
-                                    in_daylight,
-                                    &tws) == OK) {
-                    if (tws.tw_year >= 1970) {
-                        /* dmktime() falls apart for, e.g., the year 1601. */
-                        params->start_dt = tws.tw_clock;
-                    }
-                } else {
+
+                if (parse_datetime(params->dtstart, params->offsetfrom,
+                    in_daylight, &tws) != OK) {
                     inform("failed to parse start time %s for %s",
-                            params->dtstart,
-                            in_daylight ? "daylight" : "standard");
+                        params->dtstart,
+                        in_daylight ? "daylight" : "standard");
                     return NULL;
                 }
+
+                if (tws.tw_year >= 1970) {
+                    /* dmktime() falls apart for, e.g., the year 1601. */
+                    params->start_dt = tws.tw_clock;
+                }
                 params = NULL;
             } else if (! strcasecmp ("DTSTART", node->name)) {
                 /* Save DTSTART for use after getting TZOFFSETFROM. */
@@ -358,11 +360,11 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
     if (! dt_timezone) {
         /* Form #1: DATE WITH LOCAL TIME, i.e., no time zone, or
            Form #2: DATE WITH UTC TIME */
-        if (parse_datetime (node->value, NULL, false, &tws[0]) == OK) {
-            return strdup (dasctime (&tws[0], 0));
+        if (parse_datetime(node->value, NULL, false, &tws[0]) != OK) {
+            inform("unable to parse datetime %s", node->value);
+            return NULL;
         }
-        inform("unable to parse datetime %s", node->value);
-        return NULL;
+        return strdup (dasctime (&tws[0], 0));
     }
 
     /*
@@ -380,13 +382,12 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
         if (tz->tzid  &&  ! strcasecmp (dt_timezone, tz->tzid)) { break; }
     }
 
-    if (tz) {
-        free(dt_timezone);
-    } else {
+    if (!tz) {
         inform("did not find VTIMEZONE section for %s", dt_timezone);
         free(dt_timezone);
         return NULL;
     }
+    free(dt_timezone);
 
     /* Determine if it's Daylight Saving. */
     tp_std = strchr (tz->standard_params.dtstart, 'T');
@@ -431,28 +432,23 @@ format_datetime (tzdesc_t timezones, const contentline *node) {
             return NULL;
         }
 
-        if (parse_datetime (node->value, tz->standard_params.offsetto,
-                            false, &tws[0]) == OK) {
-            dt[0] = tws[0].tw_clock;
-        } else {
+        if (parse_datetime(node->value, tz->standard_params.offsetto,
+            false, &tws[0]) != OK) {
             inform("unable to parse datetime %s", node->value);
             return NULL;
         }
+        dt[0] = tws[0].tw_clock;
 
         if (tp_dst) {
             if (dt[0] < transition[1]) {
                 dst = 0;
             } else {
-                if (parse_datetime (node->value,
-                                    tz->daylight_params.offsetto, true,
-                                    &tws[1]) == OK) {
-                    dt[1] = tws[1].tw_clock;
-                } else {
-                    inform("unable to parse datetime %s",
-                            node->value);
+                if (parse_datetime(node->value,
+                    tz->daylight_params.offsetto, true, &tws[1]) != OK) {
+                    inform("unable to parse datetime %s", node->value);
                     return NULL;
                 }
-
+                dt[1] = tws[1].tw_clock;
                 dst = dt[1] <= transition[0];
             }
         }