Skip to content

Commit 5859417

Browse files
committed
Use right PCRE functions to alloc/free pcre_extra
Allocate pcre_extra structure with pcre_study or pcre_malloc and free it with pcre_free_study(). Pass flag PCRE_STUDY_EXTRA_NEEDED to pcre_study telling it to always allocate pcre_extra because this structure is needed anyway to configure match limits. Until this change, pcre_extra was allocated with eigther pcre_malloc or regular malloc (depending on whether VERSION_NGINX is defined); function msc_pcre_cleanup(), which is responsible for freeing compiled regex data, used either regular free() or pcre_free() (depending VERSION_NGINX too) to free pcre_extra structure (pointer to which is stored in regex->pe). Freeing it like this was incorrect, structure returned by pcre_study() should be freed by function pcre_free_study(). In case PCRE JIT is used, pcre_study() makes some additional allocations itself (at least for JITed executable code), which function pcre_free_study() frees. If pcre_free_study() is not used a memory leak occurs because, while pcre_extra structure itself might be freed, some additional data referenced by it is not. Fix that by calling pcre_free_study() (instead of free()/pcre_free()) on pointer returned by pcre_study(). There also seems to be no reason to allocate pcre_extra with regular malloc (and de-allocate it with free()) - there is a function pcre_malloc(), which is a function pcre_study() itself would use to allocate that memory, and, in default case, pcre_malloc and pcre_free will be set to regular malloc and free. Usage of malloc() seems to be a remaining of old code where manual allocation of pcre_extra was always done with malloc(). So, remove "#if defined(VERSION_NGINX)" branches and always use pcre_malloc() for pcre_extra allocation in case pcre_study did not allocate it yet and always free is with pcre_free_study() (btw. 'pcreapi' man page recommends to replace pcre_free() usages to deallocate pcre_extra with pcre_free_study()). Fixes #610
1 parent f732fc6 commit 5859417

File tree

1 file changed

+3
-11
lines changed

1 file changed

+3
-11
lines changed

apache2/msc_pcre.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,7 @@
2121
static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
2222
if (regex != NULL) {
2323
if (regex->pe != NULL) {
24-
#if defined(VERSION_NGINX)
25-
pcre_free(regex->pe);
26-
#else
27-
free(regex->pe);
28-
#endif
24+
pcre_free_study(regex->pe);
2925
regex->pe = NULL;
3026
}
3127
if (regex->re != NULL) {
@@ -67,19 +63,15 @@ void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
6763

6864
#ifdef WITH_PCRE_STUDY
6965
#ifdef WITH_PCRE_JIT
70-
pe = pcre_study(regex->re, PCRE_STUDY_JIT_COMPILE, &errptr);
66+
pe = pcre_study(regex->re, PCRE_STUDY_EXTRA_NEEDED|PCRE_STUDY_JIT_COMPILE, &errptr);
7167
#else
72-
pe = pcre_study(regex->re, 0, &errptr);
68+
pe = pcre_study(regex->re, PCRE_STUDY_EXTRA_NEEDED, &errptr);
7369
#endif
7470
#endif
7571

7672
/* Setup the pcre_extra record if pcre_study did not already do it */
7773
if (pe == NULL) {
78-
#if defined(VERSION_NGINX)
7974
pe = pcre_malloc(sizeof(pcre_extra));
80-
#else
81-
pe = malloc(sizeof(pcre_extra));
82-
#endif
8375
if (pe == NULL) {
8476
return NULL;
8577
}

0 commit comments

Comments
 (0)