From 4d766e70501cd1150aa53dd4b0b1b362f3529e84 Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Fri, 16 Feb 2018 13:27:44 +0000 Subject: *) regex: Allow to configure global/default options for regexes, like caseless matching or extended format. trunk patch: http://svn.apache.org/r1824339 http://svn.apache.org/r1824439 +1: ylavic, rpluem, minfrin git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1824472 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 8 -------- include/ap_mmn.h | 5 ++++- include/ap_regex.h | 22 +++++++++++++++++++++ server/core.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ server/util_pcre.c | 35 ++++++++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index fd523d0743..edcf422001 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,9 @@ Changes with Apache 2.4.30 longer fatal errors; it is logged and the truncated values are stored. [Jim Jagielski] + *) regex: Allow to configure global/default options for regexes, like + caseless matching or extended format. [Yann Ylavic] + *) mod_proxy: Allow setting options to globally defined balancer from ProxyPass used in VirtualHost. Balancers are now merged using the new merge_balancers method which merges the balancers options. [Jan Kaluza] diff --git a/STATUS b/STATUS index ce095a4761..2e76b9bf0e 100644 --- a/STATUS +++ b/STATUS @@ -118,14 +118,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) regex: Allow to configure global/default options for regexes, like - caseless matching or extended format. - trunk patch: http://svn.apache.org/r1824339 - http://svn.apache.org/r1824439 - 2.4.x patch: http://home.apache.org/~ylavic/patches/httpd-2.4.x-global_regex_options-v2.patch - +1: ylavic, rpluem, minfrin - minfrin: with mmn bump - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 70b9c621bc..af3a8a5590 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -507,6 +507,9 @@ * semantics * 20120211.73 (2.4.30-dev) Add failontimeout_set, growth_set and lbmethod_set * to proxy_balancer struct + * 20120211.74 (2.4.30-dev) Add AP_REG_DOLLAR_ENDONLY, ap_regcomp_get_default_cflags + * ap_regcomp_set_default_cflags and + * ap_regcomp_default_cflag_by_name */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -514,7 +517,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120211 #endif -#define MODULE_MAGIC_NUMBER_MINOR 73 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 74 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/ap_regex.h b/include/ap_regex.h index be41226bee..ec6908cdc9 100644 --- a/include/ap_regex.h +++ b/include/ap_regex.h @@ -77,6 +77,8 @@ extern "C" { #define AP_REG_NOMEM 0x20 /* nomem in our code */ #define AP_REG_DOTALL 0x40 /* perl's /s flag */ +#define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */ + #define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */ /* Error values: */ @@ -102,6 +104,26 @@ typedef struct { /* The functions */ +/** + * Get default compile flags + * @return Bitwise OR of AP_REG_* flags + */ +AP_DECLARE(int) ap_regcomp_get_default_cflags(void); + +/** + * Set default compile flags + * @param cflags Bitwise OR of AP_REG_* flags + */ +AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags); + +/** + * Get the AP_REG_* corresponding to the string. + * @param name The name (i.e. AP_REG_) + * @return The AP_REG_*, or zero if the string is unknown + * + */ +AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name); + /** * Compile a regular expression. * @param preg Returned compiled regex diff --git a/server/core.c b/server/core.c index b52e9b258a..4af08166f6 100644 --- a/server/core.c +++ b/server/core.c @@ -48,6 +48,7 @@ #include "mod_core.h" #include "mod_proxy.h" #include "ap_listen.h" +#include "ap_regex.h" #include "mod_so.h" /* for ap_find_loaded_module_symbol */ @@ -2847,6 +2848,58 @@ static const char *virtualhost_section(cmd_parms *cmd, void *dummy, return errmsg; } +static const char *set_regex_default_options(cmd_parms *cmd, + void *dummy, + const char *arg) +{ + const command_rec *thiscmd = cmd->cmd; + int cflags, cflag; + + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + cflags = ap_regcomp_get_default_cflags(); + while (*arg) { + const char *name = ap_getword_conf(cmd->pool, &arg); + int how = 0; + + if (strcasecmp(name, "none") == 0) { + cflags = 0; + continue; + } + + if (*name == '+') { + name++; + how = +1; + } + else if (*name == '-') { + name++; + how = -1; + } + + cflag = ap_regcomp_default_cflag_by_name(name); + if (!cflag) { + return apr_psprintf(cmd->pool, "%s: option '%s' unknown", + thiscmd->name, name); + } + + if (how > 0) { + cflags |= cflag; + } + else if (how < 0) { + cflags &= ~cflag; + } + else { + cflags = cflag; + } + } + ap_regcomp_set_default_cflags(cflags); + + return NULL; +} + static const char *set_server_alias(cmd_parms *cmd, void *dummy, const char *arg) { @@ -4421,6 +4474,9 @@ AP_INIT_TAKE12("RLimitNPROC", no_set_limit, NULL, OR_ALL, "soft/hard limits for max number of processes per uid"), #endif +AP_INIT_RAW_ARGS("RegexDefaultOptions", set_regex_default_options, NULL, RSRC_CONF, + "default options for regexes (prefixed by '+' to add, '-' to del)"), + /* internal recursion stopper */ AP_INIT_TAKE12("LimitInternalRecursion", set_recursion_limit, NULL, RSRC_CONF, "maximum recursion depth of internal redirects and subrequests"), @@ -4856,6 +4912,8 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem apr_pool_cleanup_register(pconf, NULL, reset_config_defines, apr_pool_cleanup_null); + ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY); + mpm_common_pre_config(pconf); return OK; diff --git a/server/util_pcre.c b/server/util_pcre.c index 4d2adef25b..4e707a8b28 100644 --- a/server/util_pcre.c +++ b/server/util_pcre.c @@ -111,6 +111,38 @@ AP_DECLARE(void) ap_regfree(ap_regex_t *preg) * Compile a regular expression * *************************************************/ +static int default_cflags = AP_REG_DOLLAR_ENDONLY; + +AP_DECLARE(int) ap_regcomp_get_default_cflags(void) +{ + return default_cflags; +} + +AP_DECLARE(void) ap_regcomp_set_default_cflags(int cflags) +{ + default_cflags = cflags; +} + +AP_DECLARE(int) ap_regcomp_default_cflag_by_name(const char *name) +{ + int cflag = 0; + + if (ap_cstr_casecmp(name, "ICASE") == 0) { + cflag = AP_REG_ICASE; + } + else if (ap_cstr_casecmp(name, "DOTALL") == 0) { + cflag = AP_REG_DOTALL; + } + else if (ap_cstr_casecmp(name, "DOLLAR_ENDONLY") == 0) { + cflag = AP_REG_DOLLAR_ENDONLY; + } + else if (ap_cstr_casecmp(name, "EXTENDED") == 0) { + cflag = AP_REG_EXTENDED; + } + + return cflag; +} + /* * Arguments: * preg points to a structure for recording the compiled expression @@ -127,12 +159,15 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags) int errcode = 0; int options = PCRE_DUPNAMES; + cflags |= default_cflags; if ((cflags & AP_REG_ICASE) != 0) options |= PCRE_CASELESS; if ((cflags & AP_REG_NEWLINE) != 0) options |= PCRE_MULTILINE; if ((cflags & AP_REG_DOTALL) != 0) options |= PCRE_DOTALL; + if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0) + options |= PCRE_DOLLAR_ENDONLY; preg->re_pcre = pcre_compile2(pattern, options, &errcode, &errorptr, &erroffset, NULL); -- cgit v1.2.1