summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-11-22 19:46:05 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2021-11-22 22:33:05 -0500
commitc378e3ad8ca6a31b0760f127bb31cad25b8b98dd (patch)
tree4050314e24e43ac7a788869bcc625527d221e3b1
parent670b3a395ff6365bc92889d5aafd72e362dc97c2 (diff)
downloadlighttpd-git-c378e3ad8ca6a31b0760f127bb31cad25b8b98dd.tar.gz
[core] allocate pcre output vector on demand
allocate pcre output vector on demand for saved config captures (similar to what is done in lighttpd for pcre2 support)
-rw-r--r--src/configfile-glue.c10
-rw-r--r--src/configfile.h1
-rw-r--r--src/data_config.c1
-rw-r--r--src/plugin_config.h7
-rw-r--r--src/reqpool.c7
-rw-r--r--src/t/test_keyvalue.c12
6 files changed, 22 insertions, 16 deletions
diff --git a/src/configfile-glue.c b/src/configfile-glue.c
index 7602e419..e5403626 100644
--- a/src/configfile-glue.c
+++ b/src/configfile-glue.c
@@ -687,16 +687,18 @@ static int config_pcre_match(request_st * const r, const data_config * const dc,
matches, sizeof(matches)/sizeof(*matches));
}
- #ifndef elementsof
- #define elementsof(x) (sizeof(x) / sizeof(x[0]))
- #endif
const int capture_offset = dc->capture_idx - 1;
cond_match_t * const cond_match =
r->cond_match[capture_offset] = r->cond_match_data + capture_offset;
+ if (__builtin_expect( (NULL == cond_match->matches), 0)) {
+ /*(allocate on demand)*/
+ cond_match->matches = malloc(dc->ovec_nelts * sizeof(int *));
+ force_assert(cond_match->matches);
+ }
cond_match->comp_value = b; /*holds pointer to b (!) for pattern subst*/
cond_match->captures =
pcre_exec(dc->regex, dc->regex_study, BUF_PTR_LEN(b), 0, 0,
- cond_match->matches, elementsof(cond_match->matches));
+ cond_match->matches, dc->ovec_nelts);
return cond_match->captures;
#else
diff --git a/src/configfile.h b/src/configfile.h
index a181ee72..794fc936 100644
--- a/src/configfile.h
+++ b/src/configfile.h
@@ -41,6 +41,7 @@ struct data_config {
#elif defined(HAVE_PCRE_H)
void *regex;
struct pcre_extra *regex_study;
+ int ovec_nelts;
#endif
int capture_idx;
int ext;
diff --git a/src/data_config.c b/src/data_config.c
index 56c3a416..f8cacb97 100644
--- a/src/data_config.c
+++ b/src/data_config.c
@@ -166,6 +166,7 @@ int data_config_pcre_compile(data_config * const dc, const int pcre_jit, log_err
dc->string.ptr);
return 0;
}
+ dc->ovec_nelts = 3 * (captures + 1);
return 1;
#else
diff --git a/src/plugin_config.h b/src/plugin_config.h
index f61646c9..f4e4e452 100644
--- a/src/plugin_config.h
+++ b/src/plugin_config.h
@@ -173,12 +173,9 @@ typedef struct cond_match_t {
const buffer *comp_value; /* just a pointer */
#ifdef HAVE_PCRE2_H
struct pcre2_real_match_data_8 *match_data;
- int captures;
- void *matches; /* (PCRE2_SIZE *) */
- #elif defined(HAVE_PCRE_H)
- int captures;
- int matches[3 * 10];
#endif
+ int captures;
+ void *matches; /* pcre2:(PCRE2_SIZE *), pcre:(int *) */
} cond_match_t;
int config_check_cond(request_st *r, int context_ndx);
diff --git a/src/reqpool.c b/src/reqpool.c
index 9ffc1ddd..aca37a4d 100644
--- a/src/reqpool.c
+++ b/src/reqpool.c
@@ -232,12 +232,15 @@ request_free_data (request_st * const r)
free(r->cond_cache);
#ifdef HAVE_PCRE
if (r->cond_match_data) {
- #ifdef HAVE_PCRE2_H
for (int i = 0, used = r->con->srv->config_captures; i < used; ++i) {
+ #ifdef HAVE_PCRE2_H
if (r->cond_match_data[i].match_data)
pcre2_match_data_free(r->cond_match_data[i].match_data);
+ #else /* HAVE_PCRE_H */
+ if (r->cond_match_data[i].matches)
+ free(r->cond_match_data[i].matches);
+ #endif
}
- #endif
free(r->cond_match_data);
free(r->cond_match);
}
diff --git a/src/t/test_keyvalue.c b/src/t/test_keyvalue.c
index 57c8bcd3..0c63e437 100644
--- a/src/t/test_keyvalue.c
+++ b/src/t/test_keyvalue.c
@@ -67,12 +67,14 @@ static void test_keyvalue_pcre_keyvalue_buffer_process (void) {
cache.captures = 2;
#ifdef HAVE_PCRE2_H
PCRE2_SIZE matches[4];
- cache.matches = matches;
+ #else /* HAVE_PCRE_H */
+ int matches[4];
#endif
- cache.matches[0] = 0;
- cache.matches[1] = 15;
- cache.matches[2] = 0;
- cache.matches[3] = 3;
+ matches[0] = 0;
+ matches[1] = 15;
+ matches[2] = 0;
+ matches[3] = 3;
+ cache.matches = matches;
/* converted from prior sparse tests/mod-redirect.t and tests/mod-rewrite.t
* (real-world use should prefer ${url.path} and ${qsa} in substitutions)