diff options
author | Yann Ylavic <ylavic@apache.org> | 2022-01-20 12:16:58 +0000 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2022-01-20 12:16:58 +0000 |
commit | 2a59c923685dce9f4d726f45c222df27bbdf1f1f (patch) | |
tree | 89c12bfbf0e2e9186e8deff1e0711d528435879f /server | |
parent | 702712a43d0a2d671e001e7c0107a79aaaa4fc3c (diff) | |
download | httpd-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.c | 20 |
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; |