mirror of
https://github.com/apache/httpd.git
synced 2025-08-03 16:33:59 +00:00
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
This commit is contained in:
@ -396,13 +396,12 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
|
|||||||
int rc;
|
int rc;
|
||||||
int options = 0;
|
int options = 0;
|
||||||
match_vector_pt ovector = NULL;
|
match_vector_pt ovector = NULL;
|
||||||
apr_size_t nlim = ((apr_size_t)preg->re_nsub + 1) > nmatch
|
apr_size_t ncaps = (apr_size_t)preg->re_nsub + 1;
|
||||||
? ((apr_size_t)preg->re_nsub + 1) : nmatch;
|
|
||||||
#if defined(HAVE_PCRE2) || defined(APR_HAS_THREAD_LOCAL)
|
#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
|
#else
|
||||||
int small_vector[POSIX_MALLOC_THRESHOLD * 3];
|
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
|
#endif
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
@ -424,25 +423,26 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
|
|||||||
0, options, data, NULL);
|
0, options, data, NULL);
|
||||||
#else
|
#else
|
||||||
rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
|
rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
|
||||||
0, options, ovector, nlim * 3);
|
0, options, ovector, ncaps * 3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rc >= 0) {
|
if (rc >= 0) {
|
||||||
apr_size_t n, i;
|
apr_size_t n = rc, i;
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
rc = nlim; /* All captured slots were filled in */
|
rc = ncaps; /* All captured slots were filled in */
|
||||||
n = (apr_size_t)rc < nmatch ? (apr_size_t)rc : nmatch;
|
else if (n > nmatch)
|
||||||
|
n = nmatch;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
pmatch[i].rm_so = ovector[i * 2];
|
pmatch[i].rm_so = ovector[i * 2];
|
||||||
pmatch[i].rm_eo = ovector[i * 2 + 1];
|
pmatch[i].rm_eo = ovector[i * 2 + 1];
|
||||||
}
|
}
|
||||||
for (; i < nmatch; i++)
|
for (; i < nmatch; i++)
|
||||||
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
|
pmatch[i].rm_so = pmatch[i].rm_eo = -1;
|
||||||
put_match_data(data, nlim);
|
put_match_data(data, ncaps);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
put_match_data(data, nlim);
|
put_match_data(data, ncaps);
|
||||||
#ifdef HAVE_PCRE2
|
#ifdef HAVE_PCRE2
|
||||||
if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21)
|
if (rc <= PCRE2_ERROR_UTF8_ERR1 && rc >= PCRE2_ERROR_UTF8_ERR21)
|
||||||
return AP_REG_INVARG;
|
return AP_REG_INVARG;
|
||||||
|
Reference in New Issue
Block a user