[libsoup] soup_date_new_from_string: fix an out-of-bounds memory access



commit ea57345a5c5f00fe85801b3f528687b93793afff
Author: Dan Winship <danw gnome org>
Date:   Wed Jun 9 20:06:51 2010 -0400

    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++)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]