1
0
mirror of https://github.com/apache/httpd.git synced 2025-07-30 20:03:10 +03:00

regex: Allow to configure global/default options for regexes.

Like caseless matching or extended format, which may be useful as default
behaviour the whole configuration.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1824339 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yann Ylavic
2018-02-15 17:53:24 +00:00
parent 4603595e1c
commit 2c21956d95
4 changed files with 118 additions and 0 deletions

View File

@ -1,6 +1,9 @@
-*- coding: utf-8 -*-
Changes with Apache 2.5.1
*) regex: Allow to configure global/default options for regexes, like
caseless matching or extended format. [Yann Ylavic]
*) mod_authnz_ldap: Fix language long names detection as short name.
[Yann Ylavic]

View File

@ -80,6 +80,8 @@ extern "C" {
#define AP_REG_NOTEMPTY 0x080 /**< Empty match not valid */
#define AP_REG_ANCHORED 0x100 /**< Match at the first position */
#define AP_REG_DOLLAR_ENDONLY 0x200 /**< '$' matches at end of subject string only */
#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */
/* Arguments for ap_pcre_version_string */
@ -120,6 +122,26 @@ typedef struct {
*/
AP_DECLARE(const char *) ap_pcre_version_string(int which);
/**
* 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

View File

@ -49,6 +49,7 @@
#include "mod_proxy.h"
#include "ap_listen.h"
#include "ap_provider.h"
#include "ap_regex.h"
#include "mod_so.h" /* for ap_find_loaded_module_symbol */
@ -2909,6 +2910,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)
{
@ -4645,6 +4698,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"),
@ -5089,6 +5145,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;

View File

@ -148,6 +148,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 (strcasecmp(name, "ICASE") == 0) {
cflag = AP_REG_ICASE;
}
else if (strcasecmp(name, "DOTALL") == 0) {
cflag = AP_REG_DOTALL;
}
else if (strcasecmp(name, "DOLLAR_ENDONLY") == 0) {
cflag = AP_REG_DOLLAR_ENDONLY;
}
else if (strcasecmp(name, "EXTENDED") == 0) {
cflag = AP_REG_EXTENDED;
}
return cflag;
}
/*
* Arguments:
* preg points to a structure for recording the compiled expression
@ -169,12 +201,15 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
int errcode = 0;
int options = PCREn(DUPNAMES);
cflags |= default_cflags;
if ((cflags & AP_REG_ICASE) != 0)
options |= PCREn(CASELESS);
if ((cflags & AP_REG_NEWLINE) != 0)
options |= PCREn(MULTILINE);
if ((cflags & AP_REG_DOTALL) != 0)
options |= PCREn(DOTALL);
if ((cflags & AP_REG_DOLLAR_ENDONLY) != 0)
options |= PCREn(DOLLAR_ENDONLY);
#ifdef HAVE_PCRE2
preg->re_pcre = pcre2_compile((const unsigned char *)pattern,