]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: event-filter - Fix matching duration field
authorAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 15 Nov 2022 11:22:16 +0000 (13:22 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 15 Nov 2022 12:11:41 +0000 (14:11 +0200)
If duration field is used in event filter, it cannot be matched
here as no such field exists. We need to actually synthesize the
field here for matching.

src/lib/event-filter.c
src/lib/test-event-filter.c

index fe146e3d8803b16d6f65f10f37c12ae8f40be531..35bde967a70f4a3f2f177e3b39dd9ed030eaab1c 100644 (file)
@@ -539,9 +539,20 @@ event_match_field(struct event *event, const struct event_field *wanted_field,
                  enum event_filter_node_op op, bool use_strcmp)
 {
        const struct event_field *field;
-
-       /* wanted_field has the value in all available formats */
-       field = event_find_field_recursive(event, wanted_field->key);
+       struct event_field duration;
+
+       if (strcmp(wanted_field->key, "duration") == 0) {
+               uintmax_t duration_value;
+               i_zero(&duration);
+               duration.key = "duration";
+               duration.value_type = EVENT_FIELD_VALUE_TYPE_INTMAX;
+               event_get_last_duration(event, &duration_value);
+               duration.value.intmax = (intmax_t)duration_value;
+               field = &duration;
+       } else {
+               /* wanted_field has the value in all available formats */
+               field = event_find_field_recursive(event, wanted_field->key);
+       }
        if (field == NULL) {
                /* field="" matches nonexistent field */
                return wanted_field->value.str[0] == '\0';
index 8e1e130daece6d4cd5f2d28bfa54b0e97e92d895..cc963c0e3e3c922dda18dd8d085e6043f4120ac5 100644 (file)
@@ -581,6 +581,28 @@ static void test_event_filter_named_separate_from_str(void)
        test_end();
 }
 
+static void test_event_filter_duration(void)
+{
+       struct event_filter *filter;
+       const char *error;
+       const struct failure_context failure_ctx = {
+               .type = LOG_TYPE_DEBUG
+       };
+
+       test_begin("event filter: event duration");
+
+       /* we check that we can actually match duration field */
+       filter = event_filter_create();
+       test_assert(event_filter_parse("duration < 1000", filter, &error) == 0);
+
+       struct event *e = event_create(NULL);
+       test_assert(event_filter_match(filter, e, &failure_ctx));
+
+       event_filter_unref(&filter);
+       event_unref(&e);
+       test_end();
+}
+
 void test_event_filter(void)
 {
        test_event_filter_override_parent_fields();
@@ -595,4 +617,5 @@ void test_event_filter(void)
        test_event_filter_named_and_str();
        test_event_filter_named_or_str();
        test_event_filter_named_separate_from_str();
+       test_event_filter_duration();
 }