]> source.dussan.org Git - rspamd.git/commitdiff
[Minor] Apply all matching special handlers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 26 Mar 2019 15:57:43 +0000 (15:57 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 26 Mar 2019 15:57:43 +0000 (15:57 +0000)
contrib/libucl/ucl_internal.h
contrib/libucl/ucl_parser.c
contrib/libucl/ucl_util.c

index ed4a7d76778dd6badb9d8f9b3e3a0bfe8e5f1c7c..edf64782701f659637ab351de1a7fa64d9b4d104 100644 (file)
@@ -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;
 };
 
index 59bfd7727cab4afc0c33c47c0aecbd934e631c08..7752f666190326dccf93d92336586409ec34ba39 100644 (file)
@@ -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;
                        }
                }
 
index 11799ab1e58daa8e739a2815ed69b8a82465b78d..6f36e5e736303d178d2bb9ccc306c368f6db3dbc 100644 (file)
@@ -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);
                }