From 2a59c923685dce9f4d726f45c222df27bbdf1f1f Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Thu, 20 Jan 2022 12:16:58 +0000 Subject: [PATCH] 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 --- server/util_pcre.c | 20 ++++++++++---------- 1 file 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;