summaryrefslogtreecommitdiffstats
path: root/rfc2047.c
diff options
context:
space:
mode:
authorKevin McCarthy <kevin@8t8.us>2020-04-28 15:23:29 -0700
committerKevin McCarthy <kevin@8t8.us>2020-04-28 16:04:56 -0700
commitb3fd56a4bda3ca48371483009a065895d36fceb1 (patch)
treec736ea2668e4fa901fd7999f65d67bf300301a5e /rfc2047.c
parent43204e7bec742ecf242b9f4d52ed790a60af98fa (diff)
Turn off writing exact-addresses that require 2047-encoding.
The full strdup'ed copy of the address can't be properly encoded without significant rework to parse, encode, and reassemble. (Additionally, IDNA is not being performed on the domain written in the exact-address string.) As an example, consider the current exact address behavior, given the three addresses: "ascii name" (comment) <addr@example.com> The ènd (comment) <addr2@example.com> "The ènd" (comment) <addr3@example.com> Before this commit, when sending Mutt would generate: "ascii name" (comment) <addr@example.com> The =?iso-8859-1?B?6G5kIChjb21tZW50KSA8YWRkcjJAZXhhbXBsZS5jb20+?= =?iso-8859-1?B?IlRoZSDobmQiIChjb21tZW50KSA8YWRkcjNAZXhhbXBsZS5jb20+?= The second address 2047 encodes everything starting with ènd, including the comment and address. The third address is completely encoded. A "quick workaround" I proposed to the list was turning off encode_specials. This results in: "ascii name" (comment) <addr@example.com> The =?iso-8859-1?B?6G5k?= (comment) <addr2@example.com> "The =?iso-8859-1?Q?=E8nd=22?= (comment) <addr3@example.com> That solves the second case, but in the third case 2047-encodes ènd" - including the trailing double quote. With this patch, we turn off writing the exact address if encoding is needed, generating: "ascii name" (comment) <addr@example.com> The =?iso-8859-1?B?6G5k?= <addr2@example.com> The =?iso-8859-1?B?6G5k?= <addr3@example.com> This reverts to Mutt-generated normalized form in the last two addresses, which require encoding. For the first case it preserves the address as "typed" by the user.
Diffstat (limited to 'rfc2047.c')
-rw-r--r--rfc2047.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/rfc2047.c b/rfc2047.c
index 7ed08c50..488771bd 100644
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -397,7 +397,9 @@ static size_t choose_block (char *d, size_t dlen, int col,
* allocated buffer (e, elen). The input data is in charset fromcode
* and is converted into a charset chosen from charsets.
* Return 1 if the conversion to UTF-8 failed, 2 if conversion from UTF-8
- * failed, otherwise 0. If conversion failed, fromcode is assumed to be
+ * failed, 3 if no encoding was required, otherwise 0.
+ *
+ * If conversion failed, fromcode is assumed to be
* compatible with us-ascii and the original data is used.
* The input data is assumed to be a single line starting at column col;
* if col is non-zero, the preceding character was a space.
@@ -455,7 +457,7 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col,
/* No encoding is required. */
*e = u;
*elen = ulen;
- return ret;
+ return 3;
}
/* Choose target charset. */
@@ -583,25 +585,28 @@ static int rfc2047_encode (ICONV_CONST char *d, size_t dlen, int col,
return ret;
}
-void _rfc2047_encode_string (char **pd, int encode_specials, int col)
+int _rfc2047_encode_string (char **pd, int encode_specials, int col)
{
char *e;
size_t elen;
char *charsets;
+ int rv = 0;
if (!Charset || !*pd)
- return;
+ return rv;
charsets = SendCharset;
if (!charsets)
charsets = "utf-8";
- rfc2047_encode (*pd, strlen (*pd), col,
- Charset, charsets, &e, &elen,
- encode_specials ? RFC822Specials : NULL);
+ rv = rfc2047_encode (*pd, strlen (*pd), col,
+ Charset, charsets, &e, &elen,
+ encode_specials ? RFC822Specials : NULL);
FREE (pd); /* __FREE_CHECKED__ */
*pd = e;
+
+ return rv;
}
void rfc2047_encode_adrlist (ADDRESS *addr, const char *tag)
@@ -616,8 +621,15 @@ void rfc2047_encode_adrlist (ADDRESS *addr, const char *tag)
else if (ptr->group && ptr->mailbox)
_rfc2047_encode_string (&ptr->mailbox, 1, col);
#ifdef EXACT_ADDRESS
- if (ptr->val)
- _rfc2047_encode_string (&ptr->val, 1, col);
+ /* If any kind of encoding is needed for the exact-address value,
+ * abort using it. We can't properly encode it (nor apply IDNA) without
+ * parsing it, so revert to using the parsed values.
+ */
+ if (ptr->val && Charset)
+ {
+ if (_rfc2047_encode_string (&ptr->val, 1, col) != 3)
+ FREE (&ptr->val);
+ }
#endif
ptr = ptr->next;
}