Merge branch 'cb/pcre2-chartables-leakfix'
Leakfix. * cb/pcre2-chartables-leakfix: grep: avoid leak of chartables in PCRE2 grep: make PCRE2 aware of custom allocator grep: make PCRE1 aware of custom allocator
This commit is contained in:
@ -1147,5 +1147,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
|
|||||||
run_pager(&opt, prefix);
|
run_pager(&opt, prefix);
|
||||||
clear_pathspec(&pathspec);
|
clear_pathspec(&pathspec);
|
||||||
free_grep_patterns(&opt);
|
free_grep_patterns(&opt);
|
||||||
|
grep_destroy();
|
||||||
return !hit;
|
return !hit;
|
||||||
}
|
}
|
||||||
|
47
grep.c
47
grep.c
@ -16,6 +16,20 @@ static int grep_source_is_binary(struct grep_source *gs,
|
|||||||
|
|
||||||
static struct grep_opt grep_defaults;
|
static struct grep_opt grep_defaults;
|
||||||
|
|
||||||
|
#ifdef USE_LIBPCRE2
|
||||||
|
static pcre2_general_context *pcre2_global_context;
|
||||||
|
|
||||||
|
static void *pcre2_malloc(PCRE2_SIZE size, MAYBE_UNUSED void *memory_data)
|
||||||
|
{
|
||||||
|
return malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pcre2_free(void *pointer, MAYBE_UNUSED void *memory_data)
|
||||||
|
{
|
||||||
|
return free(pointer);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char *color_grep_slots[] = {
|
static const char *color_grep_slots[] = {
|
||||||
[GREP_COLOR_CONTEXT] = "context",
|
[GREP_COLOR_CONTEXT] = "context",
|
||||||
[GREP_COLOR_FILENAME] = "filename",
|
[GREP_COLOR_FILENAME] = "filename",
|
||||||
@ -150,12 +164,28 @@ int grep_config(const char *var, const char *value, void *cb)
|
|||||||
* Initialize one instance of grep_opt and copy the
|
* Initialize one instance of grep_opt and copy the
|
||||||
* default values from the template we read the configuration
|
* default values from the template we read the configuration
|
||||||
* information in an earlier call to git_config(grep_config).
|
* information in an earlier call to git_config(grep_config).
|
||||||
|
*
|
||||||
|
* If using PCRE, make sure that the library is configured
|
||||||
|
* to use the same allocator as Git (e.g. nedmalloc on Windows).
|
||||||
|
*
|
||||||
|
* Any allocated memory needs to be released in grep_destroy().
|
||||||
*/
|
*/
|
||||||
void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
|
void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix)
|
||||||
{
|
{
|
||||||
struct grep_opt *def = &grep_defaults;
|
struct grep_opt *def = &grep_defaults;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
#if defined(USE_LIBPCRE2)
|
||||||
|
if (!pcre2_global_context)
|
||||||
|
pcre2_global_context = pcre2_general_context_create(
|
||||||
|
pcre2_malloc, pcre2_free, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_LIBPCRE1
|
||||||
|
pcre_malloc = malloc;
|
||||||
|
pcre_free = free;
|
||||||
|
#endif
|
||||||
|
|
||||||
memset(opt, 0, sizeof(*opt));
|
memset(opt, 0, sizeof(*opt));
|
||||||
opt->repo = repo;
|
opt->repo = repo;
|
||||||
opt->prefix = prefix;
|
opt->prefix = prefix;
|
||||||
@ -178,6 +208,13 @@ void grep_init(struct grep_opt *opt, struct repository *repo, const char *prefix
|
|||||||
color_set(opt->colors[i], def->colors[i]);
|
color_set(opt->colors[i], def->colors[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void grep_destroy(void)
|
||||||
|
{
|
||||||
|
#ifdef USE_LIBPCRE2
|
||||||
|
pcre2_general_context_free(pcre2_global_context);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
|
static void grep_set_pattern_type_option(enum grep_pattern_type pattern_type, struct grep_opt *opt)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -461,7 +498,6 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
|
|||||||
PCRE2_UCHAR errbuf[256];
|
PCRE2_UCHAR errbuf[256];
|
||||||
PCRE2_SIZE erroffset;
|
PCRE2_SIZE erroffset;
|
||||||
int options = PCRE2_MULTILINE;
|
int options = PCRE2_MULTILINE;
|
||||||
const uint8_t *character_tables = NULL;
|
|
||||||
int jitret;
|
int jitret;
|
||||||
int patinforet;
|
int patinforet;
|
||||||
size_t jitsizearg;
|
size_t jitsizearg;
|
||||||
@ -470,11 +506,15 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
|
|||||||
|
|
||||||
p->pcre2_compile_context = NULL;
|
p->pcre2_compile_context = NULL;
|
||||||
|
|
||||||
|
/* pcre2_global_context is initialized in append_grep_pattern */
|
||||||
if (opt->ignore_case) {
|
if (opt->ignore_case) {
|
||||||
if (!opt->ignore_locale && has_non_ascii(p->pattern)) {
|
if (!opt->ignore_locale && has_non_ascii(p->pattern)) {
|
||||||
character_tables = pcre2_maketables(NULL);
|
if (!pcre2_global_context)
|
||||||
|
BUG("pcre2_global_context uninitialized");
|
||||||
|
p->pcre2_tables = pcre2_maketables(pcre2_global_context);
|
||||||
p->pcre2_compile_context = pcre2_compile_context_create(NULL);
|
p->pcre2_compile_context = pcre2_compile_context_create(NULL);
|
||||||
pcre2_set_character_tables(p->pcre2_compile_context, character_tables);
|
pcre2_set_character_tables(p->pcre2_compile_context,
|
||||||
|
p->pcre2_tables);
|
||||||
}
|
}
|
||||||
options |= PCRE2_CASELESS;
|
options |= PCRE2_CASELESS;
|
||||||
}
|
}
|
||||||
@ -571,6 +611,7 @@ static void free_pcre2_pattern(struct grep_pat *p)
|
|||||||
pcre2_compile_context_free(p->pcre2_compile_context);
|
pcre2_compile_context_free(p->pcre2_compile_context);
|
||||||
pcre2_code_free(p->pcre2_pattern);
|
pcre2_code_free(p->pcre2_pattern);
|
||||||
pcre2_match_data_free(p->pcre2_match_data);
|
pcre2_match_data_free(p->pcre2_match_data);
|
||||||
|
free((void *)p->pcre2_tables);
|
||||||
}
|
}
|
||||||
#else /* !USE_LIBPCRE2 */
|
#else /* !USE_LIBPCRE2 */
|
||||||
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
|
static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt)
|
||||||
|
2
grep.h
2
grep.h
@ -78,6 +78,7 @@ struct grep_pat {
|
|||||||
pcre2_code *pcre2_pattern;
|
pcre2_code *pcre2_pattern;
|
||||||
pcre2_match_data *pcre2_match_data;
|
pcre2_match_data *pcre2_match_data;
|
||||||
pcre2_compile_context *pcre2_compile_context;
|
pcre2_compile_context *pcre2_compile_context;
|
||||||
|
const uint8_t *pcre2_tables;
|
||||||
uint32_t pcre2_jit_on;
|
uint32_t pcre2_jit_on;
|
||||||
unsigned fixed:1;
|
unsigned fixed:1;
|
||||||
unsigned is_fixed:1;
|
unsigned is_fixed:1;
|
||||||
@ -172,6 +173,7 @@ struct grep_opt {
|
|||||||
void init_grep_defaults(struct repository *);
|
void init_grep_defaults(struct repository *);
|
||||||
int grep_config(const char *var, const char *value, void *);
|
int grep_config(const char *var, const char *value, void *);
|
||||||
void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
|
void grep_init(struct grep_opt *, struct repository *repo, const char *prefix);
|
||||||
|
void grep_destroy(void);
|
||||||
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
|
void grep_commit_pattern_type(enum grep_pattern_type, struct grep_opt *opt);
|
||||||
|
|
||||||
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
|
void append_grep_pat(struct grep_opt *opt, const char *pat, size_t patlen, const char *origin, int no, enum grep_pat_token t);
|
||||||
|
Reference in New Issue
Block a user