From 64f81f95a19b28681a74a58b8cae205bff885755 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Wed, 7 Jun 2017 23:11:48 -0300 Subject: [PATCH] lib/index.cc: generalize filter state machine To match things more complicated than fixed strings, we need states with multiple out arrows. --- lib/index.cc | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/index.cc b/lib/index.cc index 19ddc39c..8a18abf4 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -159,16 +159,23 @@ filter_filter (GMimeFilter *gmime_filter, char *inbuf, size_t inlen, size_t pres g_mime_filter_set_size (gmime_filter, inlen, FALSE); outptr = gmime_filter->outbuf; + next = filter->state; while (inptr < inend) { - if (*inptr >= states[filter->state].a && - *inptr <= states[filter->state].b) - { - next = states[filter->state].next_if_match; - } - else - { - next = states[filter->state].next_if_not_match; - } + /* Each state is defined by a contiguous set of rows of the + * state table marked by a common value for '.state'. The + * state numbers must be equal to the index of the first row + * in a given state; thus the loop condition here looks for a + * jump to a first row of a state, which is a real transition + * in the underlying DFA. + */ + do { + if (*inptr >= states[next].a && *inptr <= states[next].b) { + next = states[next].next_if_match; + } else { + next = states[next].next_if_not_match; + } + + } while (next != states[next].state); if (filter->state < filter->first_skipping_state) *outptr++ = *inptr; -- 2.43.0