[dovecot-cvs] dovecot-1.0: If utc_mktime() fails, it doesn't mean that the IMA...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jun 12 18:03:40 EEST 2007
details: http://hg.dovecot.org/dovecot-1.0/rev/2460c70d1ffb
changeset: 5297:2460c70d1ffb
user: Timo Sirainen <tss at iki.fi>
date: Tue Jun 12 18:03:36 2007 +0300
description:
If utc_mktime() fails, it doesn't mean that the IMAP date was invalid.
Instead the year is just too low or too high to fit to time_t. If this
happens, use the lowest/highest allowed value instead of returning failure.
diffstat:
2 files changed, 35 insertions(+), 8 deletions(-)
src/lib-imap/imap-date.c | 37 ++++++++++++++++++++++++++++++-------
src/lib-imap/imap-date.h | 6 +++++-
diffs (77 lines):
diff -r fe4a89b2a548 -r 2460c70d1ffb src/lib-imap/imap-date.c
--- a/src/lib-imap/imap-date.c Tue Jun 12 16:59:42 2007 +0300
+++ b/src/lib-imap/imap-date.c Tue Jun 12 18:03:36 2007 +0300
@@ -79,6 +79,32 @@ static const char *imap_parse_date_inter
return str;
}
+static bool imap_mktime(struct tm *tm, time_t *time_r)
+{
+ *time_r = utc_mktime(tm);
+ if (*time_r != (time_t)-1)
+ return TRUE;
+
+ /* the date is outside valid range for time_t. it might still be
+ technically valid though, so try to handle this case.
+ with 64bit time_t the full 0..9999 year range is valid. */
+ if (tm->tm_year <= 100) {
+ /* too old. time_t can be signed or unsigned, handle
+ both cases. */
+ *time_r = (time_t)-1 < (int)0 ? INT_MIN : 0;
+ } else {
+ /* too high. return the highest allowed value.
+ we shouldn't get here with 64bit time_t,
+ but handle that anyway. */
+#if (TIME_T_MAX_BITS == 32 || TIME_T_MAX_BITS == 64)
+ *time_r = (1UL << (TIME_T_MAX_BITS-1)) - 1;
+#else
+ *time_r = (1UL << TIME_T_MAX_BITS) - 1;
+#endif
+ }
+ return FALSE;
+}
+
bool imap_parse_date(const char *str, time_t *time)
{
struct tm tm;
@@ -88,8 +114,8 @@ bool imap_parse_date(const char *str, ti
return FALSE;
tm.tm_isdst = -1;
- *time = utc_mktime(&tm);
- return *time != (time_t)-1;
+ (void)imap_mktime(&tm, time);
+ return TRUE;
}
bool imap_parse_datetime(const char *str, time_t *time, int *timezone_offset)
@@ -126,11 +152,8 @@ bool imap_parse_datetime(const char *str
*timezone_offset = parse_timezone(str);
tm.tm_isdst = -1;
- *time = utc_mktime(&tm);
- if (*time == (time_t)-1)
- return FALSE;
-
- *time -= *timezone_offset * 60;
+ if (imap_mktime(&tm, time))
+ *time -= *timezone_offset * 60;
return TRUE;
}
diff -r fe4a89b2a548 -r 2460c70d1ffb src/lib-imap/imap-date.h
--- a/src/lib-imap/imap-date.h Tue Jun 12 16:59:42 2007 +0300
+++ b/src/lib-imap/imap-date.h Tue Jun 12 18:03:36 2007 +0300
@@ -3,7 +3,11 @@
/* Parses IMAP date/time string. time_t is filled with UTC date.
timezone_offset is filled with parsed timezone. If no timezone is given,
- local timezone is assumed. */
+ local timezone is assumed.
+
+ Returns TRUE if string is valid. If date is outside valid range for time_t
+ (usually only with 32bit time_t), the function still return TRUE but
+ returned time is (time_t)-1. */
bool imap_parse_date(const char *str, time_t *time);
bool imap_parse_datetime(const char *str, time_t *time, int *timezone_offset);
More information about the dovecot-cvs
mailing list