summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraham Leggett <minfrin@apache.org>2018-02-16 13:27:44 +0000
committerGraham Leggett <minfrin@apache.org>2018-02-16 13:27:44 +0000
commit4d766e70501cd1150aa53dd4b0b1b362f3529e84 (patch)
tree35bab00b4dd21f6b0beb41fccf9a5a8a70a73b5e
parentcf973873623b0cfa7703403ad3b3dd84112453e4 (diff)
downloadhttpd-4d766e70501cd1150aa53dd4b0b1b362f3529e84.tar.gz
*) 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
-rw-r--r--CHANGES3
-rw-r--r--STATUS8
-rw-r--r--include/ap_mmn.h5
-rw-r--r--include/ap_regex.h22
-rw-r--r--server/core.c58
-rw-r--r--server/util_pcre.c35
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: */
@@ -103,6 +105,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_<name>)
+ * @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
* @param regex The regular expression string
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);