From b0d329b6b0b7f45015718904b8092bce0a27b773 Mon Sep 17 00:00:00 2001 From: Richard Russon Date: Sat, 30 Dec 2017 16:15:09 +0000 Subject: [PATCH] move idna functions to muttlib --- Makefile.autosetup | 4 +- address.c | 1 - alias.c | 1 - commands.c | 1 - compose.c | 1 - conn/socket.c | 1 - conn/ssl.c | 1 - copy.c | 1 - edit.c | 1 - envelope.c | 2 +- hdrline.c | 1 - header.c | 1 - init.c | 1 - main.c | 1 - mutt_idna.c => mutt/idna.c | 101 +++++++++++++++++++++++++++--------- mutt_idna.h => mutt/idna2.h | 18 +++---- mutt/mutt.h | 2 + mutt_address.c | 1 - ncrypt/pgpinvoke.c | 1 - options.h | 4 -- protos.h | 4 ++ query.c | 1 - recvcmd.c | 1 - rfc2047.c | 4 +- send.c | 1 - sendlib.c | 5 +- sort.c | 1 - 27 files changed, 97 insertions(+), 65 deletions(-) rename mutt_idna.c => mutt/idna.c (67%) rename mutt_idna.h => mutt/idna2.h (69%) diff --git a/Makefile.autosetup b/Makefile.autosetup index 6089f957b..5219b5780 100644 --- a/Makefile.autosetup +++ b/Makefile.autosetup @@ -61,7 +61,7 @@ NEOMUTTOBJS= mutt_account.o addrbook.o alias.o attach.o bcache.o body.o \ curs_main.o edit.o editmsg.o enter.o envelope.o filter.o \ flags.o from.o group.o handler.o hdrline.o \ header.o help.o history.o hook.o init.o keymap.o main.o \ - mbox.o mbyte.o menu.o mh.o muttlib.o mutt_address.o mutt_idna.o \ + mbox.o mbyte.o menu.o mh.o muttlib.o mutt_address.o \ mutt_socket.o tags.o mx.o \ newsrc.o nntp.o pager.o parameter.o parse.o pattern.o pop.o \ pop_auth.o pop_lib.o postpone.o query.o recvattach.o recvcmd.o \ @@ -93,7 +93,7 @@ ALLOBJS+= $(NEOMUTTOBJS) # libmutt LIBMUTT= libmutt.a LIBMUTTOBJS= mutt/base64.o mutt/buffer.o mutt/charset.o mutt/date.o mutt/debug.o mutt/exit.o \ - mutt/file.o mutt/hash.o mutt/list.o mutt/mapping.o mutt/mbyte.o mutt/md5.o \ + mutt/file.o mutt/hash.o mutt/idna.o mutt/list.o mutt/mapping.o mutt/mbyte.o mutt/md5.o \ mutt/memory.o mutt/message.o mutt/regex.o mutt/sha1.o mutt/signal.o mutt/string.o CLEANFILES+= $(LIBMUTT) $(LIBMUTTOBJS) MUTTLIBS+= $(LIBMUTT) diff --git a/address.c b/address.c index fbf250762..44c68e805 100644 --- a/address.c +++ b/address.c @@ -62,7 +62,6 @@ #include #include "mutt/mutt.h" #include "address.h" -#include "mutt_idna.h" /** * AddressSpecials - Characters with special meaning for email addresses diff --git a/alias.c b/alias.c index 7f98a290b..e3baccafc 100644 --- a/alias.c +++ b/alias.c @@ -36,7 +36,6 @@ #include "envelope.h" #include "globals.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "options.h" #include "protos.h" #ifdef ENABLE_NLS diff --git a/commands.c b/commands.c index 40f09a238..9a0e8de1c 100644 --- a/commands.c +++ b/commands.c @@ -48,7 +48,6 @@ #include "mailbox.h" #include "mime.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "mx.h" #include "ncrypt/ncrypt.h" diff --git a/compose.c b/compose.c index dd4dcd805..fee1b2f56 100644 --- a/compose.c +++ b/compose.c @@ -46,7 +46,6 @@ #include "mailbox.h" #include "mime.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "mx.h" #include "ncrypt/ncrypt.h" diff --git a/conn/socket.c b/conn/socket.c index fb5a4b0c1..ca65bfeaa 100644 --- a/conn/socket.c +++ b/conn/socket.c @@ -65,7 +65,6 @@ #include "conn_globals.h" #include "connection.h" #include "globals.h" -#include "mutt_idna.h" #include "options.h" #include "protos.h" #ifdef USE_SSL diff --git a/conn/ssl.c b/conn/ssl.c index ec1877275..0f0bdacf1 100644 --- a/conn/ssl.c +++ b/conn/ssl.c @@ -65,7 +65,6 @@ #include "globals.h" #include "keymap.h" #include "mutt_account.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "opcodes.h" #include "options.h" diff --git a/copy.c b/copy.c index d68728878..1ea14168e 100644 --- a/copy.c +++ b/copy.c @@ -37,7 +37,6 @@ #include "mailbox.h" #include "mime.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" diff --git a/edit.c b/edit.c index d30fb6c41..3f2676c3c 100644 --- a/edit.c +++ b/edit.c @@ -40,7 +40,6 @@ #include "globals.h" #include "header.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "options.h" #include "protos.h" #ifdef ENABLE_NLS diff --git a/envelope.c b/envelope.c index e8b21d69f..f8e7925d7 100644 --- a/envelope.c +++ b/envelope.c @@ -43,7 +43,7 @@ #include "mutt/string2.h" #include "envelope.h" #include "address.h" -#include "mutt_idna.h" +#include "protos.h" /** * mutt_env_new - Create a new Envelope diff --git a/hdrline.c b/hdrline.c index ae310714d..e5c30b170 100644 --- a/hdrline.c +++ b/hdrline.c @@ -41,7 +41,6 @@ #include "header.h" #include "mbtable.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "ncrypt/ncrypt.h" #include "options.h" #include "protos.h" diff --git a/header.c b/header.c index ec84f7092..601a70934 100644 --- a/header.c +++ b/header.c @@ -36,7 +36,6 @@ #include "context.h" #include "envelope.h" #include "globals.h" -#include "mutt_idna.h" #include "ncrypt/ncrypt.h" #include "options.h" #include "protos.h" diff --git a/init.c b/init.c index 68562eddc..193d3275e 100644 --- a/init.c +++ b/init.c @@ -53,7 +53,6 @@ #include "mbtable.h" #include "mbyte.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "mx.h" #include "myvar.h" diff --git a/main.c b/main.c index 7477be0ab..76b3048fe 100644 --- a/main.c +++ b/main.c @@ -47,7 +47,6 @@ #include "keymap.h" #include "mailbox.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "mutt_socket.h" #include "ncrypt/ncrypt.h" diff --git a/mutt_idna.c b/mutt/idna.c similarity index 67% rename from mutt_idna.c rename to mutt/idna.c index 7b48cc62c..43bf21de6 100644 --- a/mutt_idna.c +++ b/mutt/idna.c @@ -20,22 +20,38 @@ * this program. If not, see . */ +/** + * @page idna Handling of international domain names + * + * Handling of international domain names + * + * | Function | Description + * | :------------------------ | :--------------------------------------------------------- + * | mutt_idna_intl_to_local() | Convert an email's domain from Punycode + * | mutt_idna_local_to_intl() | Convert an email's domain to Punycode + * | mutt_idna_to_ascii_lz() | Convert a domain to Punycode + */ + #include "config.h" #include #include #include -#include "mutt/mutt.h" -#include "mutt_idna.h" -#include "address.h" -#include "envelope.h" -#include "globals.h" -#include "options.h" +#include "charset.h" +#include "debug.h" +#include "idna2.h" +#include "memory.h" +#include "string2.h" #ifdef HAVE_IDNA_H #include #elif defined(HAVE_IDN_IDNA_H) #include #endif +#ifdef HAVE_LIBIDN +bool IdnDecode; +bool IdnEncode; +#endif + #ifdef HAVE_LIBIDN /* Work around incompatibilities in the libidn API */ #if (!defined(HAVE_IDNA_TO_ASCII_8Z) && defined(HAVE_IDNA_TO_ASCII_FROM_UTF8)) @@ -54,18 +70,27 @@ #ifdef HAVE_LIBIDN /** - * mutt_idna_to_ascii_lz - XXX - * @param input XXX - * @param output XXX - * @param flags XXX + * mutt_idna_to_ascii_lz - Convert a domain to Punycode + * @param input Domain + * @param output Result + * @param flags Flags, e.g. IDNA_ALLOW_UNASSIGNED * @retval 0 Success * @retval >0 Failure, error code + * + * Convert a domain from the current locale to Punycode. + * + * @note The caller must free output */ int mutt_idna_to_ascii_lz(const char *input, char **output, int flags) { return idna_to_ascii_lz(input, output, flags); } +/** + * check_idn - Is domain in Punycode? + * @param domain Domain to test + * @retval true At least one part of domain is in Punycode + */ static bool check_idn(char *domain) { if (!domain) @@ -84,7 +109,25 @@ static bool check_idn(char *domain) } #endif /* HAVE_LIBIDN */ -char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags) +/** + * mutt_idna_intl_to_local - Convert an email's domain from Punycode + * @param user Username + * @param domain Domain + * @param flags Flags, e.g. #MI_MAY_BE_IRREVERSIBLE + * @retval ptr Newly allocated local email address + * @retval NULL Error in conversion + * + * If #IdnDecode is set, then the domain will be converted from Punycode. + * For example, "xn--ls8h.la" becomes the emoji domain: ":poop:.la" + * Then the user and domain are changed from 'utf-8' to the encoding in + * #Charset. + * + * If the flag #MI_MAY_BE_IRREVERSIBLE is NOT given, then the results will be + * checked to make sure that the transformation is "undo-able". + * + * @note The caller must free the returned string. + */ +char *mutt_idna_intl_to_local(const char *user, const char *domain, int flags) { char *local_user = NULL, *local_domain = NULL, *mailbox = NULL; char *reversed_user = NULL, *reversed_domain = NULL; @@ -93,8 +136,8 @@ char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags) bool is_idn_encoded = false; #endif /* HAVE_LIBIDN */ - local_user = mutt_str_strdup(orig_user); - local_domain = mutt_str_strdup(orig_domain); + local_user = mutt_str_strdup(user); + local_domain = mutt_str_strdup(domain); #ifdef HAVE_LIBIDN is_idn_encoded = check_idn(local_domain); @@ -114,10 +157,8 @@ char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags) if (mutt_cs_convert_string(&local_domain, "utf-8", Charset, 0) == -1) goto cleanup; - /* - * make sure that we can convert back and come out with the same - * user and domain name. - */ + /* make sure that we can convert back and come out with the same + * user and domain name. */ if ((flags & MI_MAY_BE_IRREVERSIBLE) == 0) { reversed_user = mutt_str_strdup(local_user); @@ -129,10 +170,9 @@ char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags) goto cleanup; } - if (mutt_str_strcasecmp(orig_user, reversed_user) != 0) + if (mutt_str_strcasecmp(user, reversed_user) != 0) { - mutt_debug(1, "#1 Not reversible. orig = '%s', reversed = '%s'.\n", - orig_user, reversed_user); + mutt_debug(1, "#1 Not reversible. orig = '%s', reversed = '%s'.\n", user, reversed_user); goto cleanup; } @@ -164,10 +204,9 @@ char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags) } #endif /* HAVE_LIBIDN */ - if (mutt_str_strcasecmp(orig_domain, reversed_domain) != 0) + if (mutt_str_strcasecmp(domain, reversed_domain) != 0) { - mutt_debug(1, "#2 Not reversible. orig = '%s', reversed = '%s'.\n", - orig_domain, reversed_domain); + mutt_debug(1, "#2 Not reversible. orig = '%s', reversed = '%s'.\n", domain, reversed_domain); goto cleanup; } } @@ -185,7 +224,21 @@ cleanup: return mailbox; } -char *mutt_idna_local_to_intl(char *user, char *domain) +/** + * mutt_idna_local_to_intl - Convert an email's domain to Punycode + * @param user Username + * @param domain Domain + * @retval ptr Newly allocated Punycode email address + * @retval NULL Error in conversion + * + * The user and domain are assumed to be encoded according to #Charset. + * They are converted to 'utf-8'. If #IdnEncode is set, then the domain + * will be converted to Punycode. For example, the emoji domain: + * ":poop:.la" becomes "xn--ls8h.la" + * + * @note The caller must free the returned string. + */ +char *mutt_idna_local_to_intl(const char *user, const char *domain) { char *intl_user = NULL, *intl_domain = NULL; char *mailbox = NULL; diff --git a/mutt_idna.h b/mutt/idna2.h similarity index 69% rename from mutt_idna.h rename to mutt/idna2.h index b7d520a23..bd20a1753 100644 --- a/mutt_idna.h +++ b/mutt/idna2.h @@ -23,19 +23,15 @@ #ifndef _MUTT_IDNA_H #define _MUTT_IDNA_H -struct Envelope; -struct Address; +#include -#define MI_MAY_BE_IRREVERSIBLE (1 << 0) - -int mutt_idna_to_ascii_lz(const char *input, char **output, int flags); +extern bool IdnDecode; +extern bool IdnEncode; -char *mutt_idna_intl_to_local(char *orig_user, char *orig_domain, int flags); -char *mutt_idna_local_to_intl(char *user, char *domain); - -int mutt_addrlist_to_intl(struct Address *a, char **err); -int mutt_addrlist_to_local(struct Address *a); +#define MI_MAY_BE_IRREVERSIBLE (1 << 0) -const char *mutt_addr_for_display(struct Address *a); +int mutt_idna_to_ascii_lz(const char *input, char **output, int flags); +char *mutt_idna_intl_to_local(const char *user, const char *domain, int flags); +char *mutt_idna_local_to_intl(const char *user, const char *domain); #endif /* _MUTT_IDNA_H */ diff --git a/mutt/mutt.h b/mutt/mutt.h index ee2723376..b03cba2ae 100644 --- a/mutt/mutt.h +++ b/mutt/mutt.h @@ -36,6 +36,7 @@ * -# @subpage exit * -# @subpage file * -# @subpage hash + * -# @subpage idna * -# @subpage list * -# @subpage mapping * -# @subpage mbyte @@ -59,6 +60,7 @@ #include "exit.h" #include "file.h" #include "hash.h" +#include "idna2.h" #include "list.h" #include "mapping.h" #include "mbyte.h" diff --git a/mutt_address.c b/mutt_address.c index 948800b86..f90f0dcf9 100644 --- a/mutt_address.c +++ b/mutt_address.c @@ -26,7 +26,6 @@ #include #include "mutt/mutt.h" #include "address.h" -#include "mutt_idna.h" /** * mutt_addrlist_to_intl - Convert an Address list to Punycode diff --git a/ncrypt/pgpinvoke.c b/ncrypt/pgpinvoke.c index fd71aaf19..a42b31175 100644 --- a/ncrypt/pgpinvoke.c +++ b/ncrypt/pgpinvoke.c @@ -36,7 +36,6 @@ #include "format_flags.h" #include "globals.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "ncrypt.h" #include "pgp.h" #include "pgpkey.h" diff --git a/options.h b/options.h index 2f8116527..7a312bd08 100644 --- a/options.h +++ b/options.h @@ -219,10 +219,6 @@ WHERE bool Use8bitmime; WHERE bool UseDomain; WHERE bool UseFrom; WHERE bool PgpUseGpgAgent; -#ifdef HAVE_LIBIDN -WHERE bool IdnDecode; -WHERE bool IdnEncode; -#endif #ifdef HAVE_GETADDRINFO WHERE bool UseIpv6; #endif diff --git a/protos.h b/protos.h index 5a4ab1b39..4841d52f1 100644 --- a/protos.h +++ b/protos.h @@ -360,6 +360,10 @@ int wcscasecmp(const wchar_t *a, const wchar_t *b); bool message_is_tagged(struct Context *ctx, int index); bool message_is_visible(struct Context *ctx, int index); +int mutt_addrlist_to_local(struct Address *a); +int mutt_addrlist_to_intl(struct Address *a, char **err); +int mutt_env_to_intl(struct Envelope *env, char **tag, char **err); +void mutt_env_to_local(struct Envelope *e); size_t rfc822_write_address(char *buf, size_t buflen, struct Address *addr, int display); void rfc822_write_address_single(char *buf, size_t buflen, struct Address *addr, int display); diff --git a/query.c b/query.c index dd03a2084..56de2b0cf 100644 --- a/query.c +++ b/query.c @@ -38,7 +38,6 @@ #include "header.h" #include "keymap.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mutt_menu.h" #include "opcodes.h" #include "protos.h" diff --git a/recvcmd.c b/recvcmd.c index 0bfa12f30..8c23d7797 100644 --- a/recvcmd.c +++ b/recvcmd.c @@ -36,7 +36,6 @@ #include "globals.h" #include "header.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "options.h" #include "protos.h" #include "state.h" diff --git a/rfc2047.c b/rfc2047.c index 7a6756b99..5c6f15d16 100644 --- a/rfc2047.c +++ b/rfc2047.c @@ -116,8 +116,8 @@ int convert_nonmime_string(char **ps) return 0; } } - mutt_cs_convert_string(ps, (const char *) mutt_cs_get_default_charset(), Charset, - MUTT_ICONV_HOOK_FROM); + mutt_cs_convert_string(ps, (const char *) mutt_cs_get_default_charset(), + Charset, MUTT_ICONV_HOOK_FROM); return -1; } diff --git a/send.c b/send.c index 9fba54f06..4c93cb1c6 100644 --- a/send.c +++ b/send.c @@ -46,7 +46,6 @@ #include "mailbox.h" #include "mime.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "ncrypt/ncrypt.h" #include "options.h" #include "parameter.h" diff --git a/sendlib.c b/sendlib.c index bcca72fa6..52ad7b037 100644 --- a/sendlib.c +++ b/sendlib.c @@ -54,7 +54,6 @@ #include "mailbox.h" #include "mime.h" #include "mutt_curses.h" -#include "mutt_idna.h" #include "mx.h" #include "ncrypt/ncrypt.h" #include "options.h" @@ -474,8 +473,8 @@ int mutt_write_mime_body(struct Body *a, FILE *f) } if (a->type == TYPETEXT && (!a->noconv)) - fc = mutt_cs_fgetconv_open(fpin, a->charset, - mutt_get_body_charset(send_charset, sizeof(send_charset), a), 0); + fc = mutt_cs_fgetconv_open( + fpin, a->charset, mutt_get_body_charset(send_charset, sizeof(send_charset), a), 0); else fc = mutt_cs_fgetconv_open(fpin, 0, 0, 0); diff --git a/sort.c b/sort.c index 8ae27a920..9beecb26f 100644 --- a/sort.c +++ b/sort.c @@ -32,7 +32,6 @@ #include "envelope.h" #include "globals.h" #include "header.h" -#include "mutt_idna.h" #include "options.h" #include "protos.h" #include "thread.h" -- 2.40.0