]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Fix event filtering for unnamed events with optional event name
authorsergey.kitov <sergey.kitov@open-xchange.com>
Fri, 29 Oct 2021 11:06:39 +0000 (14:06 +0300)
committertimo.sirainen <timo.sirainen@open-xchange.com>
Wed, 10 Nov 2021 14:04:08 +0000 (14:04 +0000)
For example event filter "event=ev_name OR field1=value1" wouldn't previously match
if the event didn't have any name, even if it did have field1=value1.

src/lib/event-filter-parser.y
src/lib/event-filter.c

index 3d5460043f8179e1233356c3ee975e9e90aaab51..652b896ba6fa837c298524ecdd45ae72438acdd7 100644 (file)
@@ -61,7 +61,6 @@ static struct event_filter_node *key_value(struct event_filter_parser_state *sta
                node->str = p_strdup(state->pool, b);
                if (wildcard_is_literal(node->str))
                        node->type = EVENT_FILTER_NODE_TYPE_EVENT_NAME_EXACT;
-               state->has_event_name = TRUE;
                break;
        case EVENT_FILTER_NODE_TYPE_EVENT_SOURCE_LOCATION: {
                const char *colon = strrchr(b, ':');
index b4f8ce566e142d3c34b4da0ecfbfad523d441386..9e3b8861d391b5cf0584daa4c133ef833d73c66a 100644 (file)
@@ -149,6 +149,23 @@ static void add_node(pool_t pool, struct event_filter_node **root,
        *root = parent;
 }
 
+static bool filter_node_requires_event_name(struct event_filter_node *node)
+{
+       switch (node->op) {
+       case EVENT_FILTER_OP_NOT:
+               return filter_node_requires_event_name(node->children[0]);
+       case EVENT_FILTER_OP_AND:
+               return filter_node_requires_event_name(node->children[0]) ||
+                       filter_node_requires_event_name(node->children[1]);
+       case EVENT_FILTER_OP_OR:
+               return filter_node_requires_event_name(node->children[0]) &&
+                       filter_node_requires_event_name(node->children[1]);
+       default:
+               return node->type == EVENT_FILTER_NODE_TYPE_EVENT_NAME_WILDCARD ||
+                       node->type == EVENT_FILTER_NODE_TYPE_EVENT_NAME_EXACT;
+       }
+}
+
 int event_filter_parse(const char *str, struct event_filter *filter,
                       const char **error_r)
 {
@@ -178,7 +195,8 @@ int event_filter_parse(const char *str, struct event_filter *filter,
                add_node(filter->pool, &int_query->expr, state.output,
                         EVENT_FILTER_OP_OR);
 
-               filter->named_queries_only = filter->named_queries_only && state.has_event_name;
+               filter->named_queries_only = filter->named_queries_only &&
+                       filter_node_requires_event_name(state.output);
        } else if (ret != 0) {
                /* error */
                i_assert(state.error != NULL);