X-Git-Url: https://git.llucax.com/software/mutt-debian.git/blobdiff_plain/14c29200cb58d3c4a0830265f2433849781858d0..987fbddea40b1b0c77b6bee8881f4d28a31afa6d:/mutt_idna.c?ds=sidebyside diff --git a/mutt_idna.c b/mutt_idna.c index 721bf4f..f720116 100644 --- a/mutt_idna.c +++ b/mutt_idna.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Thomas Roessler + * Copyright (C) 2003,2005,2008 Thomas Roessler * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,23 +26,32 @@ /* The low-level interface we use. */ -#ifndef HAVE_LIBIDN +#ifdef HAVE_LIBIDN -int mutt_idna_to_local (const char *in, char **out, int flags) -{ - *out = safe_strdup (in); - return 1; -} +/* check whether an address is an IDN */ -int mutt_local_to_idna (const char *in, char **out) +static int check_idn (ADDRESS *ap) { - *out = safe_strdup (in); - return 0; + char *p = 0; + + if (!ap || !ap->mailbox) + return 0; + + if (!ap->idn_checked) + { + ap->idn_checked = 1; + for (p = strchr (ap->mailbox, '@'); p && *p; p = strchr (p, '.')) + if (ascii_strncasecmp (++p, "xn--", 4) == 0) + { + ap->is_idn = 1; + break; + } + } + + return ap->is_idn; } - -#else -int mutt_idna_to_local (const char *in, char **out, int flags) +static int mutt_idna_to_local (const char *in, char **out, int flags) { *out = NULL; @@ -51,9 +60,9 @@ int mutt_idna_to_local (const char *in, char **out, int flags) if (!in) goto notrans; - + /* Is this the right function? Interesting effects with some bad identifiers! */ - if (idna_to_unicode_8z8z (in, out, 1) != IDNA_SUCCESS) + if (idna_to_unicode_8z8z (in, out, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS) goto notrans; /* we don't want charset-hook effects, so we set flags to 0 */ @@ -74,7 +83,7 @@ int mutt_idna_to_local (const char *in, char **out, int flags) /* we don't want charset-hook effects, so we set flags to 0 */ if (mutt_convert_string (&tmp, Charset, "utf-8", 0) == -1) irrev = 1; - if (!irrev && idna_to_ascii_8z (tmp, &t2, 1) != IDNA_SUCCESS) + if (!irrev && idna_to_ascii_8z (tmp, &t2, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS) irrev = 1; if (!irrev && ascii_strcasecmp (t2, in)) { @@ -98,7 +107,7 @@ int mutt_idna_to_local (const char *in, char **out, int flags) return 1; } -int mutt_local_to_idna (const char *in, char **out) +static int mutt_local_to_idna (const char *in, char **out) { int rv = 0; char *tmp = safe_strdup (in); @@ -113,7 +122,7 @@ int mutt_local_to_idna (const char *in, char **out) /* we don't want charset-hook effects, so we set flags to 0 */ if (mutt_convert_string (&tmp, Charset, "utf-8", 0) == -1) rv = -1; - if (!rv && idna_to_ascii_8z (tmp, out, 1) != IDNA_SUCCESS) + if (!rv && idna_to_ascii_8z (tmp, out, IDNA_ALLOW_UNASSIGNED) != IDNA_SUCCESS) rv = -2; FREE (&tmp); @@ -125,23 +134,21 @@ int mutt_local_to_idna (const char *in, char **out) return rv; } -#endif - - /* higher level functions */ static int mbox_to_udomain (const char *mbx, char **user, char **domain) { + static char *buff = NULL; char *p; - *user = NULL; - *domain = NULL; - p = strchr (mbx, '@'); + mutt_str_replace (&buff, mbx); + + p = strchr (buff, '@'); if (!p || !p[1]) return -1; - *user = safe_calloc((p - mbx + 1), sizeof(mbx[0])); - strfcpy (*user, mbx, (p - mbx + 1)); - *domain = safe_strdup(p + 1); + *p = '\0'; + *user = buff; + *domain = p + 1; return 0; } @@ -171,10 +178,9 @@ int mutt_addrlist_to_idna (ADDRESS *a, char **err) { safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2); sprintf (a->mailbox, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */ + a->idn_checked = 0; } - FREE (&domain); - FREE (&user); FREE (&tmp); if (e) @@ -193,17 +199,17 @@ int mutt_addrlist_to_local (ADDRESS *a) { if (!a->mailbox) continue; + if (!check_idn (a)) + continue; if (mbox_to_udomain (a->mailbox, &user, &domain) == -1) continue; - if (mutt_idna_to_local (domain, &tmp, 0) == 0) { safe_realloc (&a->mailbox, mutt_strlen (user) + mutt_strlen (tmp) + 2); sprintf (a->mailbox, "%s@%s", NONULL (user), NONULL (tmp)); /* __SPRINTF_CHECKED__ */ + a->idn_checked = 0; } - FREE (&domain); - FREE (&user); FREE (&tmp); } @@ -221,13 +227,13 @@ const char *mutt_addr_for_display (ADDRESS *a) char *user = NULL; FREE (&buff); - + + if (!check_idn (a)) + return a->mailbox; if (mbox_to_udomain (a->mailbox, &user, &domain) != 0) return a->mailbox; if (mutt_idna_to_local (domain, &tmp, MI_MAY_BE_IRREVERSIBLE) != 0) { - FREE (&user); - FREE (&domain); FREE (&tmp); return a->mailbox; } @@ -235,8 +241,6 @@ const char *mutt_addr_for_display (ADDRESS *a) safe_realloc (&buff, mutt_strlen (tmp) + mutt_strlen (user) + 2); sprintf (buff, "%s@%s", NONULL(user), NONULL(tmp)); /* __SPRINTF_CHECKED__ */ FREE (&tmp); - FREE (&user); - FREE (&domain); return buff; } @@ -277,3 +281,5 @@ int mutt_env_to_idna (ENVELOPE *env, char **tag, char **err) } #undef H_TO_IDNA + +#endif /* HAVE_LIBIDN */