]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Another fix in folding algorithm
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 Apr 2018 14:36:41 +0000 (15:36 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 3 Apr 2018 14:36:41 +0000 (15:36 +0100)
src/libserver/dkim.c
src/libutil/str_util.c

index 8e264a99aa95212b90b3c523bf04500d65d1e04c..f2914535ffab772faa2edbe7b8b08d776220fa2c 100644 (file)
@@ -2760,7 +2760,7 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector,
        gchar *b64_data;
        guchar *rsa_buf;
        guint rsa_len;
-       guint headers_len = 0;
+       guint headers_len = 0, cur_len = 0;
        union rspamd_dkim_header_stat hstat;
 
        g_assert (ctx != NULL);
@@ -2856,7 +2856,13 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector,
                        }
 
                        /* Now add one more entry to oversign */
-                       headers_len += (strlen (dh->name) + 1) * (count + 1);
+                       cur_len = (strlen (dh->name) + 1) * (count + 1);
+                       headers_len += cur_len;
+                       if (headers_len > 70 && i > 0 && i < ctx->common.hlist->len - 1) {
+                               rspamd_printf_gstring (hdr, "  ");
+                               headers_len = cur_len;
+                       }
+
                        for (j = 0; j < count + 1; j++) {
                                rspamd_printf_gstring (hdr, "%s:", dh->name);
                        }
@@ -2864,11 +2870,16 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector,
                else {
                        if (hstat.s.count > 0) {
 
+                               cur_len = (strlen (dh->name) + 1) * (hstat.s.count);
+                               headers_len += cur_len;
+                               if (headers_len > 70 && i > 0 && i < ctx->common.hlist->len - 1) {
+                                       rspamd_printf_gstring (hdr, "  ");
+                                       headers_len = cur_len;
+                               }
+
                                for (j = 0; j < hstat.s.count; j++) {
                                        rspamd_printf_gstring (hdr, "%s:", dh->name);
                                }
-
-                               headers_len += (strlen (dh->name) + 1) * (hstat.s.count);
                        }
 
                        if (g_hash_table_lookup (task->raw_headers, dh->name)) {
@@ -2877,16 +2888,12 @@ rspamd_dkim_sign (struct rspamd_task *task, const gchar *selector,
                        }
                }
 
-               if (headers_len > 60 && i < ctx->common.hlist->len - 1) {
-                       rspamd_printf_gstring (hdr, "  ");
-                       headers_len = 0;
-               }
-
                g_hash_table_remove (ctx->common.htable, dh->name);
        }
 
        /* Replace the last ':' with ';' */
        hdr->str[hdr->len - 1] = ';';
+       msg_err ("%v", hdr);
 
        if (ctx->common.type != RSPAMD_DKIM_ARC_SEAL) {
                if (!cached_bh->digest_normal) {
index 4d1b22076221a0c3b781a5541bc68e28b6ce42f2..d571efabb0d07a9e2ba9b2e91600df0bd406014c 100644 (file)
@@ -925,6 +925,8 @@ rspamd_header_value_fold (const gchar *name,
        const guint default_fold_max = 76;
        guint cur_len;
        const gchar *p, *c;
+       guint nspaces = 0;
+       const gchar *last;
        gboolean first_token = TRUE;
        enum {
                fold_before = 0,
@@ -954,6 +956,7 @@ rspamd_header_value_fold (const gchar *name,
 
        while (*p) {
                switch (state) {
+
                case read_token:
                        if (fold_on_chars && strchr (fold_on_chars, *p) != NULL) {
                                fold_type = fold_after;
@@ -1028,9 +1031,7 @@ rspamd_header_value_fold (const gchar *name,
                case fold_token:
                        /* Here, we have token start at 'c' and token end at 'p' */
                        if (fold_type == fold_after) {
-                               guint nspaces = 0;
-                               const gchar *last;
-
+                               nspaces = 0;
                                if (p > c) {
                                        g_string_append_len (res, c, p - c);
 
@@ -1074,27 +1075,50 @@ rspamd_header_value_fold (const gchar *name,
                                cur_len = 0;
                        }
                        else {
+                               const gchar *last;
+
                                /* Skip space if needed */
                                if (g_ascii_isspace (*c) && p > c) {
                                        c ++;
                                }
 
-                               switch (how) {
-                               case RSPAMD_TASK_NEWLINES_LF:
-                                       g_string_append_len (res, "\n\t", 2);
-                                       break;
-                               case RSPAMD_TASK_NEWLINES_CR:
-                                       g_string_append_len (res, "\r\t", 2);
-                                       break;
-                               case RSPAMD_TASK_NEWLINES_CRLF:
-                               default:
-                                       g_string_append_len (res, "\r\n\t", 3);
-                                       break;
+                               /* Avoid double folding */
+                               last = &res->str[res->len - 1];
+                               last --;
+
+                               if (*last != '\r' && *last != '\n') {
+                                       last ++;
+                                       while (g_ascii_isspace (*last)) {
+                                               last --;
+                                               nspaces ++;
+                                               res->len --;
+                                       }
+
+                                       switch (how) {
+                                       case RSPAMD_TASK_NEWLINES_LF:
+                                               g_string_append_len (res, "\n\t", 2);
+                                               break;
+                                       case RSPAMD_TASK_NEWLINES_CR:
+                                               g_string_append_len (res, "\r\t", 2);
+                                               break;
+                                       case RSPAMD_TASK_NEWLINES_CRLF:
+                                       default:
+                                               g_string_append_len (res, "\r\n\t", 3);
+                                               break;
+                                       }
+                               }
+
+                               /* Move leftover spaces */
+                               cur_len = nspaces;
+
+                               while (nspaces) {
+                                       g_string_append_c (res, ' ');
+                                       nspaces --;
                                }
 
                                if (p > c) {
                                        g_string_append_len (res, c, p - c);
-                                       cur_len = p - c;
+                                       cur_len += p - c;
                                }
                                else {
                                        cur_len = 0;