summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2024-01-16 17:51:03 +0100
committerYann Ylavic <ylavic@apache.org>2024-01-16 17:51:03 +0100
commite52a206008bdfced5551206d695b3c01b7d1948a (patch)
tree1a31dee4ba5d1e368bccbb2d7d04e36b02ec1163 /server
parentFix a typo (missing "t") (diff)
downloadapache2-e52a206008bdfced5551206d695b3c01b7d1948a.tar.xz
apache2-e52a206008bdfced5551206d695b3c01b7d1948a.zip
regex: Add ap_regexec_ex() which can take a starting offset to match from.
* include/ap_mmn.h: Bump MMN minor. * include/ap_regex.h: Declare ap_regexec_ex(). * server/util_pcre.c(ap_regexec, ap_regexec_len, ap_regexec_ex): Reuse existing ap_regexec_len() code to implement ap_regexec_ex() where the offset is given instead of zero, then implement ap_regexec{,len}() in terms of ap_regexec_ex(). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1915267 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r--server/util_pcre.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/server/util_pcre.c b/server/util_pcre.c
index 488f389ffe..da85c2da5d 100644
--- a/server/util_pcre.c
+++ b/server/util_pcre.c
@@ -427,13 +427,22 @@ AP_DECLARE(int) ap_regexec(const ap_regex_t *preg, const char *string,
apr_size_t nmatch, ap_regmatch_t *pmatch,
int eflags)
{
- return ap_regexec_len(preg, string, strlen(string), nmatch, pmatch,
- eflags);
+ return ap_regexec_ex(preg, string, strlen(string), 0,
+ nmatch, pmatch, eflags);
}
-AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
- apr_size_t len, apr_size_t nmatch,
- ap_regmatch_t *pmatch, int eflags)
+AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg,
+ const char *buff, apr_size_t len,
+ apr_size_t nmatch, ap_regmatch_t *pmatch,
+ int eflags)
+{
+ return ap_regexec_ex(preg, buff, len, 0, nmatch, pmatch, eflags);
+}
+
+AP_DECLARE(int) ap_regexec_ex(const ap_regex_t *preg,
+ const char *buff, apr_size_t len, apr_size_t pos,
+ apr_size_t nmatch, ap_regmatch_t *pmatch,
+ int eflags)
{
int rc;
int options = 0;
@@ -442,6 +451,11 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
apr_uint32_t ncaps = (apr_uint32_t)preg->re_nsub + 1;
#ifndef HAVE_PCRE2
+ /* PCRE1 uses ints, reject overflowing values */
+ if (len > APR_INT32_MAX || pos > APR_INT32_MAX) {
+ return AP_REG_INVARG;
+ }
+
/* This is fine if pcre_exec() gets a vector size smaller than the
* number of capturing groups (it will treat the remaining ones as
* non-capturing), but if the vector is too small to keep track of
@@ -482,13 +496,14 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
#ifdef HAVE_PCRE2
rc = pcre2_match((const pcre2_code *)preg->re_pcre,
- (const unsigned char *)buff, len, 0, options,
+ (const unsigned char *)buff, len, pos, options,
state.match_data, NULL);
ovector = pcre2_get_ovector_pointer(state.match_data);
#else
ovector = state.match_data;
- rc = pcre_exec((const pcre *)preg->re_pcre, NULL, buff, (int)len,
- 0, options, ovector, ncaps * 3);
+ rc = pcre_exec((const pcre *)preg->re_pcre, NULL,
+ buff, (int)len, (int)pos, options,
+ ovector, ncaps * 3);
#endif
if (rc >= 0) {