From ea57345a5c5f00fe85801b3f528687b93793afff Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 9 Jun 2010 20:06:51 -0400 Subject: [PATCH] soup_date_new_from_string: fix an out-of-bounds memory access soup_date_new_from_string() would sometimes read off the end of the string, but tests/date didn't catch this even under valgrind, because all of the strings were compile-time constants and they got laid out in a way that never triggered a read of invalid memory. So tweak the test to g_strdup each string before parsing it, which will let valgrind notice if we read outside its bounds in the future. https://bugzilla.gnome.org/show_bug.cgi?id=620288 --- libsoup/soup-date.c | 8 ++++---- tests/date.c | 25 +++++++++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/libsoup/soup-date.c b/libsoup/soup-date.c index ce99ec5..25bb761 100644 --- a/libsoup/soup-date.c +++ b/libsoup/soup-date.c @@ -355,7 +355,10 @@ parse_time (SoupDate *date, const char **date_string) static inline gboolean parse_timezone (SoupDate *date, const char **date_string) { - if (**date_string == '+' || **date_string == '-') { + if (!**date_string) { + date->utc = FALSE; + date->offset = 0; + } else if (**date_string == '+' || **date_string == '-') { gulong val; int sign = (**date_string == '+') ? -1 : 1; val = strtoul (*date_string + 1, (char **)date_string, 10); @@ -381,9 +384,6 @@ parse_timezone (SoupDate *date, const char **date_string) if ((*date_string)[1] == 'D') date->offset += 60; date->utc = FALSE; - } else if (!**date_string) { - date->utc = FALSE; - date->offset = 0; } else return FALSE; return TRUE; diff --git a/tests/date.c b/tests/date.c index 4e97d8a..aef9c66 100644 --- a/tests/date.c +++ b/tests/date.c @@ -13,6 +13,23 @@ static gboolean check_ok (const char *strdate, SoupDate *date); +static SoupDate * +make_date (const char *strdate) +{ + char *dup; + SoupDate *date; + + /* We do it this way so that if soup_date_new_from_string() + * reads off the end of the string, it will trigger an error + * when valgrinding, rather than just reading the start of the + * next const string. + */ + dup = g_strdup (strdate); + date = soup_date_new_from_string (dup); + g_free (dup); + return date; +} + static const struct { SoupDateFormat format; const char *date; @@ -31,7 +48,7 @@ check_good (SoupDateFormat format, const char *strdate) SoupDate *date; char *strdate2; - date = soup_date_new_from_string (strdate); + date = make_date (strdate); if (date) strdate2 = soup_date_to_string (date, format); if (!check_ok (strdate, date)) @@ -282,7 +299,7 @@ check_conversion (const struct conversion *conv) char *str; debug_printf (2, "%s\n", conv->source); - date = soup_date_new_from_string (conv->source); + date = make_date (conv->source); if (!date) { debug_printf (1, " date parsing failed for '%s'.\n", conv->source); errors++; @@ -359,12 +376,12 @@ main (int argc, char **argv) debug_printf (1, "\nOK dates:\n"); for (i = 0; i < G_N_ELEMENTS (ok_dates); i++) - check_ok (ok_dates[i], soup_date_new_from_string (ok_dates[i])); + check_ok (ok_dates[i], make_date (ok_dates[i])); check_ok (TIME_T_STRING, soup_date_new_from_time_t (TIME_T)); debug_printf (1, "\nBad dates:\n"); for (i = 0; i < G_N_ELEMENTS (bad_dates); i++) - check_bad (bad_dates[i], soup_date_new_from_string (bad_dates[i])); + check_bad (bad_dates[i], make_date (bad_dates[i])); debug_printf (1, "\nConversions:\n"); for (i = 0; i < G_N_ELEMENTS (conversions); i++) -- 2.7.4