@@ 0,0 1,119 @@
+From d4e93269f280a57863f55f30a910afabaf424c24 Mon Sep 17 00:00:00 2001
+From: Martin Lambers <marlam@marlam.de>
+Date: Sat, 28 Sep 2024 13:13:37 +0200
+Subject: [PATCH] Properly encode non-ASCII strings in the From header
+
+This fixes Github issue #162.
+---
+ src/msmtp.c | 4 +++-
+ src/tools.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/tools.h | 8 ++++++++
+ 3 files changed, 67 insertions(+), 1 deletion(-)
+
+diff --git a/src/msmtp.c b/src/msmtp.c
+index 95297a6..75a4a29 100644
+--- a/src/msmtp.c
++++ b/src/msmtp.c
+@@ -4187,8 +4187,10 @@ int main(int argc, char *argv[])
+ {
+ if (account->from_full_name)
+ {
++ char *enc_name = encode_for_header(account->from_full_name);
+ fprintf(prepend_header_tmpfile, "From: %s <%s>\n",
+- account->from_full_name, account->from);
++ enc_name, account->from);
++ free(enc_name);
+ }
+ else
+ {
+diff --git a/src/tools.c b/src/tools.c
+index d029f24..11718d3 100644
+--- a/src/tools.c
++++ b/src/tools.c
+@@ -50,9 +50,11 @@
+ #include <unistd.h>
+ #ifdef ENABLE_NLS
+ # include <locale.h>
++# include <langinfo.h>
+ #endif
+
+ #include "xalloc.h"
++#include "base64.h"
+ #include "tools.h"
+
+
+@@ -907,3 +909,57 @@ int check_hostname_matches_domain(const char *hostname, const char *domain)
+ return (hostname[hostname_len - 1 - domain_len] == '.'
+ && strcasecmp(hostname + (hostname_len - domain_len), domain) == 0) ? 1 : 0;
+ }
++
++
++/*
++ * encode_for_header()
++ *
++ * see tools.h
++ */
++
++char *encode_for_header(const char *s)
++{
++ int needsEncoding = 0;
++ for (int i = 0; s[i]; i++)
++ {
++ if (s[i] < 32 || s[i] >= 127)
++ {
++ needsEncoding = 1;
++ break;
++ }
++ }
++ if (needsEncoding)
++ {
++ /* create a string of the form "=?ENCODING?B?BASE64STRING?=" */
++ size_t s_len = strlen(s);
++ size_t b64_s_len = BASE64_LENGTH(s_len);
++ char* encoding = xstrdup(
++#ifdef ENABLE_NLS
++ nl_langinfo(CODESET)
++#else
++ "UTF-8";
++#endif
++ );
++ size_t e_len = strlen(encoding);
++ size_t enc_len = 2 + e_len + 3 + b64_s_len + 3;
++ char *enc = xmalloc(enc_len + 1);
++ size_t i = 0;
++ enc[i++] = '=';
++ enc[i++] = '?';
++ for (size_t j = 0; j < e_len; j++)
++ {
++ enc[i++] = tolower(encoding[j]);
++ }
++ free(encoding);
++ enc[i++] = '?';
++ enc[i++] = 'B';
++ enc[i++] = '?';
++ base64_encode(s, s_len, enc + i, enc_len - i + 1);
++ strcat(enc, "?=");
++ return enc;
++ }
++ else
++ {
++ return xstrdup(s);
++ }
++}
+diff --git a/src/tools.h b/src/tools.h
+index 86ba9ff..ebdeb73 100644
+--- a/src/tools.h
++++ b/src/tools.h
+@@ -259,4 +259,12 @@ void split_mail_address(const char *address, char **local_part, char **domain_pa
+ */
+ int check_hostname_matches_domain(const char *hostname, const char *domain);
+
++/*
++ * encode_for_header()
++ *
++ * Encode a string so that it can be used in a mail header.
++ * The result is allocated and needs to be freed.
++ */
++char *encode_for_header(const char *s);
++
+ #endif