Hi,

> UTF-8 in the e-mail body does not appear to cause problems, but as
> soon as a UTF-8 character appears in the subject, I get the following error:

Thanks for reporting. I have pushed the attached patch to fix that. It
will take care to encode 8-bit header values, if LC_ALL is properly set.

Best regards,
Sergey

>From 3d92f39a7de831348b550cd42fc6cd745cdae58f Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <[email protected]>
Date: Sun, 5 Apr 2026 20:15:21 +0300
Subject: [PATCH] mail: encode 8-bit headers when sending

* libmailutils/string/strcount.c (mu_mem_8bit_count): Fix.
*  mail/send.c (add_header): Change arguments. Copy name and value. If
the latter contains 8-bit characters and default charset can be determined,
encode the value as per RFC 2047. All uses changed.
---
 libmailutils/string/strcount.c |  2 +-
 mail/send.c                    | 54 ++++++++++++++++++++++++----------
 2 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/libmailutils/string/strcount.c b/libmailutils/string/strcount.c
index 6aade5800..eacf972df 100644
--- a/libmailutils/string/strcount.c
+++ b/libmailutils/string/strcount.c
@@ -82,7 +82,7 @@ mu_mem_8bit_count (char const *str, size_t len)
 {
   size_t n = 0;
   while (len--)
-    if (*str & 0xf0)
+    if (*str++ & 0x80)
       n++;
   return n;
 }
diff --git a/mail/send.c b/mail/send.c
index 775903cbb..b01de87f5 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -59,26 +59,54 @@ list_headers (void *item, void *data)
   return 0;
 }

-static void
-add_header (char *name, char *value, int mode)
+static int
+add_header (char const *name, size_t namelen, char const *value, int mode)
 {
   struct add_header *hp;
-
+  size_t vlen, n8;
+  char *vp = NULL;
+
   if (!add_header_list)
     {
       int rc = mu_list_create (&add_header_list);
       if (rc)
 	{
 	  mu_error (_("Cannot create header list: %s"), mu_strerror (rc));
-	  exit (1);
+	  return -1;
 	}
     }

   hp = mu_alloc (sizeof (*hp));
   hp->mode = mode;
-  hp->name = name;
-  hp->value = value;
+  hp->name = namelen == 0 ? strdup (name) : strndup (name, namelen);
+  if (!hp->name)
+    mu_alloc_die ();
+
+  vlen = strlen (value);
+  if ((n8 = mu_mem_8bit_count (value, vlen)) > 0)
+    {
+      char *charset = util_get_charset ();
+      if (charset)
+	{
+	  char *output;
+	  char const *encoding = (n8 > vlen / 2) ? "base64" : "quoted-printable";
+	  int rc = mu_rfc2047_encode (charset, encoding, value, &output);
+	  if (rc == 0)
+	    vp = output;
+	  else
+	    {
+	      mu_error (_("can't encode %s header: %s"), hp->name,
+			mu_strerror (rc));
+	      free (hp->name);
+	      free (hp);
+	      return -1;
+	    }
+	}
+    }
+
+  hp->value = vp ? vp : mu_strdup (value);
   mu_list_append (add_header_list, hp);
+  return 0;
 }

 void
@@ -86,7 +114,6 @@ send_append_header (char const *text)
 {
   char *p;
   size_t len;
-  char *name;

   p = strchr (text, ':');
   if (!p)
@@ -95,19 +122,16 @@ send_append_header (char const *text)
       return;
     }
   len = p - text;
-  name = mu_alloc (len + 1);
-  memcpy (name, text, len);
-  name[len] = 0;
   for (p++; *p && mu_isspace (*p); p++)
     ;

-  add_header (name, mu_strdup (p), COMPOSE_APPEND);
+  add_header (text, len, p, COMPOSE_APPEND);
 }

 void
 send_append_header2 (char const *name, char const *value, int mode)
 {
-  add_header (mu_strdup (name), mu_strdup (value), mode);
+  add_header (name, 0, value, mode);
 }

 int
@@ -125,9 +149,9 @@ mail_sendheader (int argc, char **argv)
   else
     {
       size_t len = strlen (argv[1]);
-      if (len > 0 && argv[1][len - 1] == ':')
-	argv[1][len - 1] = 0;
-      add_header (mu_strdup (argv[1]), mu_strdup (argv[2]), COMPOSE_APPEND);
+      if (len > 0 && argv[1][len - 1] == ':')
+	--len;
+      add_header (argv[1], 0, argv[2], COMPOSE_APPEND);
     }
   return 0;
 }
--
2.35.1

Reply via email to