[evolution-data-server] Bug #347520 - Names containing a dot in address parsed incorrectly



commit a27b2b09b09cba9eacdd6ecf236fbdcd52300d1a
Author: Milan Crha <mcrha redhat com>
Date:   Fri Oct 8 09:31:00 2010 +0200

    Bug #347520 - Names containing a dot in address parsed incorrectly

 camel/camel-mime-utils.c       |   25 +++++++++++++++++++++
 camel/tests/lib/address-data.h |   27 +++++++++++++++++++++++
 camel/tests/lib/camel-test.c   |    1 +
 camel/tests/message/test2.c    |   47 ++++++++++++++++++++++++++++++++++++++-
 4 files changed, 98 insertions(+), 2 deletions(-)
---
diff --git a/camel/camel-mime-utils.c b/camel/camel-mime-utils.c
index 4fcc3a1..0c05717 100644
--- a/camel/camel-mime-utils.c
+++ b/camel/camel-mime-utils.c
@@ -2476,6 +2476,8 @@ header_decode_mailbox (const gchar **in, const gchar *charset)
 		/* Another fix for seriously-broken-mailers */
 		if (*inptr && *inptr != ',') {
 			gchar *text;
+			const gchar *name_part;
+			gboolean in_quote;
 
 			w(g_warning("We didn't get an '@' where we expected in '%s', trying again", *in));
 			w(g_warning("Name is '%s', Addr is '%s' we're at '%s'\n", name?name->str:"<UNSET>", addr->str, inptr));
@@ -2486,6 +2488,29 @@ header_decode_mailbox (const gchar **in, const gchar *charset)
 			else
 				g_string_append_c (addr, *inptr);
 
+			name_part = *in;
+			in_quote = FALSE;
+			while (*name_part && *name_part != ',') {
+				if (*name_part == '\"')
+					in_quote = !in_quote;
+				else if (!in_quote && *name_part == '<')
+					break;
+				name_part++;
+			}
+
+			if (*name_part == '<' && ((!strchr (name_part, ',') && strchr (name_part, '>')) || (strchr (name_part, ',') > strchr (name_part, '>')))) {
+				/* it's of a form "display-name <addr-spec>" */
+				if (name)
+					g_string_free (name, TRUE);
+				name = NULL;
+				g_string_free (addr, TRUE);
+
+				if (name_part == *in)
+					addr = g_string_new ("");
+				else
+					addr = g_string_new_len (*in, name_part - *in - (camel_mime_is_lwsp (name_part[-1]) ? 1 : 0));
+			}
+
 			/* check for address is encoded word ... */
 			text = camel_header_decode_string (addr->str, charset);
 			if (name == NULL) {
diff --git a/camel/tests/lib/address-data.h b/camel/tests/lib/address-data.h
index dcc4b86..9fe9dd8 100644
--- a/camel/tests/lib/address-data.h
+++ b/camel/tests/lib/address-data.h
@@ -94,3 +94,30 @@ static struct _l {
 	{ "gb2312", "ǨÒƵ½×°Êδ°¿Ú¹ÜÀí³ÌÐò(AfterStep, Enlightenment, FVWM, IceWM, SawMill)" },
 	{ "big5", "µøµ¡ºÞ²zªÌ¥u²¾°Ê¸Ë¹¢µøµ¡\n(AfterStep, Enlightenment, FVWM, IceWM, Sawmill)" },
 };
+
+static struct _d {
+	const gchar *name;
+	const gchar *email;
+} test_decode[] = {
+	{ NULL,                   "email example com" },
+	{ NULL,                   "your email example com" },
+	{ "Your",                 "email example com" },
+	{ "Your Email",           "email example com" },
+	{ "Mr Smith Black",       "smith black com" },
+	{ "Mr. Smith Black",      "smith black com" },
+	{ "Mr. Smith O. Black",   "smith o black com" },
+	{ "Joe d'Magio",          "joe d example com" },
+	{ "example.com address",  "email example com" },
+	{ "email at example.com", "email example com" },
+	{ "email.at.example.com", "email example com" }
+};
+
+static struct _ldf {
+	const gchar *with_name;
+	const gchar *without_name;
+} line_decode_formats[] = {
+	{"%s <%s>",      "%s" },
+	{ "%s<%s>",      "%s" },
+	{ "\"%s\" <%s>", " <%s>"},
+	{ "\"%s\"<%s>",  "<%s>"}
+};
diff --git a/camel/tests/lib/camel-test.c b/camel/tests/lib/camel-test.c
index fe026c4..3344d2a 100644
--- a/camel/tests/lib/camel-test.c
+++ b/camel/tests/lib/camel-test.c
@@ -99,6 +99,7 @@ camel_test_init (gint argc, gchar **argv)
 
 	setup = 1;
 
+	g_type_init ();
 	/* yeah, we do need ot thread init, even though camel isn't compiled with enable threads */
 	g_thread_init (NULL);
 
diff --git a/camel/tests/message/test2.c b/camel/tests/message/test2.c
index d2546c8..372788f 100644
--- a/camel/tests/message/test2.c
+++ b/camel/tests/message/test2.c
@@ -74,6 +74,24 @@ fail:
 	return out;
 }
 
+static void
+check_address_line_decode (gint i, const gchar *line, const gchar *name, const gchar *email)
+{
+	CamelInternetAddress *addr;
+	const gchar *dname, *demail;
+
+	push ("Testing address line %d '%s'", i, line);
+	dname = NULL;
+	demail = NULL;
+	addr = camel_internet_address_new ();
+	check (camel_address_decode (CAMEL_ADDRESS (addr), line) == 1);
+	check (camel_internet_address_get (CAMEL_INTERNET_ADDRESS (addr), 0, &dname, &demail));
+	check_msg (g_strcmp0 (dname, name) == 0  || (!name && dname && !*dname), "decoded name = '%s', but should be '%s'", dname, name);
+	check_msg (g_strcmp0 (demail, email) == 0, "decoded email = '%s', but should be '%s'", demail, email);
+	check_unref (addr, 1);
+	pull ();
+}
+
 #define to_utf8(in, type) convert(in, type, "utf-8")
 #define from_utf8(in, type) convert(in, "utf-8", type)
 
@@ -317,8 +335,33 @@ gint main (gint argc, gchar **argv)
 
 	camel_test_end ();
 
-	/* FIXME: Add test of decoding of broken addresses */
+	camel_test_start ("CamelInternerAddress name & email decoder");
+
+	for (i = 0; i < G_N_ELEMENTS (test_decode); i++) {
+		gchar *line;
+		const gchar *name, *email;
+		gint jj;
+
+		name = test_decode[i].name;
+		email = test_decode[i].email;
+
+		for (jj = 0; jj < G_N_ELEMENTS (line_decode_formats); jj++) {
+			if (line_decode_formats[jj].without_name) {
+				line = g_strdup_printf (line_decode_formats[jj].without_name, email);
+				check_address_line_decode (i, line, NULL, email);
+				g_free (line);
+			}
+
+			if (!name)
+				continue;
+
+			line = g_strdup_printf (line_decode_formats[jj].with_name, name, email);
+			check_address_line_decode (i, line, name, email);
+			g_free (line);
+		}
+	}
+
+	camel_test_end();
 
 	return 0;
 }
-



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