aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2018-11-13 17:51:55 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-11-13 17:51:55 +0000
commit18c8f28606d6beb2e2fc2bcd177bddef139752be (patch)
tree8c294ec341d6f4e4b4ee6aedb62928252521843a
parent6536352d531e9c6602c59e909c88146d089e2732 (diff)
downloadrspamd-18c8f28606d6beb2e2fc2bcd177bddef139752be.tar.gz
rspamd-18c8f28606d6beb2e2fc2bcd177bddef139752be.zip
[Fix] Add obs_fws state support to eoh state machine
Issue: #2584
-rw-r--r--src/libutil/str_util.c99
1 files changed, 98 insertions, 1 deletions
diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c
index 09817a344..4f7aa1c97 100644
--- a/src/libutil/str_util.c
+++ b/src/libutil/str_util.c
@@ -1428,7 +1428,8 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
got_lf,
got_linebreak,
got_linebreak_cr,
- got_linebreak_lf
+ got_linebreak_lf,
+ obs_fws
} state = skip_char;
g_assert (input != NULL);
@@ -1478,7 +1479,9 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
}
else if (g_ascii_isspace (*p)) {
/* We have \r<space>*, allow to stay in this state */
+ c = p;
p ++;
+ state = obs_fws;
}
else {
p++;
@@ -1498,7 +1501,9 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
}
else if (g_ascii_isspace (*p)) {
/* We have \n<space>*, allow to stay in this state */
+ c = p;
p ++;
+ state = obs_fws;
}
else {
p++;
@@ -1518,7 +1523,9 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
}
else if (g_ascii_isspace (*p)) {
/* We have <linebreak><space>*, allow to stay in this state */
+ c = p;
p ++;
+ state = obs_fws;
}
else {
p++;
@@ -1537,6 +1544,8 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
}
else if (g_ascii_isspace (*p)) {
/* We have \r\n<space>*, allow to keep in this state */
+ c = p;
+ state = obs_fws;
p ++;
}
else {
@@ -1552,7 +1561,95 @@ rspamd_string_find_eoh (GString *input, goffset *body_start)
}
return c - input->str;
+ case obs_fws:
+ if (*p == ' ' || *p == '\t') {
+ p ++;
+ }
+ else if (*p == '\r') {
+ /* Perform lookahead due to #2349 */
+ if (end - p > 2) {
+ if (p[1] == '\n' && g_ascii_isspace (p[2])) {
+ /* Real obs_fws state, switch */
+ c = p;
+ p ++;
+ state = got_cr;
+ }
+ else if (g_ascii_isspace (p[1])) {
+ p ++;
+ state = obs_fws;
+ }
+ else {
+ /*
+ * newline wsp+ \r <nwsp>, hence:
+ * c -> eoh
+ * p + 1 -> body start
+ */
+ if (body_start) {
+ /* \r\n\r\n */
+ *body_start = p - input->str + 1;
+ }
+
+ return c - input->str;
+ }
+ }
+ else {
+ /* shortage */
+ if (body_start) {
+ *body_start = p - input->str + 1;
+ }
+
+ return p - input->str;
+ }
+ }
+ else if (*p == '\n') {
+ /* Perform lookahead due to #2349 */
+ if (end - p > 1) {
+ if (p[1] == ' ' || p[1] == '\t') {
+ c = p;
+ p ++;
+ state = obs_fws;
+ }
+ else if (p[1] == '\r') {
+ c = p;
+ p ++;
+ state = got_lf;
+ }
+ else if (p[1] == '\n') {
+ c = p;
+ p ++;
+ state = got_lf;
+ }
+ else {
+ /*
+ * newline wsp+ \n <nwsp>, hence:
+ * c -> eoh
+ * p + 1 -> body start
+ */
+ if (body_start) {
+ /* \r\n\r\n */
+ *body_start = p - input->str + 1;
+ }
+
+ return c - input->str;
+ }
+
+ }
+ else {
+ /* shortage */
+ if (body_start) {
+ *body_start = p - input->str + 1;
+ }
+
+ return p - input->str;
+ }
+ }
+ else {
+ p++;
+ state = skip_char;
+ }
+ break;
}
+
}
if (state == got_linebreak_lf) {