]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: replace strptime()/timegm()/mktime() with GDateTime APIs set
authorDaniel P. Berrangé <berrange@redhat.com>
Mon, 23 Dec 2019 15:37:26 +0000 (15:37 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Fri, 3 Jan 2020 15:42:13 +0000 (15:42 +0000)
All places where we use strptime/timegm()/mktime() are handling
conversion of dates in a format compatible with ISO 8601, so we
can use the GDateTime APIs to simplify code.

Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/conf/domain_conf.c
src/esx/esx_vi_types.c
src/vz/vz_sdk.c

index afa072e17d4bd068e37680c0c369b78df36c167f..ee33b7caf0d2f5982c40f7eb70c7243c1d6dffa3 100644 (file)
@@ -13673,33 +13673,17 @@ virDomainGraphicsAuthDefParseXML(xmlNodePtr node,
 
     validTo = virXMLPropString(node, "passwdValidTo");
     if (validTo) {
-        char *tmp;
-        struct tm tm;
-        memset(&tm, 0, sizeof(tm));
-        /* Expect: YYYY-MM-DDTHH:MM:SS (%d-%d-%dT%d:%d:%d)  eg 2010-11-28T14:29:01 */
-        if (/* year */
-            virStrToLong_i(validTo, &tmp, 10, &tm.tm_year) < 0 || *tmp != '-' ||
-            /* month */
-            virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mon) < 0 || *tmp != '-' ||
-            /* day */
-            virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_mday) < 0 || *tmp != 'T' ||
-            /* hour */
-            virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_hour) < 0 || *tmp != ':' ||
-            /* minute */
-            virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_min) < 0 || *tmp != ':' ||
-            /* second */
-            virStrToLong_i(tmp+1, &tmp, 10, &tm.tm_sec) < 0 || *tmp != '\0') {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("cannot parse password validity time '%s', expect YYYY-MM-DDTHH:MM:SS"),
-                           validTo);
-            VIR_FREE(def->passwd);
+        g_autoptr(GDateTime) then = NULL;
+        g_autoptr(GTimeZone) tz = g_time_zone_new_utc();
+
+        then = g_date_time_new_from_iso8601(validTo, tz);
+        if (!then) {
+            virReportError(VIR_ERR_INVALID_ARG,
+                           _("password validity time '%s' values out of range"), validTo);
             return -1;
         }
 
-        tm.tm_year -= 1900; /* Human epoch starts at 0 BC, not 1900BC */
-        tm.tm_mon--; /* Humans start months at 1, computers at 0 */
-
-        def->validTo = timegm(&tm);
+        def->validTo = (int)g_date_time_to_unix(then);
         def->expires = true;
     }
 
index 1deb5026b7ac4fec20a6d0acc09b04d38868bc76..434313dfa4cd4e950a36322b6512160d5a12eb1f 100644 (file)
@@ -1473,27 +1473,14 @@ int
 esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
                                      long long *secondsSinceEpoch)
 {
-    char value[64] = "";
-    char *tmp;
-    struct tm tm;
-    int milliseconds;
-    char sign;
-    int tz_hours;
-    int tz_minutes;
-    int tz_offset = 0;
+    g_autoptr(GDateTime) then = NULL;
+    g_autoptr(GTimeZone) tz = NULL;
 
     if (!dateTime || !secondsSinceEpoch) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
         return -1;
     }
 
-    if (virStrcpyStatic(value, dateTime->value) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("xsd:dateTime value '%s' too long for destination"),
-                       dateTime->value);
-        return -1;
-    }
-
     /*
      * expected format: [-]CCYY-MM-DDTHH:MM:SS[.ssssss][((+|-)HH:MM|Z)]
      * typical example: 2010-04-05T12:13:55.316789+02:00
@@ -1502,66 +1489,22 @@ esxVI_DateTime_ConvertToCalendarTime(esxVI_DateTime *dateTime,
      *
      * map negative years to 0, since the base for time_t is the year 1970.
      */
-    if (*value == '-') {
+    if (*(dateTime->value) == '-') {
         *secondsSinceEpoch = 0;
         return 0;
     }
 
-    tmp = strptime(value, "%Y-%m-%dT%H:%M:%S", &tm);
+    tz = g_time_zone_new_utc();
+    then = g_date_time_new_from_iso8601(dateTime->value, tz);
 
-    if (!tmp) {
+    if (!then) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("xsd:dateTime value '%s' has unexpected format"),
                        dateTime->value);
         return -1;
     }
 
-    if (*tmp != '\0') {
-        /* skip .ssssss part if present */
-        if (*tmp == '.' &&
-            virStrToLong_i(tmp + 1, &tmp, 10, &milliseconds) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("xsd:dateTime value '%s' has unexpected format"),
-                           dateTime->value);
-            return -1;
-        }
-
-        /* parse timezone offset if present. if missing assume UTC */
-        if (*tmp == '+' || *tmp == '-') {
-            sign = *tmp;
-
-            if (virStrToLong_i(tmp + 1, &tmp, 10, &tz_hours) < 0 ||
-                *tmp != ':' ||
-                virStrToLong_i(tmp + 1, NULL, 10, &tz_minutes) < 0) {
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("xsd:dateTime value '%s' has unexpected format"),
-                               dateTime->value);
-                return -1;
-            }
-
-            tz_offset = tz_hours * 60 * 60 + tz_minutes * 60;
-
-            if (sign == '-')
-                tz_offset = -tz_offset;
-        } else if (STREQ(tmp, "Z")) {
-            /* Z refers to UTC. tz_offset is already initialized to zero */
-        } else {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("xsd:dateTime value '%s' has unexpected format"),
-                           dateTime->value);
-            return -1;
-        }
-    }
-
-    /*
-     * xsd:dateTime represents local time relative to the optional timezone
-     * given as offset. pretend the local time is in UTC and use timegm in
-     * order to avoid interference with the timezone to this computer.
-     * apply timezone correction afterwards, because it's simpler than
-     * handling all the possible over- and underflows when trying to apply
-     * it to the tm struct.
-     */
-    *secondsSinceEpoch = timegm(&tm) - tz_offset;
+    *secondsSinceEpoch = g_date_time_to_unix(then);
 
     return 0;
 }
index 59d7d3141956abc020e3f785db698d09c9cc7067..c98542c244cb095bb7fbbea5f4f502ec314703a3 100644 (file)
@@ -4607,17 +4607,17 @@ int prlsdkSetMemsize(virDomainObjPtr dom, unsigned int memsize)
 static long long
 prlsdkParseDateTime(const char *str)
 {
-    struct tm tm;
-    const char *tmp;
+    g_autoptr(GDateTime) then = NULL;
+    g_autoptr(GTimeZone) tz = g_time_zone_new_local();
 
-    tmp = strptime(str, "%Y-%m-%d %H:%M:%S", &tm);
-    if (!tmp || *tmp != '\0') {
+    then = g_date_time_new_from_iso8601(str, tz);
+    if (!then) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected DateTime format: '%s'"), str);
         return -1;
     }
 
-    return mktime(&tm);
+    return g_date_time_to_unix(then);
 }
 
 static virDomainSnapshotObjListPtr