Am 09.08.19 um 13:24 schrieb Carlo Arenas: > disregard this version, it still broken (and wouldn't even build on > some cases), the reasons why are still unclear though but at least it > might > seem from the last known run in windows that segfaults were prevented > at last and something was still off enough to trigger a BUG (shouldn't > be a concern with V6 or later that do PCRE2 migration to NED fully, as > agreed) So how about starting stupidly simple? You can test it everywhere, it just needs libpcre2. It works without that library as well (tested with "make USE_LIBPCRE= USE_LIBPCRE2= test"), but doesn't allocate anything in that case, of course. The character tables leak fix should be safe on top. If you detect performance issues then we can address them in additional patches. -- >8 -- Subject: [PATCH] grep: use xmalloc() for all PCRE2 allocations Build a PCRE2 global custom context when compiling a pattern and use it to tell the library to use xmalloc() for allocations. This provides consistent out-of-memory handling and makes sure it uses a custom allocator, e.g. with USE_NED_ALLOCATOR. Signed-off-by: René Scharfe <l.s.r@xxxxxx> --- The function names are ridiculously long, I tried to stay within 80 characters per line but gave up in the end and just kept going without line breaks. Fits the "stupidly simple" approach.. grep.c | 23 +++++++++++++++++------ grep.h | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/grep.c b/grep.c index cd952ef5d3..44f4e38657 100644 --- a/grep.c +++ b/grep.c @@ -482,6 +482,16 @@ static void free_pcre1_regexp(struct grep_pat *p) #endif /* !USE_LIBPCRE1 */ #ifdef USE_LIBPCRE2 +static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data) +{ + return xmalloc(size); +} + +static void pcre2_free(void *pointer, MAYBE_UNUSED void *memory_data) +{ + free(pointer); +} + static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) { int error; @@ -495,12 +505,12 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt assert(opt->pcre2); - p->pcre2_compile_context = NULL; + p->pcre2_general_context = pcre2_general_context_create(pcre2_malloc, pcre2_free, NULL); + p->pcre2_compile_context = pcre2_compile_context_create(p->pcre2_general_context); if (opt->ignore_case) { if (has_non_ascii(p->pattern)) { - character_tables = pcre2_maketables(NULL); - p->pcre2_compile_context = pcre2_compile_context_create(NULL); + character_tables = pcre2_maketables(p->pcre2_general_context); pcre2_set_character_tables(p->pcre2_compile_context, character_tables); } options |= PCRE2_CASELESS; @@ -513,7 +523,7 @@ 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, p->pcre2_general_context); if (!p->pcre2_match_data) die("Couldn't allocate PCRE2 match data"); } else { @@ -550,10 +560,10 @@ 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, p->pcre2_general_context); if (!p->pcre2_jit_stack) die("Couldn't allocate PCRE2 JIT stack"); - p->pcre2_match_context = pcre2_match_context_create(NULL); + p->pcre2_match_context = pcre2_match_context_create(p->pcre2_general_context); if (!p->pcre2_match_context) die("Couldn't allocate PCRE2 match context"); pcre2_jit_stack_assign(p->pcre2_match_context, NULL, p->pcre2_jit_stack); @@ -605,6 +615,7 @@ static void free_pcre2_pattern(struct grep_pat *p) pcre2_match_data_free(p->pcre2_match_data); pcre2_jit_stack_free(p->pcre2_jit_stack); pcre2_match_context_free(p->pcre2_match_context); + pcre2_general_context_free(p->pcre2_general_context); } #else /* !USE_LIBPCRE2 */ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt) diff --git a/grep.h b/grep.h index 1875880f37..73b8b87a3a 100644 --- a/grep.h +++ b/grep.h @@ -28,6 +28,7 @@ typedef int pcre_jit_stack; #else typedef int pcre2_code; typedef int pcre2_match_data; +typedef int pcre2_general_context; typedef int pcre2_compile_context; typedef int pcre2_match_context; typedef int pcre2_jit_stack; @@ -93,6 +94,7 @@ struct grep_pat { int pcre1_jit_on; pcre2_code *pcre2_pattern; pcre2_match_data *pcre2_match_data; + pcre2_general_context *pcre2_general_context; pcre2_compile_context *pcre2_compile_context; pcre2_match_context *pcre2_match_context; pcre2_jit_stack *pcre2_jit_stack; -- 2.22.0