[gmime] Fixed parse_broken_date() to always return 0 on garbage input
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime] Fixed parse_broken_date() to always return 0 on garbage input
- Date: Sun, 12 Mar 2017 12:12:25 +0000 (UTC)
commit 5c7b6a60c177e56b1f75ac7e8fe1d2d7bf636ae5
Author: Jeffrey Stedfast <jestedfa microsoft com>
Date: Sun Mar 12 08:10:45 2017 -0400
Fixed parse_broken_date() to always return 0 on garbage input
Fixes bug #779923
gmime/gmime-utils.c | 42 +++++++++++++++++++++++++++---------------
tests/test-mime.c | 16 +++++++++++-----
2 files changed, 38 insertions(+), 20 deletions(-)
---
diff --git a/gmime/gmime-utils.c b/gmime/gmime-utils.c
index 1f085fc..443c213 100644
--- a/gmime/gmime-utils.c
+++ b/gmime/gmime-utils.c
@@ -519,8 +519,6 @@ parse_rfc822_date (date_token *tokens, int *tzone)
struct tm tm;
time_t t;
- g_return_val_if_fail (tokens != NULL, (time_t) 0);
-
token = tokens;
memset ((void *) &tm, 0, sizeof (struct tm));
@@ -592,34 +590,41 @@ parse_rfc822_date (date_token *tokens, int *tzone)
#define is_tzone_numeric(t) (((date_token_mask (t) & DATE_TOKEN_NON_TIMEZONE_NUMERIC) == 0) &&
(date_token_mask (t) & DATE_TOKEN_HAS_SIGN))
#define is_tzone(t) (is_tzone_alpha (t) || is_tzone_numeric (t))
+#define YEAR (1 << 0)
+#define MONTH (1 << 1)
+#define DAY (1 << 2)
+#define WEEKDAY (1 << 3)
+#define TIME (1 << 4)
+#define TZONE (1 << 5)
+
static time_t
parse_broken_date (date_token *tokens, int *tzone)
{
- gboolean got_wday, got_month, got_tzone;
int hour, min, sec, offset, n;
date_token *token;
struct tm tm;
time_t t;
+ int mask;
memset ((void *) &tm, 0, sizeof (struct tm));
- got_wday = got_month = got_tzone = FALSE;
offset = 0;
+ mask = 0;
token = tokens;
while (token) {
- if (is_weekday (token) && !got_wday) {
+ if (is_weekday (token) && !(mask & WEEKDAY)) {
if ((n = get_wday (token->start, token->len)) != -1) {
d(printf ("weekday; "));
- got_wday = TRUE;
+ mask |= WEEKDAY;
tm.tm_wday = n;
goto next;
}
}
- if (is_month (token) && !got_month) {
+ if (is_month (token) && !(mask & MONTH)) {
if ((n = get_month (token->start, token->len)) != -1) {
d(printf ("month; "));
- got_month = TRUE;
+ mask |= MONTH;
tm.tm_mon = n;
goto next;
}
@@ -631,48 +636,52 @@ parse_broken_date (date_token *tokens, int *tzone)
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
+ mask |= TIME;
goto next;
}
}
- if (is_tzone (token) && !got_tzone) {
+ if (is_tzone (token) && !(mask & TZONE)) {
date_token *t = token;
if ((n = get_tzone (&t)) != -1) {
d(printf ("tzone; "));
- got_tzone = TRUE;
+ mask |= TZONE;
offset = n;
goto next;
}
}
if (is_numeric (token)) {
- if (token->len == 4 && !tm.tm_year) {
+ if (token->len == 4 && !(mask & YEAR)) {
if ((n = get_year (token->start, token->len)) != -1) {
d(printf ("year; "));
tm.tm_year = n - 1900;
+ mask |= YEAR;
goto next;
}
} else {
/* Note: assumes MM-DD-YY ordering if '0 < MM < 12' holds true */
- if (!got_month && token->next && is_numeric (token->next)) {
+ if (!(mask & MONTH) && token->next && is_numeric (token->next)) {
if ((n = decode_int (token->start, token->len)) > 12) {
goto mday;
} else if (n > 0) {
d(printf ("mon; "));
- got_month = TRUE;
tm.tm_mon = n - 1;
+ mask |= MONTH;
}
goto next;
- } else if (!tm.tm_mday && (n = get_mday (token->start, token->len)) != -1) {
+ } else if (!(mask & DAY) && (n = get_mday (token->start, token->len)) != -1) {
mday:
d(printf ("mday; "));
tm.tm_mday = n;
+ mask |= DAY;
goto next;
- } else if (!tm.tm_year) {
+ } else if (!(mask & YEAR)) {
if ((n = get_year (token->start, token->len)) != -1) {
d(printf ("2-digit year; "));
tm.tm_year = n - 1900;
+ mask |= YEAR;
}
goto next;
}
@@ -688,6 +697,9 @@ parse_broken_date (date_token *tokens, int *tzone)
d(printf ("\n"));
+ if (!(mask & (YEAR | MONTH | DAY | TIME)))
+ return 0;
+
t = mktime_utc (&tm);
/* t is now GMT of the time we want, but not offset by the timezone ... */
diff --git a/tests/test-mime.c b/tests/test-mime.c
index d613268..34bf6cc 100644
--- a/tests/test-mime.c
+++ b/tests/test-mime.c
@@ -305,18 +305,21 @@ static struct {
{ "17-6-2008 17:10:08",
"Tue, 17 Jun 2008 17:10:08 +0000",
1213722608, 0 },
+ { "nonsense",
+ "Thu, 01 Jan 1970 00:00:00 +0000",
+ 0, 0 }
};
static void
test_date_parser (void)
{
+ Exception *ex;
time_t date;
int tzone;
char *buf;
guint i;
for (i = 0; i < G_N_ELEMENTS (dates); i++) {
- buf = NULL;
testsuite_check ("Date: '%s'", dates[i].in);
try {
date = g_mime_utils_header_decode_date (dates[i].in, &tzone);
@@ -328,16 +331,19 @@ test_date_parser (void)
throw (exception_new ("timezones do not match"));
buf = g_mime_utils_header_format_date (date, tzone);
- if (strcmp (dates[i].out, buf) != 0)
- throw (exception_new ("date strings do not match"));
+ if (strcmp (dates[i].out, buf) != 0) {
+ ex = exception_new ("date strings do not match: %s", buf);
+ g_free (buf);
+ throw (ex);
+ }
+
+ g_free (buf);
testsuite_check_passed ();
} catch (ex) {
testsuite_check_failed ("Date: '%s': %s", dates[i].in,
ex->message);
} finally;
-
- g_free (buf);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]