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-message.hh"
#include "utils/mu-utils.hh"
#include "mu-mime-object.hh"
#include <gmime/gmime.h>
#include <glib.h>
#include <string>
using namespace Mu;
std::string
Contact::display_name() const
static bool
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())
return email;
else
else if (!quote || !needs_quoting(name))
return name + " <" + email + '>';
else
return address_rfc2047(*this);
}
std::string
@ -131,6 +145,29 @@ test_ctor_cleanup()
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
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-blinky", test_ctor_blinky);
g_test_add_func("/message/contact/ctor-cleanup", test_ctor_cleanup);
g_test_add_func("/message/contact/encode", test_encode);
return g_test_run();
}

View File

@ -88,9 +88,13 @@ struct Contact {
* Jane Doe <email@example.com>
* 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
*/
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)
@ -160,7 +164,6 @@ private:
}
};
constexpr Option<Contact::Type>
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;
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));
contacts.add(Sexp::make_list(std::move(contact)));