summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2010-06-09 20:06:51 -0400
committerDan Winship <danw@gnome.org>2010-06-09 20:10:59 -0400
commitea57345a5c5f00fe85801b3f528687b93793afff (patch)
treeff071f9abde002e07a983be7186293386ff6f290
parentceceaa912cd02660eecacd52d9a1ffc4d15c3c00 (diff)
downloadlibsoup-ea57345a5c5f00fe85801b3f528687b93793afff.tar.gz
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
-rw-r--r--libsoup/soup-date.c8
-rw-r--r--tests/date.c25
2 files changed, 25 insertions, 8 deletions
diff --git a/libsoup/soup-date.c b/libsoup/soup-date.c
index ce99ec5b..25bb761f 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 4e97d8ac..aef9c663 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++)