[PATCH 1/1] pcre2: allow overriding the system allocator

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Schindelin <johannes.schindelin@xxxxxx>

Since 7d3bf769994 (grep: avoid leak of chartables in PCRE2, 2019-08-01),
we try to release the UTF-8 tables obtained via `pcre2_maketables()`. To
do that, we use the function `free()`. That is all fine and dandy as
long as that refers to the system allocator.

However, when we compile Git with `USE_NED_ALLOCATOR` (notably on
Windows), then `free()` actually calls `nedfree()`. But
`pcre2_maketables()` allocated the tables using the system allocator
because we did not tell it to use nedmalloc instead.

This leads to segmentation faults when the UTF-8 tables are released,
most notably in the `t7816-grep-binary-pattern.sh` test script.

PCRE2 does have an option to override the allocator it should use, and
this patch calls upon it.

As there are other ways to override the system allocator than
`USE_NED_ALLOCATOR`, we choose to specify the allocator we want to use
specifically, even if we still use the system allocator.

Signed-off-by: Johannes Schindelin <johannes.schindelin@xxxxxx>
---
 grep.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/grep.c b/grep.c
index d4c5d464ad..d6d29fc724 100644
--- a/grep.c
+++ b/grep.c
@@ -482,6 +482,27 @@ static void free_pcre1_regexp(struct grep_pat *p)
 #endif /* !USE_LIBPCRE1 */
 
 #ifdef USE_LIBPCRE2
+static void *pcre2_malloc(PCRE2_SIZE size, void *memory_data)
+{
+	return malloc(size);
+}
+
+static void pcre2_free(void *pointer, void *memory_data)
+{
+	return free(pointer);
+}
+
+static pcre2_general_context *get_pcre2_context(void)
+{
+	static pcre2_general_context *context;
+
+	if (!context)
+		context = pcre2_general_context_create(pcre2_malloc,
+						       pcre2_free, NULL);
+
+	return context;
+}
+
 static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
 {
 	int error;
@@ -498,8 +519,9 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 
 	if (opt->ignore_case) {
 		if (has_non_ascii(p->pattern)) {
-			p->pcre2_tables = pcre2_maketables(NULL);
-			p->pcre2_compile_context = pcre2_compile_context_create(NULL);
+			p->pcre2_tables = pcre2_maketables(get_pcre2_context());
+			p->pcre2_compile_context =
+				pcre2_compile_context_create(get_pcre2_context());
 			pcre2_set_character_tables(p->pcre2_compile_context,
 							p->pcre2_tables);
 		}
@@ -513,7 +535,8 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 					 p->pcre2_compile_context);
 
 	if (p->pcre2_pattern) {
-		p->pcre2_match_data = pcre2_match_data_create_from_pattern(p->pcre2_pattern, NULL);
+		p->pcre2_match_data =
+			pcre2_match_data_create_from_pattern(p->pcre2_pattern, get_pcre2_context());
 		if (!p->pcre2_match_data)
 			die("Couldn't allocate PCRE2 match data");
 	} else {
@@ -550,7 +573,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
 			return;
 		}
 
-		p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, NULL);
+		p->pcre2_jit_stack = pcre2_jit_stack_create(1, 1024 * 1024, get_pcre2_context());
 		if (!p->pcre2_jit_stack)
 			die("Couldn't allocate PCRE2 JIT stack");
 		p->pcre2_match_context = pcre2_match_context_create(NULL);
-- 
gitgitgadget



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux