diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-12-14 16:40:01 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2021-12-14 16:40:01 +0000 |
commit | c1f6f952f4932089c45d36b71919330e5ee8dfe1 (patch) | |
tree | 1fee3b43f3b5f269690e3d18e076c7f48cad517f | |
parent | 19afb90db2d67a43cde5959e211134cf4231f624 (diff) | |
download | rspamd-c1f6f952f4932089c45d36b71919330e5ee8dfe1.tar.gz rspamd-c1f6f952f4932089c45d36b71919330e5ee8dfe1.zip |
[Minor] More fixes for headers folding
-rw-r--r-- | src/libutil/str_util.c | 109 |
1 files changed, 53 insertions, 56 deletions
diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c index 50af10f28..88f9ce3e5 100644 --- a/src/libutil/str_util.c +++ b/src/libutil/str_util.c @@ -1581,7 +1581,7 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, GString *res; const guint default_fold_max = 76; guint cur_len; - const gchar *p, *c, *end; + const gchar *p, *c, *end, *fold_sequence; guint nspaces = 0; gboolean first_token = TRUE; enum { @@ -1603,6 +1603,19 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, fold_max = default_fold_max; } + switch (how) { + case RSPAMD_TASK_NEWLINES_LF: + fold_sequence = "\n\t"; + break; + case RSPAMD_TASK_NEWLINES_CR: + fold_sequence = "\r\t"; + break; + case RSPAMD_TASK_NEWLINES_CRLF: + default: + fold_sequence ="\r\n\t"; + break; + } + res = g_string_sized_new (value_len); c = value; @@ -1653,16 +1666,44 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, state = fold_token; next_state = read_token; } else { - /* Reset line length */ - cur_len = 0; + /* We need to ensure that it is a folding and not something else */ + + const char *t = p; + bool seen_fold = false; - while (g_ascii_isspace (*p)) { - p++; + while (t < end) { + if (*t == ' ' || *t == '\t') { + seen_fold = true; + break; + } + else if (!g_ascii_isspace(*t)) { + break; + } + + t++; } - g_string_append_len (res, c, p - c); - c = p; - first_token = TRUE; + if (seen_fold) { + /* Reset line length */ + cur_len = 0; + + while (g_ascii_isspace (*p)) { + p++; + } + + g_string_append_len(res, c, p - c); + c = p; + first_token = TRUE; + } + else { + /* Not seen folding, inject it */ + g_string_append_len (res, c, p - c); + g_string_append (res, fold_sequence); + p = t; /* Adjust p to ensure that we do not append extra stuff */ + state = read_token; + first_token = TRUE; + c = p; + } } } else if (g_ascii_isspace (*p)) { if (cur_len > fold_max * 0.8 && cur_len < fold_max) { @@ -1707,18 +1748,7 @@ rspamd_header_value_fold (const gchar *name, gsize name_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; - } + g_string_append (res, fold_sequence); /* Skip space if needed */ if (g_ascii_isspace (*p)) { @@ -1753,18 +1783,7 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, 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; - } + g_string_append (res, fold_sequence); } /* Move leftover spaces */ @@ -1816,18 +1835,7 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, if (g_ascii_isspace (*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; - } + g_string_append (res, fold_sequence); g_string_append_len (res, c, p - c); } else { @@ -1846,18 +1854,7 @@ rspamd_header_value_fold (const gchar *name, gsize name_len, else { if (*c != '\r' && *c != '\n') { /* We need to add folding as well */ - 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; - } + g_string_append (res, fold_sequence); g_string_append_len (res, c, p - c); } else { |