[geary/geary-0.13] Merge branch 'wip/282-composer-quoted-email' into 'master'



commit 733d1636b02077700b05a0e26e8a28588a45c97c
Author: Michael Gratton <mike vee net>
Date:   Sat Mar 2 04:20:01 2019 +0000

    Merge branch 'wip/282-composer-quoted-email' into 'master'
    
    Fix RFC822 mailbox names with commas breaking composer address entry
    
    Closes #282
    
    See merge request GNOME/geary!159
    
    (cherry picked from commit 8e93acbc3c4dc842310bef4f0235094686c83af2)
    
    9ba7c75c Add some tests for decoding/encoding quoted names in RFC822 mailboxes
    ecb91d15 Ensure Smtp.ClientSession is quoting RCPT addresses correctly
    a5beccc6 Fix RFC822 mailbox names with commas breaking composer address entry

 src/engine/rfc822/rfc822-mailbox-address.vala  | 23 ++++++++++++++++++-----
 src/engine/smtp/smtp-client-session.vala       |  2 +-
 test/engine/rfc822-mailbox-address-test.vala   | 20 +++++++++++++++++++-
 test/engine/rfc822-mailbox-addresses-test.vala | 14 +++++++++++++-
 4 files changed, 51 insertions(+), 8 deletions(-)
---
diff --git a/src/engine/rfc822/rfc822-mailbox-address.vala b/src/engine/rfc822/rfc822-mailbox-address.vala
index 869ca76a..a1864baf 100644
--- a/src/engine/rfc822/rfc822-mailbox-address.vala
+++ b/src/engine/rfc822/rfc822-mailbox-address.vala
@@ -49,6 +49,15 @@ public class Geary.RFC822.MailboxAddress :
         return GMime.utils_header_decode_text(prepare_header_text_part(mailbox));
     }
 
+    private static bool display_name_needs_quoting(string name) {
+        // Currently we only care if the name contains a comma, since
+        // that will screw up the composer's address entry fields. See
+        // issue #282. This might be able to be removed when the
+        // composer doesn't parse recipients as a text list of
+        // addresses.
+        return (name.index_of(",") != -1);
+    }
+
     private static bool local_part_needs_quoting(string local_part) {
         bool needs_quote = false;
         bool is_dot = false;
@@ -74,13 +83,13 @@ public class Geary.RFC822.MailboxAddress :
         return needs_quote || is_dot; // no trailing dots
     }
 
