From 275cdcc8d92f7cd9ca77ac25282b52c3d2dbaaf7 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 3 Apr 2018 15:36:41 +0100 Subject: [PATCH] [Fix] Another fix in folding algorithm --- src/libserver/dkim.c | 25 ++++++++++++------- src/libutil/str_util.c | 54 ++++++++++++++++++++++++++++++------------ 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/libserver/dkim.c b/src/libserver/dkim.c index 8e264a99a..f2914535f 100644 --- a/src/libserver/dkim.c +++ b/src/libserver/dkim.c @@ -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) { diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 4d1b22076..d571efabb 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -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; -- 2.39.5