commit a5af7ff: [Minor] Apply all matching special handlers

Vsevolod Stakhov vsevolod at highsecure.ru
Tue Mar 26 18:28:04 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-03-26 15:57:43 +0000
URL: https://github.com/rspamd/rspamd/commit/a5af7ff8d409b63743889c5562c7b735e19313a8

[Minor] Apply all matching special handlers

---
 contrib/libucl/ucl_internal.h |  9 ++++++++-
 contrib/libucl/ucl_parser.c   | 13 ++++++++++---
 contrib/libucl/ucl_util.c     | 21 +++++++++++++--------
 3 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/contrib/libucl/ucl_internal.h b/contrib/libucl/ucl_internal.h
index ed4a7d767..edf647827 100644
--- a/contrib/libucl/ucl_internal.h
+++ b/contrib/libucl/ucl_internal.h
@@ -205,6 +205,13 @@ struct ucl_stack {
 	struct ucl_chunk *chunk;
 };
 
+struct ucl_parser_special_handler_chain {
+	unsigned char *begin;
+	size_t len;
+	struct ucl_parser_special_handler *special_handler;
+	struct ucl_parser_special_handler_chain *next;
+};
+
 struct ucl_chunk {
 	const unsigned char *begin;
 	const unsigned char *end;
@@ -216,7 +223,7 @@ struct ucl_chunk {
 	unsigned priority;
 	enum ucl_duplicate_strategy strategy;
 	enum ucl_parse_type parse_type;
-	struct ucl_parser_special_handler *special_handler;
+	struct ucl_parser_special_handler_chain *special_handlers;
 	struct ucl_chunk *next;
 };
 
diff --git a/contrib/libucl/ucl_parser.c b/contrib/libucl/ucl_parser.c
index 59bfd7727..7752f6661 100644
--- a/contrib/libucl/ucl_parser.c
+++ b/contrib/libucl/ucl_parser.c
@@ -2861,6 +2861,7 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
 
 		memset (chunk, 0, sizeof (*chunk));
 
+		/* Apply all matching handlers from the first to the last */
 		LL_FOREACH (parser->special_handlers, special_handler) {
 			if ((special_handler->flags & UCL_SPECIAL_HANDLER_PREPROCESS_ALL) ||
 					(len >= special_handler->magic_len &&
@@ -2874,11 +2875,17 @@ ucl_parser_add_chunk_full (struct ucl_parser *parser, const unsigned char *data,
 					return false;
 				}
 
+				struct ucl_parser_special_handler_chain *nchain;
+				nchain = UCL_ALLOC (sizeof (*nchain));
+				nchain->begin = ndata;
+				nchain->len = nlen;
+				nchain->special_handler = special_handler;
+
+				/* Free order is reversed */
+				LL_PREPEND (chunk->special_handlers, nchain);
+
 				data = ndata;
 				len = nlen;
-				chunk->special_handler = special_handler;
-
-				break;
 			}
 		}
 
diff --git a/contrib/libucl/ucl_util.c b/contrib/libucl/ucl_util.c
index 11799ab1e..6f36e5e73 100644
--- a/contrib/libucl/ucl_util.c
+++ b/contrib/libucl/ucl_util.c
@@ -520,18 +520,23 @@ void
 ucl_chunk_free (struct ucl_chunk *chunk)
 {
 	if (chunk) {
-		if (chunk->special_handler) {
-			if (chunk->special_handler->free_function) {
-				chunk->special_handler->free_function (
-						(unsigned char *) chunk->begin,
-						chunk->end - chunk->begin,
-						chunk->special_handler->user_data);
+		struct ucl_parser_special_handler_chain *chain, *tmp;
+
+		LL_FOREACH_SAFE (chunk->special_handlers, chain, tmp) {
+			if (chain->special_handler->free_function) {
+				chain->special_handler->free_function (
+						chain->begin,
+						chain->len,
+						chain->special_handler->user_data);
 			} else {
-				UCL_FREE (chunk->end - chunk->begin,
-						(unsigned char *) chunk->begin);
+				UCL_FREE (chain->len, chain->begin);
 			}
+
+			UCL_FREE (sizeof (*chain), chain);
 		}
 
+		chunk->special_handlers = NULL;
+
 		if (chunk->fname) {
 			free (chunk->fname);
 		}


More information about the Commits mailing list