On x86 we allow "overflows" around 1969/1970 but not for other dates.
Fixes #509.
tm_year += (tm_year < 50) ? 2000 : 1900;
}
- /* prevent large 32 bit integer overflows */
- if (sizeof(time_t) == 4 && tm_year > 2038)
+ /* prevent obvious 32 bit integer overflows */
+ if (sizeof(time_t) == 4 && (tm_year > 2038 || tm_year < 1901))
{
return TIME_32_BIT_SIGNED_MAX;
}
tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec - tz_offset;
- /* has a 32 bit signed integer overflow occurred? */
- return (tm_secs < 0) ? TIME_32_BIT_SIGNED_MAX : tm_secs;
+ if (sizeof(time_t) == 4)
+ { /* has a 32 bit signed integer overflow occurred? */
+ if (tm_year > 1970 && tm_secs < 0)
+ { /* depending on the time zone, the first days in 1970 may result in
+ * a negative value, but dates after 1970 never will */
+ return TIME_32_BIT_SIGNED_MAX;
+ }
+ if (tm_year < 1969 && tm_secs > 0)
+ { /* similarly, tm_secs is not positive for dates before 1970, except
+ * for the last days in 1969, depending on the time zone */
+ return TIME_32_BIT_SIGNED_MAX;
+ }
+ }
+ return tm_secs;
}
/**
/**
* Converts an ASN.1 UTCTIME or GENERALIZEDTIME string to time_t
*
+ * On systems where sizeof(time_t) == 4 there will be an overflow
+ * for dates
+ * > Tue, 19 Jan 2038 03:14:07 UTC (0x7fffffff)
+ * and
+ * < Fri, 13 Dec 1901 20:45:52 UTC (0x80000000)
+ * in both cases TIME_32_BIT_SIGNED_MAX is returned.
+ *
* @param utctime body of an ASN.1 coded time object
* @param type ASN1_UTCTIME or ASN1_GENERALIZEDTIME
* @return time_t in UTC
{ 0, 0x17, "7001010260Z" },
{ 0, 0x17, "7001010203-1Z" },
{ 0, 0x17, "700101020361Z" },
+ { -631152000, 0x17, "500101000000Z" }, /* UTCTime min */
+ { 59, 0x17, "691231235959-0001" },
+ { -1, 0x17, "691231235959Z" },
+ { 0, 0x17, "700101000000Z" },
+ { -60, 0x17, "700101000000+0001" },
+ { 2524607999UL, 0x17, "491231235959Z" }, /* UTCTime max */
{ 5097600, 0x17, "7003010000Z" },
{ 68256000, 0x17, "7203010000Z" },
{ 951868800, 0x17, "0003010000Z" },