[dovecot-cvs] dovecot: If utc_mktime() fails, it doesn't mean that the IMAP da...

dovecot at dovecot.org dovecot at dovecot.org
Tue Jun 12 18:03:44 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/bbd2b811d3e6
changeset: 5700:bbd2b811d3e6
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jun 12 18:03:37 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 01b90449db90 -r bbd2b811d3e6 src/lib-imap/imap-date.c
--- a/src/lib-imap/imap-date.c	Tue Jun 12 17:12:42 2007 +0300
+++ b/src/lib-imap/imap-date.c	Tue Jun 12 18:03:37 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 01b90449db90 -r bbd2b811d3e6 src/lib-imap/imap-date.h
--- a/src/lib-imap/imap-date.h	Tue Jun 12 17:12:42 2007 +0300
+++ b/src/lib-imap/imap-date.h	Tue Jun 12 18:03:37 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