Hi all, hopefully it will be revealed useful, in this patch, we re trying to use the MALLOC/FREE macros since pcre* libraries are capable of overriding internally memory management.
I had a little related question, would it be better to provide function pointers of this form struct my_allocator { void *(*alloc)(void *, size_t), void (*free)(void *, void *)} .... } to allow using hierarical based allocators like talloc for example ... just thinking aloud not sure it s relevant. Kind regards.
From aab0ca1fd9e9f6584f2e2ab57ec290bbcd2bde23 Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Fri, 21 Jul 2017 07:26:38 +0100 Subject: [PATCH] MINOR: regex: using allocators macros Only pools use it at the moment, but since pcre (via its global pcre_malloc/pcre_free) and pcre2 (via contexts) can override memory management functions as well, we use here this possibility. --- include/common/regex.h | 6 ++++-- src/regex.c | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/include/common/regex.h b/include/common/regex.h index 2f171b3b..ec906a23 100644 --- a/include/common/regex.h +++ b/include/common/regex.h @@ -55,6 +55,7 @@ struct my_regex { #endif #elif USE_PCRE2 pcre2_code *reg; + pcre2_general_context *ctx; #else /* no PCRE */ regex_t regex; #endif @@ -105,7 +106,7 @@ static inline int regex_exec(const struct my_regex *preg, char *subject) { pcre2_match_data *pm; int ret; - pm = pcre2_match_data_create_from_pattern(preg->reg, NULL); + pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx); ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, 0, pm, NULL); pcre2_match_data_free(pm); @@ -136,7 +137,7 @@ static inline int regex_exec2(const struct my_regex *preg, char *subject, int le pcre2_match_data *pm; int ret; - pm = pcre2_match_data_create_from_pattern(preg->reg, NULL); + pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx); ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length, 0, 0, pm, NULL); pcre2_match_data_free(pm); @@ -172,6 +173,7 @@ static inline void regex_free(struct my_regex *preg) { pcre_free(preg->extra); #endif /* PCRE_CONFIG_JIT */ #elif defined(USE_PCRE2) || defined(USE_PCRE2_JIT) + pcre2_general_context_free(preg->ctx); pcre2_code_free(preg->reg); #else regfree(&preg->regex); diff --git a/src/regex.c b/src/regex.c index 38d7132b..26ef25ec 100644 --- a/src/regex.c +++ b/src/regex.c @@ -19,6 +19,7 @@ #include <common/defaults.h> #include <common/regex.h> #include <common/standard.h> +#include <common/memory.h> #include <proto/log.h> /* regex trash buffer used by various regex tests */ @@ -197,7 +198,7 @@ int regex_exec_match(const struct my_regex *preg, const char *subject, * space in the matches array. */ #ifdef USE_PCRE2 - pm = pcre2_match_data_create_from_pattern(preg->reg, NULL); + pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx); ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)strlen(subject), 0, options, pm, NULL); if (ret < 0) { @@ -208,7 +209,6 @@ int regex_exec_match(const struct my_regex *preg, const char *subject, matches = pcre2_get_ovector_pointer(pm); #else ret = pcre_exec(preg->reg, preg->extra, subject, strlen(subject), 0, options, matches, enmatch * 3); - if (ret < 0) return 0; #endif @@ -290,7 +290,7 @@ int regex_exec_match2(const struct my_regex *preg, char *subject, int length, * space in the matches array. */ #ifdef USE_PCRE2 - pm = pcre2_match_data_create_from_pattern(preg->reg, NULL); + pm = pcre2_match_data_create_from_pattern(preg->reg, preg->ctx); ret = pcre2_match(preg->reg, (PCRE2_SPTR)subject, (PCRE2_SIZE)length, 0, options, pm, NULL); if (ret < 0) { @@ -337,6 +337,34 @@ int regex_exec_match2(const struct my_regex *preg, char *subject, int length, #endif } +#if defined(USE_PCRE) || defined(USE_PCRE_JIT) +static inline void * +my_pcrealloc(size_t size) +{ + return MALLOC(size); +} + +static inline void +my_pcrefree(void *ptr) +{ + FREE(ptr); +} +#elif defined(USE_PCRE2) || defined(USE_PCRE2_JIT) +static inline void * +my_pcrealloc(PCRE2_SIZE size, void *a) +{ + (void)a; + return MALLOC(size); +} + +static inline void +my_pcrefree(void *ptr, void *a) +{ + (void)a; + FREE(ptr); +} +#endif + int regex_comp(const char *str, struct my_regex *regex, int cs, int cap, char **err) { #if defined(USE_PCRE) || defined(USE_PCRE_JIT) @@ -375,6 +403,7 @@ int regex_comp(const char *str, struct my_regex *regex, int cs, int cap, char ** if (!cap) flags |= PCRE2_NO_AUTO_CAPTURE; + regex->ctx = pcre2_general_context_create(my_pcrealloc, my_pcrefree, NULL); regex->reg = pcre2_compile((PCRE2_SPTR)str, PCRE2_ZERO_TERMINATED, flags, &errn, &erroffset, NULL); if (!regex->reg) { pcre2_get_error_message(errn, error, sizeof(error)); @@ -417,6 +446,8 @@ static void __regex_init(void) char *ptr = NULL; #ifdef USE_PCRE + pcre_malloc = my_pcrealloc; + pcre_free = my_pcrefree; memprintf(&ptr, "Built with PCRE version : %s", (HAP_XSTRING(Z PCRE_PRERELEASE)[1] == 0)? HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) : HAP_XSTRING(PCRE_MAJOR.PCRE_MINOR) HAP_XSTRING(PCRE_PRERELEASE PCRE_DATE)); -- 2.13.3