diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-27 16:58:25 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2018-11-27 16:58:25 +0000 |
commit | e2cb16d8f40cd7193b27e05c88aa23e0639d38be (patch) | |
tree | 49dad7fc364813d6ad926a1768d4d283ff1e2c4d /src/libmime | |
parent | dda2df85a29ebf8db1836ecc8f31c5143d827c0d (diff) | |
download | rspamd-e2cb16d8f40cd7193b27e05c88aa23e0639d38be.tar.gz rspamd-e2cb16d8f40cd7193b27e05c88aa23e0639d38be.zip |
[CritFix] Strictly deny unencoded bad utf8 sequences in headers
Diffstat (limited to 'src/libmime')
-rw-r--r-- | src/libmime/email_addr.c | 1 | ||||
-rw-r--r-- | src/libmime/mime_headers.c | 26 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/libmime/email_addr.c b/src/libmime/email_addr.c index 3b9f31de9..e1d52e185 100644 --- a/src/libmime/email_addr.c +++ b/src/libmime/email_addr.c @@ -202,6 +202,7 @@ rspamd_email_address_check_and_add (const gchar *start, gsize len, struct rspamd_email_address addr; /* The whole email is likely address */ + memset (&addr, 0, sizeof (addr)); rspamd_smtp_addr_parse (start, len, &addr); if (addr.flags & RSPAMD_EMAIL_ADDR_VALID) { diff --git a/src/libmime/mime_headers.c b/src/libmime/mime_headers.c index 9d0518c29..b782db010 100644 --- a/src/libmime/mime_headers.c +++ b/src/libmime/mime_headers.c @@ -18,6 +18,7 @@ #include "smtp_parsers.h" #include "mime_encoding.h" #include "libserver/mempool_vars_internal.h" +#include <unicode/utf8.h> static void rspamd_mime_header_check_special (struct rspamd_task *task, @@ -533,7 +534,8 @@ rspamd_mime_header_decode (rspamd_mempool_t *pool, const gchar *in, gsize inlen) { GString *out; - const gchar *c, *p, *end, *tok_start = NULL; + const guchar *c, *p, *end; + const gchar *tok_start = NULL; gsize tok_len = 0, pos; GByteArray *token = NULL, *decoded; rspamd_ftok_t cur_charset = {0, NULL}, old_charset = {0, NULL}; @@ -566,6 +568,28 @@ rspamd_mime_header_decode (rspamd_mempool_t *pool, const gchar *in, c = p; state = got_eqsign; } + else if (*p >= 128) { + gint off = 0; + UChar32 uc; + /* Unencoded character */ + g_string_append_len (out, c, p - c); + /* Check if that's valid UTF8 */ + U8_NEXT (p, off, end - p, uc); + + if (uc <= 0) { + c = p + 1; + /* 0xFFFD in UTF8 */ + g_string_append_len (out, " ", 3); + off = 0; + U8_APPEND_UNSAFE (out->str + out->len - 3, + off, 0xfffd); + } + else { + c = p; + p = p + off; + continue; /* To avoid p ++ after this block */ + } + } p ++; break; case got_eqsign: |