contacts: support encoding names with '"', ',' etc.

This commit is contained in:
Dirk-Jan C. Binnema 2022-05-06 09:03:11 +03:00
parent e0d047105b
commit ffce3dda21
3 changed files with 47 additions and 6 deletions

View File

@ -20,19 +20,33 @@
#include "mu-contact.hh" #include "mu-contact.hh"
#include "mu-message.hh" #include "mu-message.hh"
#include "utils/mu-utils.hh" #include "utils/mu-utils.hh"
#include "mu-mime-object.hh"
#include <gmime/gmime.h> #include <gmime/gmime.h>
#include <glib.h> #include <glib.h>
#include <string>
using namespace Mu; using namespace Mu;
std::string static bool
Contact::display_name() const needs_quoting(const std::string& name)
{ {
for (auto& c: name)
if (c == ',' || c == '"')
return true;
return false;
}
std::string
Contact::display_name(bool quote) const
{
if (name.empty()) if (name.empty())
return email; return email;
else else if (!quote || !needs_quoting(name))
return name + " <" + email + '>'; return name + " <" + email + '>';
else
return address_rfc2047(*this);
} }
std::string std::string
@ -131,6 +145,29 @@ test_ctor_cleanup()
assert_equal(c.display_name(), "Bli ky <bar@example.com>"); assert_equal(c.display_name(), "Bli ky <bar@example.com>");
} }
static void
test_encode()
{
Contact c{
"cassius@example.com",
"Ali, Muhammad \"The Greatest\"",
345,
false, /* personal */
333, /*freq*/
768 /* tstamp */
};
assert_equal(c.email, "cassius@example.com");
assert_equal(c.name, "Ali, Muhammad \"The Greatest\"");
g_assert_false(c.personal);
g_assert_cmpuint(c.frequency,==,333);
g_assert_cmpuint(c.tstamp,==,768);
g_assert_cmpuint(c.message_date,==,345);
assert_equal(c.display_name(true),
"\"Ali, Muhammad \\\"The Greatest\\\"\" <cassius@example.com>");
}
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
@ -141,6 +178,7 @@ main(int argc, char* argv[])
g_test_add_func("/message/contact/ctor-foo", test_ctor_foo); g_test_add_func("/message/contact/ctor-foo", test_ctor_foo);
g_test_add_func("/message/contact/ctor-blinky", test_ctor_blinky); g_test_add_func("/message/contact/ctor-blinky", test_ctor_blinky);
g_test_add_func("/message/contact/ctor-cleanup", test_ctor_cleanup); g_test_add_func("/message/contact/ctor-cleanup", test_ctor_cleanup);
g_test_add_func("/message/contact/encode", test_encode);
return g_test_run(); return g_test_run();
} }

View File

@ -88,9 +88,13 @@ struct Contact {
* Jane Doe <email@example.com> * Jane Doe <email@example.com>
* otherwise it's just the e-mail address. * otherwise it's just the e-mail address.
* *
* @param quote_if_needed if true, handle quoting of the name-part as well. This
* is useful when the address is to be used directly in emails.
*
* @return the display name * @return the display name
*/ */
std::string display_name() const; std::string display_name(bool quote_if_needed=false) const;
/** /**
* Operator==; based on the hash values (ie. lowercase e-mail address) * Operator==; based on the hash values (ie. lowercase e-mail address)
@ -160,7 +164,6 @@ private:
} }
}; };
constexpr Option<Contact::Type> constexpr Option<Contact::Type>
contact_type_from_field_id(Field::Id id) noexcept { contact_type_from_field_id(Field::Id id) noexcept {

View File

@ -547,7 +547,7 @@ Server::Private::contacts_handler(const Parameters& params)
Sexp::List contact; Sexp::List contact;
contact.add_prop(":address", contact.add_prop(":address",
Sexp::make_string(ci.display_name())); Sexp::make_string(ci.display_name(true/*encode-if-needed*/)));
contact.add_prop(":rank", Sexp::make_number(rank)); contact.add_prop(":rank", Sexp::make_number(rank));
contacts.add(Sexp::make_list(std::move(contact))); contacts.add(Sexp::make_list(std::move(contact)));