summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2022-01-20 12:16:58 +0000
committerYann Ylavic <ylavic@apache.org>2022-01-20 12:16:58 +0000
commit2a59c923685dce9f4d726f45c222df27bbdf1f1f (patch)
tree89c12bfbf0e2e9186e8deff1e0711d528435879f /server
parent702712a43d0a2d671e001e7c0107a79aaaa4fc3c (diff)
downloadhttpd-2a59c923685dce9f4d726f45c222df27bbdf1f1f.tar.gz
ap_regex: PCRE needs buffers sized against the number of captures only.
No more (useless), no less (or PCRE will allocate a new buffer by itself to satisfy the needs), so we should base our buffer size solely on the number of captures in the regex (determined at compile time from the pattern). The nmatch provided by the user is used to fill in pmatch only (up to that), but "our" buffers are sized exactly as needed to avoid oversized allocations or PCRE allocating by itself. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1897244 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r--server/util_pcre.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/server/util_pcre.c b/server/util_pcre.c
index 1dcd950792..9bfa4791d8 100644
--- a/server/util_pcre.c
+++ b/server/util_pcre.c
@@ -396,13 +396,12 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
int rc;
int options = 0;
match_vector_pt ovector = NULL;
- apr_size_t nlim = ((apr_size_t)preg->re_nsub + 1) > nmatch
- ? ((apr_size_t)preg->re_nsub + 1) : nmatch;
+ apr_size_t ncaps = (apr_size_t)preg->re_nsub + 1;
#if defined(HAVE_PCRE2) || defined(APR_HAS_THREAD_LOCAL)
- match_data_pt data = get_match_data(nlim, &ovector, NULL);
+ match_data_pt data = get_match_data(ncaps, &ovector, NULL);
#else
int small_vector[POSIX_MALLOC_THRESHOLD * 3];
- match_data_pt data = get_match_data(nlim, &ovector, small_vector);
+ match_data_pt data = get_match_data(ncaps, &ovector, small_vector);
#endif
if (!data) {
@@ -424,25 +423,26 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
0, options, data, NULL);
#else
rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
- 0, options, ovector, nlim * 3);
+ 0, options, ovector, ncaps * 3);
#endif
if (rc >= 0) {
- apr_size_t n, i;
+ apr_size_t n = rc, i;
if (rc == 0)
- rc = nlim; /* All captured slots were filled in */
- n = (apr_size_t)rc < nmatch ? (apr_size_t)rc : nmatch;
+ rc = ncaps; /* All captured slots were filled in */
+ else if (n > nmatch)
+ n = nmatch;
for (i = 0; i < n; i++) {
pmatch[i].rm_so = ovector[i * 2];
pmatch[i].rm_eo = ovector[i * 2 + 1];
}
for (; i < nmatch; i++)
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
- put_match_data(data, nlim);
+ put_match_data(data, ncaps);
return 0;
}
else {
- put_match_data(data, nlim);
+ put_match_data(data, ncaps);
#ifdef HAVE_PCRE2
if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21)
return AP_REG_INVARG;