diff --git c/postler/postler-bureau.vala i/postler/postler-bureau.vala index 3346223..cb0bc2c 100644 --- c/postler/postler-bureau.vala +++ i/postler/postler-bureau.vala @@ -903,7 +903,7 @@ public class Postler.Bureau : Gtk.Window { string body = ( "From: Zeus\nTo: You, Hera , Ares , Aphrodite ," + "Artemis , Hephaistos , Poseidon , Dionisos ," - + "Apollo , Hermes , Athena , Demeter , " + + "Apollo , \"Hermes, Mercury\" , Athena , Demeter , " + "Hestia \nCC: Hades , Herkules , Uranus , Nyx \n" + "Subject: Regarding nudity on the Olympus\n" + "Date: Fri, 28 May 2010 23:27:35 +0200\n" diff --git c/postler/postler-contact.vala i/postler/postler-contact.vala index 8bdfb29..3f5e692 100644 --- c/postler/postler-contact.vala +++ i/postler/postler-contact.vala @@ -13,6 +13,7 @@ namespace Postler { public class Contact { public string display_name; public GLib.File? avatar; + static Regex contact_regex = null; public Contact (string display_name, GLib.File? avatar) { this.display_name = display_name; @@ -26,29 +27,36 @@ namespace Postler { return { address, address }; } - if (!(">" in address && "<" in address)) - return { address, address }; - - long greater = address.length - 1; - while (address[greater] != '>') - greater--; - long lower = greater; - while (address[lower] != '<') - lower--; - - string recipient = address.slice (lower + 1, greater); - if (recipient.has_prefix ("mailto:")) - recipient = recipient.substring (7, -1); - if (lower == 0) - return { recipient, recipient }; - if (">" in recipient) - return { recipient, recipient }; + if (contact_regex == null) { + /* Taken from http://www.regular-expressions.info/email.html; + added possibility of "mailto:" */ + var valid_email_address_regex = + """(mailto:)?(?[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4})"""; + var possibly_invalid_email_address_regex = """(mailto:)?(?.+)"""; + try { + contact_regex = new Regex ( + """^\s*((("(?.*)"|'(?.*)'|(?.*)))?\s*<%s>|%s)\s*$""" + .printf (valid_email_address_regex, + possibly_invalid_email_address_regex), + GLib.RegexCompileFlags.CASELESS | GLib.RegexCompileFlags.DUPNAMES); + } + catch (GLib.RegexError error) { + GLib.critical ("parse: could not parse regular expression: %s", error.message); + return { address, address }; + } + } - /* Remove double or single quotes around the name */ - long first = address.has_prefix ("'") || address.has_prefix ("\"") ? 1 : 0; - return { address.substring (first, lower - 1) - .replace ("\\\"", "`") - .replace ("' ", "").replace ("\"", "").chomp (), recipient }; + MatchInfo mi; + if (contact_regex.match (address, 0, out mi)) { + var email = mi.fetch_named ("EMAIL") ?? address; + var name = mi.fetch_named ("NAME") ?? email; + name = name.replace ("\\\"", "`"); + return { name , email }; + } + else { + GLib.warning ("parse: could not parse address %s", address); + return { address, address }; + } } public static string address_from_string (string contact) { @@ -69,6 +77,34 @@ namespace Postler { return true; return false; } + + public static string[] quoted_split (string? comma_separated_list) { + var retval = new string[0]; + if (comma_separated_list != null) { + var cur = ""; + foreach (var s in comma_separated_list.split (",")) { + if (cur == "") { + cur = s; + } + else { + cur += "," + s; + } + bool quot_open = false; + for (var tail = cur.chr (-1, '"'); tail != null; + tail = tail[1:-1].chr (-1, '"')) { + quot_open = !quot_open; + } + if (!quot_open && cur != "") { + retval += cur; + cur = ""; + } + } + if (cur != "") { + retval += cur; + } + } + return retval; + } } } diff --git c/postler/postler-content.vala i/postler/postler-content.vala index c0f35e5..826b9ea 100644 --- c/postler/postler-content.vala +++ i/postler/postler-content.vala @@ -216,7 +216,7 @@ public class Postler.Content : WebKit.WebView { string arguments = parts[1] != null ? ("?" + parts[1]) : ""; int count = 0; - foreach (string address in addresses.split (",")) { + foreach (string address in Contact.quoted_split (addresses)) { if (address == "") continue; if (!address.contains ("@")) { diff --git c/postler/postler-message.vala i/postler/postler-message.vala index b9f43fb..143816f 100644 --- c/postler/postler-message.vala +++ i/postler/postler-message.vala @@ -378,12 +378,18 @@ namespace Postler { Also Reply-To may equal From, which is at best confusing. */ if (reply_to != null) { string canonical = Postler.Contact.address_from_string (reply_to); - if (Postler.Contact.equal (canonical, get_field ("to"))) - reply_to = null; - else if (Postler.Contact.equal (canonical, get_field ("list-post"))) + foreach (var r in Postler.Contact.quoted_split (recipients)) { + if (Postler.Contact.equal (canonical, r)) { + reply_to = null; + break; + } + } + if (Postler.Contact.equal (canonical, get_field ("list-post"))) { reply_to = null; - else if (Postler.Contact.equal (canonical, sender)) + } + else if (Postler.Contact.equal (canonical, sender)) { reply_to = null; + } } if (id == null) diff --git c/postler/postler-recipiententry.vala i/postler/postler-recipiententry.vala index a9ec771..24a5d74 100644 --- c/postler/postler-recipiententry.vala +++ i/postler/postler-recipiententry.vala @@ -139,7 +139,7 @@ namespace Postler { void buttonize_text () { if (entry.text.chr (-1, '@') != null) { - string[] addresses = entry.text.split (","); + string[] addresses = Postler.Contact.quoted_split (entry.text); entry.text = ""; foreach (string address in addresses) add_address (address);