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

Reply via email to