From: Yann Ylavic Date: Thu, 20 Jan 2022 12:16:58 +0000 (+0000) Subject: ap_regex: PCRE needs buffers sized against the number of captures only. X-Git-Tag: 2.5.0-alpha2-ci-test-only~576 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a59c923685dce9f4d726f45c222df27bbdf1f1f;p=thirdparty%2Fapache%2Fhttpd.git 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 --- diff --git a/server/util_pcre.c b/server/util_pcre.c index 1dcd9507929..9bfa4791d8a 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;