diff --git a/lib/logmatcher.c b/lib/logmatcher.c index 8f7140aa704..26481df207c 100644 --- a/lib/logmatcher.c +++ b/lib/logmatcher.c @@ -384,6 +384,7 @@ typedef struct _LogMatcherPcreMatchResult const gchar *source_value; gssize source_value_len; pcre2_match_data *match_data; + gboolean source_handles_value_changed; } LogMatcherPcreMatchResult; static inline void @@ -404,7 +405,8 @@ log_matcher_pcre_re_feed_value(LogMatcherPcreRe *self, LogMessage *msg, { gboolean indirect = result->source_handle != LM_V_NONE && log_msg_is_handle_settable_with_an_indirect_value(target_handle) && - log_msg_is_handle_referencable_from_an_indirect_value(result->source_handle); + log_msg_is_handle_referencable_from_an_indirect_value(result->source_handle) && + !result->source_handles_value_changed; if (target_handle == result->source_handle) { @@ -416,6 +418,8 @@ log_matcher_pcre_re_feed_value(LogMatcherPcreRe *self, LogMessage *msg, * make it less appearent, this is not always the case: it does not * happen if the new value does not fit the old NVEntry). */ log_matcher_pcre_re_save_source_value_to_avoid_clobbering(result); + result->source_handles_value_changed = TRUE; + indirect = FALSE; } if (indirect) @@ -509,6 +513,7 @@ log_matcher_pcre_re_match(LogMatcher *s, LogMessage *msg, gint value_handle, con result.source_value = value; result.source_value_len = value_len; result.source_handle = value_handle; + result.source_handles_value_changed = FALSE; rc = pcre2_match(self->pattern, (PCRE2_SPTR) result.source_value, diff --git a/lib/tests/test_matcher.c b/lib/tests/test_matcher.c index 2b69f0de010..fae26809e88 100644 --- a/lib/tests/test_matcher.c +++ b/lib/tests/test_matcher.c @@ -448,6 +448,41 @@ Test(matcher, test_matcher_matches_against_buffers_are_captured_directly) log_msg_unref(msg); } +Test(matcher, test_matcher_matches_are_captured_directly_if_source_handle_changes) +{ + LogMatcherOptions matcher_options; + LogMessage *msg; + gboolean result; + + const gchar *input = "kiwi-wiki-kiki"; + + msg = create_empty_message(); + log_msg_set_value_with_type(msg, LM_V_FILE_NAME, input, -1, LM_VT_STRING); + + log_matcher_options_defaults(&matcher_options); + matcher_options.flags = LMF_STORE_MATCHES; + LogMatcher *m = log_matcher_pcre_re_new(&matcher_options); + log_matcher_compile(m, "^(?kiwi)-(?wiki)-(?kiki)", NULL); + + result = log_matcher_match(m, msg, LM_V_FILE_NAME, input, 14); + cr_assert(result); + + assert_log_message_match_value(msg, 1, "kiwi"); + assert_log_message_match_value(msg, 2, "wiki"); + assert_log_message_match_value(msg, 3, "kiki"); + assert_log_message_value_by_name(msg, "A_foobar", "kiwi"); + assert_log_message_value_by_name(msg, "FILE_NAME", "wiki"); + assert_log_message_value_by_name(msg, "Z_barbaz", "kiki"); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("1")); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("2")); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("3")); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("A_foobar")); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("FILE_NAME")); + assert_log_message_value_is_direct(msg, log_msg_get_value_handle("Z_barbaz")); + log_matcher_unref(m); + log_msg_unref(msg); +} + Test(matcher, test_replace_works_correctly_if_capture_group_overwrites_the_input_in_a_match_variable) { gssize value_len; diff --git a/news/bugfix-4759.md b/news/bugfix-4759.md new file mode 100644 index 00000000000..d1acb54c467 --- /dev/null +++ b/news/bugfix-4759.md @@ -0,0 +1 @@ +`regexp-parser()`: Fixed a bug, which stored some values incorrectly if `${MESSAGE}` was changed with a capture group.