clamp the result to the time_t range, and document that. Remove the #ifdef
authorDan Winship <danw@src.gnome.org>
Thu, 7 Feb 2008 01:38:15 +0000 (01:38 +0000)
committerDan Winship <danw@src.gnome.org>
Thu, 7 Feb 2008 01:38:15 +0000 (01:38 +0000)
* libsoup/soup-date.c (soup_date_to_time_t): clamp the result to
the time_t range, and document that. Remove the #ifdef HAVE_TIMEGM
branch.

* configure.in: remove check for timegm

svn path=/trunk/; revision=1074

ChangeLog
configure.in
libsoup/soup-date.c

index fa49751..b42981a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-02-06  Dan Winship  <danw@gnome.org>
+
+       * libsoup/soup-date.c (soup_date_to_time_t): clamp the result to
+       the time_t range, and document that. Remove the #ifdef HAVE_TIMEGM
+       branch.
+
+       * configure.in: remove check for timegm
+
 2008-02-04  Dan Winship  <danw@gnome.org>
 
        * libsoup/Makefile.am: Fix the handling of soup-enum-types.h to
index e22a346..8dfc91b 100644 (file)
@@ -109,7 +109,6 @@ dnl *******************
 dnl *** Misc checks ***
 dnl *******************
 AC_CHECK_FUNCS(gmtime_r)
-AC_CHECK_FUNCS(timegm)
 
 dnl *********************************
 dnl *** Networking library checks ***
index 52fcbd4..beffc96 100644 (file)
@@ -501,51 +501,46 @@ soup_date_to_string (SoupDate *date, SoupDateFormat format)
  * soup_date_to_time_t:
  * @date: a #SoupDate
  *
- * Converts @date to a %time_t
+ * Converts @date to a %time_t.
+ *
+ * If @date is not representable as a %time_t, it will be clamped into
+ * range. (In particular, some HTTP cookies have expiration dates
+ * after "Y2.038k" (2038-01-19T03:14:07Z).)
  *
  * Return value: @date as a %time_t
  **/
 time_t
 soup_date_to_time_t (SoupDate *date)
 {
-#ifndef HAVE_TIMEGM
        time_t tt;
        static const int days_before[] = {
                0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
        };
-#endif
-       struct tm tm;
 
        /* FIXME: offset, etc */
 
-       tm.tm_year = date->year - 1900;
-       tm.tm_mon  = date->month - 1;
-       tm.tm_mday = date->day;
-       tm.tm_hour = date->hour;
-       tm.tm_min  = date->minute;
-       tm.tm_sec  = date->second;
+       if (date->year < 1970)
+               return 0;
 
-#if HAVE_TIMEGM
-       return timegm (&tm);
-#else
-       /* We check the month because (a) if we don't, the
-        * days_before[] part below may access random memory, and (b)
-        * soup_date_parse() doesn't check the return value of
-        * parse_month(). The caller is responsible for ensuring the
-        * sanity of everything else.
+       /* If the year is later than 2038, we're guaranteed to
+        * overflow a 32-bit time_t. (If it's exactly 2038, we'll
+        * *probably* overflow, but only by a little, and it's easiest
+        * to test that at the end by seeing if the result has turned
+        * negative.)
         */
-       if (tm.tm_mon < 0 || tm.tm_mon > 11)
-               return (time_t)-1;
+       if (sizeof (time_t) == 4 && date->year > 2038)
+               return (time_t)0x7fffffff;
 
-       tt = (tm.tm_year - 70) * 365;
-       tt += (tm.tm_year - 68) / 4;
-       tt += days_before[tm.tm_mon] + tm.tm_mday - 1;
-       if (tm.tm_year % 4 == 0 && tm.tm_mon < 2)
+       tt = (date->year - 1970) * 365;
+       tt += (date->year - 1968) / 4;
+       tt += days_before[date->month - 1] + date->day - 1;
+       if (date->year % 4 == 0 && date->month <= 2)
                tt--;
-       tt = ((((tt * 24) + tm.tm_hour) * 60) + tm.tm_min) * 60 + tm.tm_sec;
-       
+       tt = ((((tt * 24) + date->hour) * 60) + date->minute) * 60 + date->second;
+
+       if (sizeof (time_t) == 4 && tt < 0)
+               return (time_t)0x7fffffff;
        return tt;
-#endif
 }
 
 /**