rewtguy/pidgin

658471e41d75
Parents 03ad128b5361
Children
Add some additional tests to purple_str_to_time and address their failures.

Testing Done:
Ran the unit tests with all sorts of values for `TZ` and made sure they passed.

Bugs closed: PIDGIN-17552

Reviewed at https://reviews.imfreedom.org/r/931/
--- a/libpurple/tests/test_util.c Wed Sep 29 16:36:42 2021 -0500
+++ b/libpurple/tests/test_util.c Wed Oct 06 04:04:56 2021 -0500
@@ -160,23 +160,51 @@
long tz_off;
const char *rest;
time_t timestamp;
+ gchar *oldtz = g_strdup(g_getenv("TZ"));
+
+ timestamp = purple_str_to_time("2010-08-27.134202-0700PDT", FALSE, &tm, &tz_off, &rest);
+ fail_unless(1282941722 == timestamp);
+ fail_unless((-7 * 60 * 60) == tz_off);
+ assert_string_equal("PDT", rest);
fail_unless(377182200 == purple_str_to_time("19811214T12:50:00", TRUE, NULL, NULL, NULL));
- fail_unless(377203800 == purple_str_to_time("19811214T12:50:00-06", FALSE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21", TRUE, NULL, NULL, NULL));
fail_unless(1282941722 == purple_str_to_time("2010-08-27.204202", TRUE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21.3234", TRUE, NULL, NULL, NULL));
fail_unless(1175919261 == purple_str_to_time("20070407T04:14:21Z", TRUE, NULL, NULL, NULL));
fail_unless(1631512800 == purple_str_to_time("09-13-2021", TRUE, NULL, NULL, NULL));
- timestamp = purple_str_to_time("2010-08-27.134202-0700PDT", FALSE, &tm, &tz_off, &rest);
- fail_unless(1282941722 == timestamp);
- fail_unless((-7 * 60 * 60) == tz_off);
- assert_string_equal("PDT", rest);
+ /* For testing local time we use Asia/Kathmandu because it's +05:45 and
+ * doesn't have DST which means the test should always pass regardless of
+ * the time of year, at least until Kathmandu changes something.
+ */
+ g_setenv("TZ", "Asia/Kathmandu", TRUE);
+
+ /* There's a timezone in this timestamp, so the returned value will be in
+ * UTC with the offset added/subtracted.
+ */
+ fail_unless(377203800 == purple_str_to_time("19811214T12:50:00-06", FALSE, NULL, NULL, NULL));
+
+ /* This also has a tz, so the returned value will be utc with the given
+ * offset.
+ */
+ fail_unless(1569746481 == purple_str_to_time("2019-09-29T08:41:21.401000+00:00", FALSE, NULL, NULL, NULL));
+ /* while it looks like the time is specified, this time is not valid
+ * according to our parser, so it's just the date which will be handled by
+ * localtime.
+ */
timestamp = purple_str_to_time("09/13/202115:34:34", TRUE, NULL, NULL, &rest);
- fail_unless(1631512800 == timestamp);
+ fail_unless(1631470500 == timestamp);
assert_string_equal("15:34:34", rest);
+
+ /* finally revert the TZ environment variable */
+ if(oldtz != NULL) {
+ g_setenv("TZ", oldtz, TRUE);
+ g_free(oldtz);
+ } else {
+ g_unsetenv("TZ");
+ }
}
END_TEST
--- a/libpurple/util.c Wed Sep 29 16:36:42 2021 -0500
+++ b/libpurple/util.c Wed Oct 06 04:04:56 2021 -0500
@@ -756,6 +756,7 @@
GMatchInfo *info = NULL;
gboolean mktime_with_utc = FALSE, matched = FALSE;
gchar *match = NULL;
+ gchar *hours = NULL, *minutes = NULL, *seconds = NULL;
struct tm t;
long tzoff = PURPLE_NO_TZ_OFF;
time_t retval;
@@ -818,83 +819,80 @@
g_free(match);
/* get the hour */
- match = g_match_info_fetch_named(info, "hours");
- if(match != NULL && *match != '\0') {
- t.tm_hour = atoi(match);
- }
- g_free(match);
-
- /* get the minutes */
- match = g_match_info_fetch_named(info, "minutes");
- if(match != NULL && *match != '\0') {
- t.tm_min = atoi(match);
- }
- g_free(match);
-
- /* get the seconds */
- match = g_match_info_fetch_named(info, "seconds");
- if(match != NULL && *match != '\0') {
- t.tm_sec = atoi(match);
- }
- g_free(match);
-
- /* check if this is utc time */
- match = g_match_info_fetch_named(info, "utc");
- if(match != NULL && *match != '\0') {
- tzoff = 0;
- g_free(match);
- } else {
- /* free match if it was just an empty string */
- g_free(match);
-
- /* if match is null, check if we have tzsign which is required */
- match = g_match_info_fetch_named(info, "tzsign");
- if(match != NULL) {
- gint tzsign = -1, tzhour = 0, tzminute = 0;
-
- /* Figure out if we're ahead or behind of utc, assuming ahead by
- * default.
- */
- if(*match == '+') {
- tzsign = -1;
- }
+ hours = g_match_info_fetch_named(info, "hours");
+ minutes = g_match_info_fetch_named(info, "minutes");
+ seconds = g_match_info_fetch_named(info, "seconds");
+
+ if(hours != NULL && *hours != '\0' &&
+ minutes != NULL && *minutes != '\0' &&
+ seconds != NULL && *seconds != '\0')
+ {
+ t.tm_hour = atoi(hours);
+ t.tm_min = atoi(minutes);
+ t.tm_sec = atoi(seconds);
+
+ /* check if this is utc time */
+ match = g_match_info_fetch_named(info, "utc");
+ if(match != NULL && *match != '\0') {
+ g_free(match);
+
+ tzoff = 0;
+ mktime_with_utc = TRUE;
+ } else {
+ /* free match if it was just an empty string */
g_free(match);
- /* get the tz hour */
- match = g_match_info_fetch_named(info, "tzhour");
- if(match != NULL && *match != '\0') {
- tzhour = atoi(match);
- }
- g_free(match);
-
- /* get the tz minute */
- match = g_match_info_fetch_named(info, "tzminute");
- if(match != NULL && *match != '\0') {
- tzminute = atoi(match);
- }
- g_free(match);
-
- /* we need at least either an hour or minute to offset the timezone */
- if(tzhour > 0 || tzminute > 0) {
+ /* if match is null, check if we have tzsign which is required */
+ match = g_match_info_fetch_named(info, "tzsign");
+ if(match != NULL) {
+ gint tzsign = -1, tzhour = 0, tzminute = 0;
+
+ /* Figure out if we're ahead or behind of utc, assuming ahead by
+ * default.
+ */
+ if(*match == '+') {
+ tzsign = 1;
+ }
+ g_free(match);
+
+ /* get the tz hour */
+ match = g_match_info_fetch_named(info, "tzhour");
+ if(match != NULL && *match != '\0') {
+ tzhour = atoi(match);
+ }
+ g_free(match);
+
+ /* get the tz minute */
+ match = g_match_info_fetch_named(info, "tzminute");
+ if(match != NULL && *match != '\0') {
+ tzminute = atoi(match);
+ }
+ g_free(match);
+
+ /* if the timezone is utc +00:00 or -00:00 tzoff will multiple out to
+ * be zero like it should be.
+ */
mktime_with_utc = TRUE;
tzoff = tzsign * ((tzhour * 3600) + (tzminute * 60));
}
}
- }
-
- /* If we have a time, figure out if we need to adjust our tz offset. */
- if(t.tm_hour > 0 || t.tm_min > 0 || t.tm_sec > 0) {
+
+ /* If we have a time, figure out if we need to adjust our tz offset. */
if(!mktime_with_utc) {
if(utc) {
mktime_with_utc = TRUE;
tzoff = 0;
} else {
/* Local Time */
- t.tm_isdst = -1;
+ t.tm_isdst = -1; /* -1 means dst info is not available */
}
}
}
+ g_free(hours);
+ g_free(minutes);
+ g_free(seconds);
+
if(mktime_with_utc) {
retval = mktime_utc(&t);
} else {