From: Timo Sirainen Date: Wed, 12 Sep 2018 13:30:32 +0000 (+0300) Subject: lib: event_filter_match() - "field=" filter now matches nonexistent field X-Git-Tag: 2.3.10~111 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93ca89c4e7e6c3a5f01e616de4f8374498d6bc81;p=thirdparty%2Fdovecot%2Fcore.git lib: event_filter_match() - "field=" filter now matches nonexistent field This makes sense, because event_filter_clear() also works by adding an empty value to the event. So it wouldn't even be possible to differentiate between empty and nonexistent fields unless larger changes were made. --- diff --git a/src/lib/event-filter.c b/src/lib/event-filter.c index 72ab1015dc..e3e692dbe0 100644 --- a/src/lib/event-filter.c +++ b/src/lib/event-filter.c @@ -458,14 +458,16 @@ event_match_field(struct event *event, const struct event_field *wanted_field) /* wanted_field has the value in all available formats */ while ((field = event_find_field(event, wanted_field->key)) == NULL) { event = event_get_parent(event); - if (event == NULL) - return FALSE; + if (event == NULL) { + /* "field=" matches nonexistent field */ + return wanted_field->value.str[0] == '\0'; + } } switch (field->value_type) { case EVENT_FIELD_VALUE_TYPE_STR: if (field->value.str[0] == '\0') { - /* field was removed */ - return FALSE; + /* field was removed, but it matches "field=" filter */ + return wanted_field->value.str[0] == '\0'; } return wildcard_match_icase(field->value.str, wanted_field->value.str); case EVENT_FIELD_VALUE_TYPE_INTMAX: diff --git a/src/lib/test-event-filter.c b/src/lib/test-event-filter.c index 840c3c43e8..cbaccccb5e 100644 --- a/src/lib/test-event-filter.c +++ b/src/lib/test-event-filter.c @@ -84,6 +84,7 @@ static void test_event_filter_clear_parent_fields(void) event_field_clear(child, "int"); for (unsigned int i = 0; i < N_ELEMENTS(keys); i++) { + /* match any value */ filter_fields[0].key = keys[i]; filter = event_filter_create(); event_filter_add(filter, &query); @@ -93,6 +94,26 @@ static void test_event_filter_clear_parent_fields(void) event_filter_unref(&filter); } + /* match empty field */ + filter_fields[0].key = "str"; + filter_fields[0].value = ""; + filter = event_filter_create(); + event_filter_add(filter, &query); + + test_assert(!event_filter_match(filter, parent, &failure_ctx)); + test_assert(event_filter_match(filter, child, &failure_ctx)); + event_filter_unref(&filter); + + /* match nonexistent field */ + filter_fields[0].key = "nonexistent"; + filter_fields[0].value = ""; + filter = event_filter_create(); + event_filter_add(filter, &query); + + test_assert(event_filter_match(filter, parent, &failure_ctx)); + test_assert(event_filter_match(filter, child, &failure_ctx)); + event_filter_unref(&filter); + event_unref(&parent); event_unref(&child); test_end();