mirror of
https://github.com/apache/httpd.git
synced 2025-07-29 09:01:18 +03:00
core: Support named groups and backreferences within the LocationMatch,
DirectoryMatch, FilesMatch and ProxyMatch directives. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1554300 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
3
CHANGES
3
CHANGES
@ -1,6 +1,9 @@
|
|||||||
-*- coding: utf-8 -*-
|
-*- coding: utf-8 -*-
|
||||||
Changes with Apache 2.5.0
|
Changes with Apache 2.5.0
|
||||||
|
|
||||||
|
*) core: Support named groups and backreferences within the LocationMatch,
|
||||||
|
DirectoryMatch, FilesMatch and ProxyMatch directives. [Graham Leggett]
|
||||||
|
|
||||||
*) mod_authz_user: Support the expression parser within the require
|
*) mod_authz_user: Support the expression parser within the require
|
||||||
directives. [Graham Leggett]
|
directives. [Graham Leggett]
|
||||||
|
|
||||||
|
@ -443,6 +443,7 @@
|
|||||||
* 20130924.1 (2.5.0-dev) Add ap_proxy_connection_reusable()
|
* 20130924.1 (2.5.0-dev) Add ap_proxy_connection_reusable()
|
||||||
* 20131112.0 (2.5.0-dev) Add parse_errorlog_arg to ap_errorlog_provider
|
* 20131112.0 (2.5.0-dev) Add parse_errorlog_arg to ap_errorlog_provider
|
||||||
* 20131112.1 (2.5.0-dev) Add suspend_connection and resume_connection hooks
|
* 20131112.1 (2.5.0-dev) Add suspend_connection and resume_connection hooks
|
||||||
|
* 20131112.2 (2.5.0-dev) Add ap_regname
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
|
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
|
||||||
@ -450,7 +451,7 @@
|
|||||||
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
#ifndef MODULE_MAGIC_NUMBER_MAJOR
|
||||||
#define MODULE_MAGIC_NUMBER_MAJOR 20131112
|
#define MODULE_MAGIC_NUMBER_MAJOR 20131112
|
||||||
#endif
|
#endif
|
||||||
#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */
|
#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
|
||||||
|
@ -149,6 +149,15 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
|
|||||||
AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
|
AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg,
|
||||||
char *errbuf, apr_size_t errbuf_size);
|
char *errbuf, apr_size_t errbuf_size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of named regex backreferences
|
||||||
|
* @param preg The precompiled regex
|
||||||
|
* @param names The array to which the names will be added
|
||||||
|
* @param upper If non zero, uppercase the names
|
||||||
|
*/
|
||||||
|
AP_DECLARE(int) ap_regname(const ap_regex_t *preg,
|
||||||
|
apr_array_header_t *names, int upper);
|
||||||
|
|
||||||
/** Destroy a pre-compiled regex.
|
/** Destroy a pre-compiled regex.
|
||||||
* @param preg The pre-compiled regex to free.
|
* @param preg The pre-compiled regex to free.
|
||||||
*/
|
*/
|
||||||
|
@ -619,6 +619,10 @@ typedef struct {
|
|||||||
|
|
||||||
unsigned int allow_encoded_slashes_set : 1;
|
unsigned int allow_encoded_slashes_set : 1;
|
||||||
unsigned int decode_encoded_slashes_set : 1;
|
unsigned int decode_encoded_slashes_set : 1;
|
||||||
|
|
||||||
|
/** Named back references */
|
||||||
|
apr_array_header_t *refs;
|
||||||
|
|
||||||
} core_dir_config;
|
} core_dir_config;
|
||||||
|
|
||||||
/* macro to implement off by default behaviour */
|
/* macro to implement off by default behaviour */
|
||||||
|
@ -744,22 +744,52 @@ static int proxy_walk(request_rec *r)
|
|||||||
*/
|
*/
|
||||||
const char *proxyname = r->filename + 6;
|
const char *proxyname = r->filename + 6;
|
||||||
int j;
|
int j;
|
||||||
|
apr_pool_t *rxpool = NULL;
|
||||||
|
|
||||||
for (j = 0; j < num_sec; ++j)
|
for (j = 0; j < num_sec; ++j)
|
||||||
{
|
{
|
||||||
entry_config = sec_proxy[j];
|
entry_config = sec_proxy[j];
|
||||||
entry_proxy = ap_get_module_config(entry_config, &proxy_module);
|
entry_proxy = ap_get_module_config(entry_config, &proxy_module);
|
||||||
|
|
||||||
/* XXX: What about case insensitive matching ???
|
int nmatch = 0;
|
||||||
* Compare regex, fnmatch or string as appropriate
|
int i;
|
||||||
* If the entry doesn't relate, then continue
|
ap_regmatch_t *pmatch = NULL;
|
||||||
*/
|
|
||||||
if (entry_proxy->r
|
if (entry_proxy->r) {
|
||||||
? ap_regexec(entry_proxy->r, proxyname, 0, NULL, 0)
|
|
||||||
: (entry_proxy->p_is_fnmatch
|
if (entry_proxy->refs && entry_proxy->refs->nelts) {
|
||||||
? apr_fnmatch(entry_proxy->p, proxyname, 0)
|
if (!rxpool) {
|
||||||
: strncmp(proxyname, entry_proxy->p,
|
apr_pool_create(&rxpool, r->pool);
|
||||||
strlen(entry_proxy->p)))) {
|
}
|
||||||
|
nmatch = entry_proxy->refs->nelts;
|
||||||
|
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_regexec(entry_proxy->r, proxyname, nmatch, pmatch, 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nmatch; i++) {
|
||||||
|
if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
|
||||||
|
((const char **)entry_proxy->refs->elts)[i]) {
|
||||||
|
apr_table_setn(r->subprocess_env,
|
||||||
|
((const char **)entry_proxy->refs->elts)[i],
|
||||||
|
apr_pstrndup(r->pool,
|
||||||
|
proxyname + pmatch[i].rm_so,
|
||||||
|
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (
|
||||||
|
/* XXX: What about case insensitive matching ???
|
||||||
|
* Compare regex, fnmatch or string as appropriate
|
||||||
|
* If the entry doesn't relate, then continue
|
||||||
|
*/
|
||||||
|
entry_proxy->p_is_fnmatch ? apr_fnmatch(entry_proxy->p,
|
||||||
|
proxyname, 0) :
|
||||||
|
strncmp(proxyname, entry_proxy->p,
|
||||||
|
strlen(entry_proxy->p))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults,
|
per_dir_defaults = ap_merge_per_dir_configs(r->pool, per_dir_defaults,
|
||||||
@ -768,6 +798,10 @@ static int proxy_walk(request_rec *r)
|
|||||||
|
|
||||||
r->per_dir_config = per_dir_defaults;
|
r->per_dir_config = per_dir_defaults;
|
||||||
|
|
||||||
|
if (rxpool) {
|
||||||
|
apr_pool_destroy(rxpool);
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1314,6 +1348,7 @@ static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
|
|||||||
new->p = add->p;
|
new->p = add->p;
|
||||||
new->p_is_fnmatch = add->p_is_fnmatch;
|
new->p_is_fnmatch = add->p_is_fnmatch;
|
||||||
new->r = add->r;
|
new->r = add->r;
|
||||||
|
new->refs = add->refs;
|
||||||
|
|
||||||
/* Put these in the dir config so they work inside <Location> */
|
/* Put these in the dir config so they work inside <Location> */
|
||||||
new->raliases = apr_array_append(p, base->raliases, add->raliases);
|
new->raliases = apr_array_append(p, base->raliases, add->raliases);
|
||||||
@ -2238,6 +2273,11 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg)
|
|||||||
conf->p = cmd->path;
|
conf->p = cmd->path;
|
||||||
conf->p_is_fnmatch = apr_fnmatch_test(conf->p);
|
conf->p_is_fnmatch = apr_fnmatch_test(conf->p);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
|
||||||
|
ap_regname(r, conf->refs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
ap_add_per_proxy_conf(cmd->server, new_dir_conf);
|
ap_add_per_proxy_conf(cmd->server, new_dir_conf);
|
||||||
|
|
||||||
if (*arg != '\0') {
|
if (*arg != '\0') {
|
||||||
|
@ -219,6 +219,10 @@ typedef struct {
|
|||||||
unsigned int error_override_set:1;
|
unsigned int error_override_set:1;
|
||||||
unsigned int alias_set:1;
|
unsigned int alias_set:1;
|
||||||
unsigned int add_forwarded_headers:1;
|
unsigned int add_forwarded_headers:1;
|
||||||
|
|
||||||
|
/** Named back references */
|
||||||
|
apr_array_header_t *refs;
|
||||||
|
|
||||||
} proxy_dir_conf;
|
} proxy_dir_conf;
|
||||||
|
|
||||||
/* if we interpolate env vars per-request, we'll need a per-request
|
/* if we interpolate env vars per-request, we'll need a per-request
|
||||||
|
@ -215,6 +215,7 @@ static void *merge_core_dir_configs(apr_pool_t *a, void *basev, void *newv)
|
|||||||
conf->d_is_fnmatch = new->d_is_fnmatch;
|
conf->d_is_fnmatch = new->d_is_fnmatch;
|
||||||
conf->d_components = new->d_components;
|
conf->d_components = new->d_components;
|
||||||
conf->r = new->r;
|
conf->r = new->r;
|
||||||
|
conf->refs = new->refs;
|
||||||
conf->condition = new->condition;
|
conf->condition = new->condition;
|
||||||
|
|
||||||
if (new->opts & OPT_UNSET) {
|
if (new->opts & OPT_UNSET) {
|
||||||
@ -2214,6 +2215,11 @@ static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg)
|
|||||||
conf->d = cmd->path;
|
conf->d = cmd->path;
|
||||||
conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0);
|
conf->d_is_fnmatch = (apr_fnmatch_test(conf->d) != 0);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
|
||||||
|
ap_regname(r, conf->refs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make this explicit - the "/" root has 0 elements, that is, we
|
/* Make this explicit - the "/" root has 0 elements, that is, we
|
||||||
* will always merge it, and it will always sort and merge first.
|
* will always merge it, and it will always sort and merge first.
|
||||||
* All others are sorted and tested by the number of slashes.
|
* All others are sorted and tested by the number of slashes.
|
||||||
@ -2290,6 +2296,11 @@ static const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg)
|
|||||||
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
|
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
|
||||||
conf->r = r;
|
conf->r = r;
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
|
||||||
|
ap_regname(r, conf->refs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
ap_add_per_url_conf(cmd->server, new_url_conf);
|
ap_add_per_url_conf(cmd->server, new_url_conf);
|
||||||
|
|
||||||
if (*arg != '\0') {
|
if (*arg != '\0') {
|
||||||
@ -2372,6 +2383,11 @@ static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg)
|
|||||||
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
|
conf->d_is_fnmatch = apr_fnmatch_test(conf->d) != 0;
|
||||||
conf->r = r;
|
conf->r = r;
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *));
|
||||||
|
ap_regname(r, conf->refs, 1);
|
||||||
|
}
|
||||||
|
|
||||||
ap_add_file_conf(cmd->pool, (core_dir_config *)mconfig, new_file_conf);
|
ap_add_file_conf(cmd->pool, (core_dir_config *)mconfig, new_file_conf);
|
||||||
|
|
||||||
if (*arg != '\0') {
|
if (*arg != '\0') {
|
||||||
|
122
server/request.c
122
server/request.c
@ -741,6 +741,7 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
|
|||||||
apr_size_t buflen;
|
apr_size_t buflen;
|
||||||
char *buf;
|
char *buf;
|
||||||
unsigned int seg, startseg;
|
unsigned int seg, startseg;
|
||||||
|
apr_pool_t *rxpool = NULL;
|
||||||
|
|
||||||
/* Invariant: from the first time filename_len is set until
|
/* Invariant: from the first time filename_len is set until
|
||||||
* it goes out of scope, filename_len==strlen(r->filename)
|
* it goes out of scope, filename_len==strlen(r->filename)
|
||||||
@ -1196,6 +1197,10 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
|
|||||||
*/
|
*/
|
||||||
for (; sec_idx < num_sec; ++sec_idx) {
|
for (; sec_idx < num_sec; ++sec_idx) {
|
||||||
|
|
||||||
|
int nmatch = 0;
|
||||||
|
int i;
|
||||||
|
ap_regmatch_t *pmatch = NULL;
|
||||||
|
|
||||||
core_dir_config *entry_core;
|
core_dir_config *entry_core;
|
||||||
entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
|
entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
|
||||||
|
|
||||||
@ -1203,10 +1208,29 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ap_regexec(entry_core->r, r->filename, 0, NULL, 0)) {
|
if (entry_core->refs && entry_core->refs->nelts) {
|
||||||
|
if (!rxpool) {
|
||||||
|
apr_pool_create(&rxpool, r->pool);
|
||||||
|
}
|
||||||
|
nmatch = entry_core->refs->nelts;
|
||||||
|
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_regexec(entry_core->r, r->filename, nmatch, pmatch, 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nmatch; i++) {
|
||||||
|
if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
|
||||||
|
((const char **)entry_core->refs->elts)[i]) {
|
||||||
|
apr_table_setn(r->subprocess_env,
|
||||||
|
((const char **)entry_core->refs->elts)[i],
|
||||||
|
apr_pstrndup(r->pool,
|
||||||
|
r->filename + pmatch[i].rm_so,
|
||||||
|
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If we haven't already continue'd above, we have a match.
|
/* If we haven't already continue'd above, we have a match.
|
||||||
*
|
*
|
||||||
* Calculate our full-context core opts & override.
|
* Calculate our full-context core opts & override.
|
||||||
@ -1245,6 +1269,10 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r)
|
|||||||
last_walk->merged = now_merged;
|
last_walk->merged = now_merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rxpool) {
|
||||||
|
apr_pool_destroy(rxpool);
|
||||||
|
}
|
||||||
|
|
||||||
/* Whoops - everything matched in sequence, but either the original
|
/* Whoops - everything matched in sequence, but either the original
|
||||||
* walk found some additional matches (which we need to truncate), or
|
* walk found some additional matches (which we need to truncate), or
|
||||||
* this walk found some additional matches.
|
* this walk found some additional matches.
|
||||||
@ -1382,6 +1410,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
|||||||
int matches = cache->walked->nelts;
|
int matches = cache->walked->nelts;
|
||||||
int cached_matches = matches;
|
int cached_matches = matches;
|
||||||
walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
|
walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
|
||||||
|
apr_pool_t *rxpool = NULL;
|
||||||
|
|
||||||
cached &= auth_internal_per_conf;
|
cached &= auth_internal_per_conf;
|
||||||
cache->cached = entry_uri;
|
cache->cached = entry_uri;
|
||||||
@ -1403,16 +1432,48 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
|||||||
* not slash terminated, then this uri must be slash
|
* not slash terminated, then this uri must be slash
|
||||||
* terminated (or at the end of the string) to match.
|
* terminated (or at the end of the string) to match.
|
||||||
*/
|
*/
|
||||||
if (entry_core->r
|
if (entry_core->r) {
|
||||||
? ap_regexec(entry_core->r, r->uri, 0, NULL, 0)
|
|
||||||
: (entry_core->d_is_fnmatch
|
int nmatch = 0;
|
||||||
|
int i;
|
||||||
|
ap_regmatch_t *pmatch = NULL;
|
||||||
|
|
||||||
|
if (entry_core->refs && entry_core->refs->nelts) {
|
||||||
|
if (!rxpool) {
|
||||||
|
apr_pool_create(&rxpool, r->pool);
|
||||||
|
}
|
||||||
|
nmatch = entry_core->refs->nelts;
|
||||||
|
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nmatch; i++) {
|
||||||
|
if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
|
||||||
|
((const char **)entry_core->refs->elts)[i]) {
|
||||||
|
apr_table_setn(r->subprocess_env,
|
||||||
|
((const char **)entry_core->refs->elts)[i],
|
||||||
|
apr_pstrndup(r->pool,
|
||||||
|
r->uri + pmatch[i].rm_so,
|
||||||
|
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if ((entry_core->d_is_fnmatch
|
||||||
? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
|
? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
|
||||||
: (strncmp(entry_core->d, cache->cached, len)
|
: (strncmp(entry_core->d, cache->cached, len)
|
||||||
|| (len > 0
|
|| (len > 0
|
||||||
&& entry_core->d[len - 1] != '/'
|
&& entry_core->d[len - 1] != '/'
|
||||||
&& cache->cached[len] != '/'
|
&& cache->cached[len] != '/'
|
||||||
&& cache->cached[len] != '\0')))) {
|
&& cache->cached[len] != '\0')))) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we merged this same section last time, reuse it
|
/* If we merged this same section last time, reuse it
|
||||||
@ -1447,6 +1508,10 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
|||||||
last_walk->merged = now_merged;
|
last_walk->merged = now_merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rxpool) {
|
||||||
|
apr_pool_destroy(rxpool);
|
||||||
|
}
|
||||||
|
|
||||||
/* Whoops - everything matched in sequence, but either the original
|
/* Whoops - everything matched in sequence, but either the original
|
||||||
* walk found some additional matches (which we need to truncate), or
|
* walk found some additional matches (which we need to truncate), or
|
||||||
* this walk found some additional matches.
|
* this walk found some additional matches.
|
||||||
@ -1556,6 +1621,7 @@ AP_DECLARE(int) ap_file_walk(request_rec *r)
|
|||||||
int matches = cache->walked->nelts;
|
int matches = cache->walked->nelts;
|
||||||
int cached_matches = matches;
|
int cached_matches = matches;
|
||||||
walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
|
walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
|
||||||
|
apr_pool_t *rxpool = NULL;
|
||||||
|
|
||||||
cached &= auth_internal_per_conf;
|
cached &= auth_internal_per_conf;
|
||||||
cache->cached = test_file;
|
cache->cached = test_file;
|
||||||
@ -1568,12 +1634,42 @@ AP_DECLARE(int) ap_file_walk(request_rec *r)
|
|||||||
core_dir_config *entry_core;
|
core_dir_config *entry_core;
|
||||||
entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
|
entry_core = ap_get_core_module_config(sec_ent[sec_idx]);
|
||||||
|
|
||||||
if (entry_core->r
|
if (entry_core->r) {
|
||||||
? ap_regexec(entry_core->r, cache->cached , 0, NULL, 0)
|
|
||||||
: (entry_core->d_is_fnmatch
|
int nmatch = 0;
|
||||||
? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
|
int i;
|
||||||
: strcmp(entry_core->d, cache->cached))) {
|
ap_regmatch_t *pmatch = NULL;
|
||||||
continue;
|
|
||||||
|
if (entry_core->refs && entry_core->refs->nelts) {
|
||||||
|
if (!rxpool) {
|
||||||
|
apr_pool_create(&rxpool, r->pool);
|
||||||
|
}
|
||||||
|
nmatch = entry_core->refs->nelts;
|
||||||
|
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ap_regexec(entry_core->r, cache->cached, nmatch, pmatch, 0)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nmatch; i++) {
|
||||||
|
if (pmatch[i].rm_so >= 0 && pmatch[i].rm_eo >= 0 &&
|
||||||
|
((const char **)entry_core->refs->elts)[i]) {
|
||||||
|
apr_table_setn(r->subprocess_env,
|
||||||
|
((const char **)entry_core->refs->elts)[i],
|
||||||
|
apr_pstrndup(r->pool,
|
||||||
|
cache->cached + pmatch[i].rm_so,
|
||||||
|
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((entry_core->d_is_fnmatch
|
||||||
|
? apr_fnmatch(entry_core->d, cache->cached, APR_FNM_PATHNAME)
|
||||||
|
: strcmp(entry_core->d, cache->cached))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we merged this same section last time, reuse it
|
/* If we merged this same section last time, reuse it
|
||||||
@ -1608,6 +1704,10 @@ AP_DECLARE(int) ap_file_walk(request_rec *r)
|
|||||||
last_walk->merged = now_merged;
|
last_walk->merged = now_merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rxpool) {
|
||||||
|
apr_pool_destroy(rxpool);
|
||||||
|
}
|
||||||
|
|
||||||
/* Whoops - everything matched in sequence, but either the original
|
/* Whoops - everything matched in sequence, but either the original
|
||||||
* walk found some additional matches (which we need to truncate), or
|
* walk found some additional matches (which we need to truncate), or
|
||||||
* this walk found some additional matches.
|
* this walk found some additional matches.
|
||||||
|
@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
#include "apr_strings.h"
|
#include "apr_strings.h"
|
||||||
|
#include "apr_tables.h"
|
||||||
#include "pcre.h"
|
#include "pcre.h"
|
||||||
|
|
||||||
#define APR_WANT_STRFUNC
|
#define APR_WANT_STRFUNC
|
||||||
@ -124,7 +125,7 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
|
|||||||
const char *errorptr;
|
const char *errorptr;
|
||||||
int erroffset;
|
int erroffset;
|
||||||
int errcode = 0;
|
int errcode = 0;
|
||||||
int options = 0;
|
int options = PCRE_DUPNAMES;
|
||||||
|
|
||||||
if ((cflags & AP_REG_ICASE) != 0)
|
if ((cflags & AP_REG_ICASE) != 0)
|
||||||
options |= PCRE_CASELESS;
|
options |= PCRE_CASELESS;
|
||||||
@ -256,4 +257,38 @@ AP_DECLARE(int) ap_regexec_len(const ap_regex_t *preg, const char *buff,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AP_DECLARE(int) ap_regname(const ap_regex_t *preg,
|
||||||
|
apr_array_header_t *names, int upper)
|
||||||
|
{
|
||||||
|
int namecount;
|
||||||
|
int nameentrysize;
|
||||||
|
int i;
|
||||||
|
char *nametable;
|
||||||
|
|
||||||
|
pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
|
||||||
|
PCRE_INFO_NAMECOUNT, &namecount);
|
||||||
|
pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
|
||||||
|
PCRE_INFO_NAMEENTRYSIZE, &nameentrysize);
|
||||||
|
pcre_fullinfo((const pcre *)preg->re_pcre, NULL,
|
||||||
|
PCRE_INFO_NAMETABLE, &nametable);
|
||||||
|
|
||||||
|
for (i = 0; i < namecount; i++) {
|
||||||
|
const char *offset = nametable + i * nameentrysize;
|
||||||
|
int capture = ((offset[0] << 8) + offset[1]);
|
||||||
|
while (names->nelts <= capture) {
|
||||||
|
apr_array_push(names);
|
||||||
|
}
|
||||||
|
if (upper) {
|
||||||
|
char *name = ((char **)names->elts)[capture] =
|
||||||
|
apr_pstrdup(names->pool, offset + 2);
|
||||||
|
ap_str_toupper(name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
((const char **)names->elts)[capture] = offset + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return namecount;
|
||||||
|
}
|
||||||
|
|
||||||
/* End of pcreposix.c */
|
/* End of pcreposix.c */
|
||||||
|
Reference in New Issue
Block a user