-    private static string quote_local_part(string local_part) {
+    private static string quote_string(string needs_quoting) {
         StringBuilder builder = new StringBuilder();
-        if (!String.is_empty(local_part)) {
+        if (!String.is_empty(needs_quoting)) {
             builder.append_c('"');
             int index = 0;
             for (;;) {
-                char ch = local_part[index++];
+                char ch = needs_quoting[index++];
                 if (ch == String.EOS)
                     break;
 
@@ -251,7 +260,8 @@ public class Geary.RFC822.MailboxAddress :
      * address) and {@link address} parts, suitable for display to
      * people. The string will have white space reduced and
      * non-printable characters removed, and the address will be
-     * surrounded by angle brackets if a name is present.
+     * surrounded by angle brackets if a name is present, and if the
+     * name contains a reserved character, it will be quoted.
      *
      * If you need a form suitable for sending a message, see {@link
      * to_rfc822_string} instead.
@@ -269,6 +279,9 @@ public class Geary.RFC822.MailboxAddress :
      */
     public string to_full_display(string open = "<", string close = ">") {
         string clean_name = Geary.String.reduce_whitespace(this.name);
+        if (display_name_needs_quoting(clean_name)) {
+            clean_name = quote_string(clean_name);
+        }
         string clean_address = Geary.String.reduce_whitespace(this.address);
         return (!has_distinct_name() || is_spoofed())
             ? clean_address
@@ -430,7 +443,7 @@ public class Geary.RFC822.MailboxAddress :
         // manually.
         string local_part = GMime.utils_header_encode_text(this.mailbox);
         if (local_part_needs_quoting(local_part)) {
-            local_part = quote_local_part(local_part);
+            local_part = quote_string(local_part);
         }
         return "%s@%s".printf(
             local_part,
diff --git a/src/engine/smtp/smtp-client-session.vala b/src/engine/smtp/smtp-client-session.vala
index 8ae3093a..5d58db9e 100644
--- a/src/engine/smtp/smtp-client-session.vala
+++ b/src/engine/smtp/smtp-client-session.vala
@@ -217,7 +217,7 @@ public class Geary.Smtp.ClientSession {
         
         // TODO: Support mailbox groups
         foreach (RFC822.MailboxAddress mailbox in addrlist) {
-            RcptRequest rcpt_request = new RcptRequest.plain(mailbox.address);
+            RcptRequest rcpt_request = new RcptRequest.plain(mailbox.to_rfc822_address());
             Response response = yield cx.transaction_async(rcpt_request, cancellable);
 
             if (!response.code.is_success_completed()) {
diff --git a/test/engine/rfc822-mailbox-address-test.vala b/test/engine/rfc822-mailbox-address-test.vala
index 501706ad..761cf796 100644
--- a/test/engine/rfc822-mailbox-address-test.vala
+++ b/test/engine/rfc822-mailbox-address-test.vala
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016-2018 Michael Gratton <mike vee net>
+ * Copyright 2016-2019 Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
  * (version 2.1 or later). See the COPYING file in this distribution.
@@ -38,6 +38,8 @@ class Geary.RFC822.MailboxAddressTest : TestCase {
         assert(Geary.RFC822.MailboxAddress.is_valid_address("test@") == false);
         assert(Geary.RFC822.MailboxAddress.is_valid_address("@") == false);
         assert(Geary.RFC822.MailboxAddress.is_valid_address("") == false);
+
+        assert(Geary.RFC822.MailboxAddress.is_valid_address("\"Surname, Name\" <mail example com>") == true);
     }
 
     public void unescaped_constructor() throws Error {
@@ -193,6 +195,11 @@ class Geary.RFC822.MailboxAddressTest : TestCase {
                "example example com");
         assert(new MailboxAddress("Test", "example@example example com").to_full_display() ==
                "example@example example com");
+
+        assert_string(
+            "\"Testerson, Test\" <test example com>",
+            new MailboxAddress("Testerson, Test", "test example com").to_full_display()
+        );
     }
 
     public void to_short_display() throws Error {
@@ -260,6 +267,17 @@ class Geary.RFC822.MailboxAddressTest : TestCase {
                "=?iso-8859-1?b?qQ==?= <example example com>");
         assert(new MailboxAddress("😸", "example example com").to_rfc822_string() ==
                "=?UTF-8?b?8J+YuA==?= <example example com>");
+
+        assert_string(
+            "\"Surname, Name\" <example example com>",
+            new MailboxAddress("Surname, Name", "example example com").to_rfc822_string()
+        );
+        assert_string(
+            "\"Surname, Name\" <example example com>",
+            new MailboxAddress
+            .from_rfc822_string("\"Surname, Name\" <example example com>")
+            .to_rfc822_string()
+        );
     }
 
     public void equal_to() throws GLib.Error {
diff --git a/test/engine/rfc822-mailbox-addresses-test.vala b/test/engine/rfc822-mailbox-addresses-test.vala
index 45853a0a..6c3a59b1 100644
--- a/test/engine/rfc822-mailbox-addresses-test.vala
+++ b/test/engine/rfc822-mailbox-addresses-test.vala
@@ -1,5 +1,5 @@
 /*
- * Copyright 2018 Michael Gratton <mike vee net>
+ * Copyright 2018-2019 Michael Gratton <mike vee net>
  *
  * This software is licensed under the GNU Lesser General Public License
  * (version 2.1 or later). See the COPYING file in this distribution.
@@ -10,6 +10,7 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
     public MailboxAddressesTest() {
         base("Geary.RFC822.MailboxAddressesTest");
         add_test("from_rfc822_string_encoded", from_rfc822_string_encoded);
+        add_test("from_rfc822_string_quoted", from_rfc822_string_quoted);
         add_test("to_rfc822_string", to_rfc822_string);
     }
 
@@ -29,6 +30,17 @@ class Geary.RFC822.MailboxAddressesTest : TestCase {
         assert(addrs.size == 2);
     }
 
+    public void from_rfc822_string_quoted() throws GLib.Error {
+        MailboxAddresses addrs = new MailboxAddresses.from_rfc822_string(
+            "\"Surname, Name\" <mail example com>"
+        ) ;
+        assert_int(1, addrs.size);
+        assert_string("Surname, Name", addrs[0].name);
+        assert_string("mail example com", addrs[0].address);
+
+        assert_string("\"Surname, Name\" <mail example com>", addrs.to_rfc822_string());
+    }
+
     public void to_rfc822_string() throws Error {
         assert(new MailboxAddresses().to_rfc822_string() == "");
         assert(new_addreses({ "test1 example com" })


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