diff options
Diffstat (limited to 'libsoup/soup-date.c')
-rw-r--r-- | libsoup/soup-date.c | 49 |
1 files changed, 22 insertions, 27 deletions
diff --git a/libsoup/soup-date.c b/libsoup/soup-date.c index 52fcbd4f..beffc967 100644 --- a/libsoup/soup-date.c +++ b/libsoup/soup-date.c @@ -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 } /** |