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 <[email protected]>
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