]> source.dussan.org Git - rspamd.git/commitdiff
[CritFix] Strictly deny unencoded bad utf8 sequences in headers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 27 Nov 2018 16:58:25 +0000 (16:58 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 27 Nov 2018 16:58:25 +0000 (16:58 +0000)
src/libmime/email_addr.c
src/libmime/mime_headers.c

index 3b9f31de95651fc53110b0573faf6c840c3d8b49..e1d52e1857de8256a0cb5b30f3152cf9467dc7e7 100644 (file)
@@ -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) {
index 9d0518c29bd08253ef6ae00d2fc2c9ca869a560b..b782db010986e8225b13fa39c5a5bff0d33ed996 100644 (file)
@@ -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: