mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-14 13:56:01 +03:00
Support for PCRE2
This commit is contained in:
parent
849cd7e848
commit
8fc0b519b7
2
CHANGES
2
CHANGES
@ -1,6 +1,8 @@
|
||||
DD mmm YYYY - 2.9.x (to be released)
|
||||
-------------------
|
||||
|
||||
* Support for PCRE2
|
||||
[Issue #2737, #2827 - @martinhsv]
|
||||
|
||||
07 Sep 2022 - 2.9.6
|
||||
-------------------
|
||||
|
@ -42,6 +42,7 @@ mod_security2_la_CFLAGS = @APR_CFLAGS@ \
|
||||
@LUA_CFLAGS@ \
|
||||
@MODSEC_EXTRA_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ \
|
||||
@PCRE2_CFLAGS@ \
|
||||
@YAJL_CFLAGS@ \
|
||||
@SSDEEP_CFLAGS@
|
||||
|
||||
@ -50,7 +51,8 @@ mod_security2_la_CPPFLAGS = @APR_CPPFLAGS@ \
|
||||
@CURL_CPPFLAGS@ \
|
||||
@LIBXML2_CFLAGS@ \
|
||||
@LIBXML2_CPPFLAGS@ \
|
||||
@PCRE_CPPFLAGS@
|
||||
@PCRE_CPPFLAGS@ \
|
||||
@PCRE2_CPPFLAGS@
|
||||
|
||||
mod_security2_la_LIBADD = @APR_LDADD@ \
|
||||
@APU_LDADD@ \
|
||||
@ -59,6 +61,7 @@ mod_security2_la_LIBADD = @APR_LDADD@ \
|
||||
@LIBXML2_LDADD@ \
|
||||
@LUA_LDADD@ \
|
||||
@PCRE_LDADD@ \
|
||||
@PCRE2_LDADD@ \
|
||||
@YAJL_LDADD@
|
||||
|
||||
if AIX
|
||||
@ -71,6 +74,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -85,6 +89,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -99,6 +104,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -113,6 +119,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -127,6 +134,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version -R @PCRE_LD_PATH
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -141,6 +149,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -155,6 +164,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
@ -169,6 +179,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PCRE2_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@ \
|
||||
@SSDEEP_LDFLAGS@
|
||||
endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -1293,7 +1293,11 @@ static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
|
||||
{
|
||||
directory_config *dcfg = _dcfg;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE2_DOTALL, NULL, NULL);
|
||||
#else
|
||||
dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE_DOTALL, NULL, NULL);
|
||||
#endif
|
||||
if (dcfg->auditlog_relevant_regex == NULL) {
|
||||
return apr_psprintf(cmd->pool, "ModSecurity: Invalid regular expression: %s", p1);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -107,6 +107,8 @@ static int server_limit, thread_limit;
|
||||
*/
|
||||
static void version(apr_pool_t *mp) {
|
||||
char *pcre_vrs = NULL;
|
||||
char *pcre_loaded_vrs = NULL;
|
||||
char pcre2_loaded_vrs_buffer[80] ={0};
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
||||
"ModSecurity: APR compiled version=\"%s\"; "
|
||||
@ -116,13 +118,20 @@ static void version(apr_pool_t *mp) {
|
||||
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, "ModSecurity: Loaded APR do not match with compiled!");
|
||||
}
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
pcre_vrs = apr_psprintf(mp,"%d.%d ", PCRE2_MAJOR, PCRE2_MINOR);
|
||||
pcre_loaded_vrs = pcre2_loaded_vrs_buffer;
|
||||
pcre2_config(PCRE2_CONFIG_VERSION, pcre_loaded_vrs);
|
||||
#else
|
||||
pcre_vrs = apr_psprintf(mp,"%d.%d ", PCRE_MAJOR, PCRE_MINOR);
|
||||
pcre_loaded_vrs = pcre_version();
|
||||
#endif
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
||||
"ModSecurity: PCRE compiled version=\"%s\"; "
|
||||
"loaded version=\"%s\"", pcre_vrs, pcre_version());
|
||||
"loaded version=\"%s\"", pcre_vrs, pcre_loaded_vrs);
|
||||
|
||||
if (strstr(pcre_version(),pcre_vrs) == NULL) {
|
||||
if (strstr(pcre_loaded_vrs,pcre_vrs) == NULL) {
|
||||
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, "ModSecurity: Loaded PCRE do not match with compiled!");
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -561,7 +561,11 @@ static int is_response_status_relevant(modsec_rec *msr, int status) {
|
||||
|
||||
rc = msc_regexec(msr->txcfg->auditlog_relevant_regex, buf, strlen(buf), &my_error_msg);
|
||||
if (rc >= 0) return 1;
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc == PCRE2_ERROR_NOMATCH) return 0;
|
||||
#else
|
||||
if (rc == PCRE_ERROR_NOMATCH) return 0;
|
||||
#endif
|
||||
|
||||
msr_log(msr, 1, "Regex processing failed (rc %d): %s", rc, my_error_msg);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -386,7 +386,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
case HASH_URL_HREF_HASH_RX:
|
||||
if(em[i]->type == HASH_URL_HREF_HASH_RX) {
|
||||
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -415,7 +419,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
msr_log(msr, 4, "%s.", error_msg);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -441,7 +449,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
case HASH_URL_FACTION_HASH_RX:
|
||||
if(em[i]->type == HASH_URL_FACTION_HASH_RX) {
|
||||
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -470,7 +482,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
msr_log(msr, 4, "%s.", error_msg);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -496,7 +512,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
case HASH_URL_LOCATION_HASH_RX:
|
||||
if(em[i]->type == HASH_URL_LOCATION_HASH_RX) {
|
||||
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -525,7 +545,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
msr_log(msr, 4, "%s.", error_msg);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -551,7 +575,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
case HASH_URL_IFRAMESRC_HASH_RX:
|
||||
if(em[i]->type == HASH_URL_IFRAMESRC_HASH_RX) {
|
||||
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -580,7 +608,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
msr_log(msr, 4, "%s.", error_msg);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -606,7 +638,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
case HASH_URL_FRAMESRC_HASH_RX:
|
||||
if(em[i]->type == HASH_URL_FRAMESRC_HASH_RX) {
|
||||
rc = msc_regexec_capture(em[i]->param_data, link, strlen(link), ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -635,7 +671,11 @@ int do_hash_method(modsec_rec *msr, char *link, int type) {
|
||||
msr_log(msr, 4, "%s.", error_msg);
|
||||
return -1;
|
||||
}
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -20,6 +20,16 @@
|
||||
*/
|
||||
static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
||||
if (regex != NULL) {
|
||||
#ifdef WITH_PCRE2
|
||||
if (regex->match_context != NULL) {
|
||||
pcre2_match_context_free(regex->match_context);
|
||||
regex->match_context = NULL;
|
||||
}
|
||||
if (regex->re != NULL) {
|
||||
pcre2_code_free(regex->re);
|
||||
regex->re = NULL;
|
||||
}
|
||||
#else
|
||||
if (regex->pe != NULL) {
|
||||
#if defined(VERSION_NGINX)
|
||||
pcre_free(regex->pe);
|
||||
@ -32,6 +42,7 @@ static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
||||
pcre_free(regex->re);
|
||||
regex->re = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
@ -48,6 +59,78 @@ static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
|
||||
void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||
const char **_errptr, int *_erroffset,
|
||||
int match_limit, int match_limit_recursion)
|
||||
#ifdef WITH_PCRE2
|
||||
{
|
||||
msc_regex_t *regex = NULL;
|
||||
PCRE2_SPTR pcre2_pattern;
|
||||
uint32_t pcre2_options;
|
||||
int error_number = 0;
|
||||
PCRE2_SIZE error_offset = 0;
|
||||
pcre2_match_context *match_context = NULL;
|
||||
|
||||
regex = apr_pcalloc(pool, sizeof(msc_regex_t));
|
||||
if (regex == NULL) return NULL;
|
||||
regex->pattern = pattern;
|
||||
|
||||
pcre2_pattern = (PCRE2_SPTR)pattern;
|
||||
pcre2_options = (uint32_t)options;
|
||||
|
||||
regex->re = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED,
|
||||
pcre2_options, &error_number, &error_offset, NULL);
|
||||
if (regex->re == NULL) {
|
||||
if (_erroffset != NULL) {
|
||||
*_erroffset = (int)error_offset;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: Add PCRE2 JIT support */
|
||||
|
||||
/* Setup the pcre2 match context */
|
||||
regex->match_context = NULL;
|
||||
match_context = pcre2_match_context_create(NULL);
|
||||
if (match_context == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Prefer the match limit passed as an arg; else use compilation default */
|
||||
{
|
||||
uint32_t final_match_limit = 0;
|
||||
if (match_limit > 0) {
|
||||
final_match_limit = match_limit;
|
||||
pcre2_set_match_limit(match_context, final_match_limit);
|
||||
}
|
||||
#ifdef MODSEC_PCRE_MATCH_LIMIT
|
||||
else {
|
||||
final_match_limit = MODSEC_PCRE_MATCH_LIMIT;
|
||||
pcre2_set_match_limit(match_context, final_match_limit);
|
||||
}
|
||||
#endif /* MODSEC_PCRE_MATCH_LIMIT */
|
||||
}
|
||||
|
||||
/* Prefer the depth limit passed as an arg; else use compilation default */
|
||||
{
|
||||
uint32_t final_match_limit_recursion = 0;
|
||||
if (match_limit_recursion > 0) {
|
||||
final_match_limit_recursion = match_limit_recursion;
|
||||
pcre2_set_depth_limit(match_context, final_match_limit_recursion);
|
||||
}
|
||||
#ifdef MODSEC_PCRE_MATCH_LIMIT_RECURSION
|
||||
else {
|
||||
final_match_limit_recursion = MODSEC_PCRE_MATCH_LIMIT_RECURSION;
|
||||
pcre2_set_depth_limit(match_context, final_match_limit_recursion);
|
||||
}
|
||||
#endif /* MODSEC_PCRE_MATCH_LIMIT_RECURSION */
|
||||
}
|
||||
|
||||
regex->match_context = match_context;
|
||||
|
||||
apr_pool_cleanup_register(pool, (void *)regex,
|
||||
(apr_status_t (*)(void *))msc_pcre_cleanup, apr_pool_cleanup_null);
|
||||
|
||||
return regex;
|
||||
}
|
||||
#else /* not WITH_PCRE2 */
|
||||
{
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
@ -131,6 +214,7 @@ void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
|
||||
|
||||
return regex;
|
||||
}
|
||||
#endif /* WITH_PCRE2 */
|
||||
|
||||
/**
|
||||
* Compiles the provided regular expression pattern. Calls msc_pregcomp_ex()
|
||||
@ -143,9 +227,9 @@ void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes regular expression with extended options.
|
||||
* Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1
|
||||
* on errors, and a value > 0 when there is a match.
|
||||
* Executes regular expression with extended options (or match context)
|
||||
* Returns PCRE_ERROR_NOMATCH (or PCRE2_ERROR_NOMATCH),
|
||||
* error code < -1 on errors, and a value > 0 when there is a match.
|
||||
*/
|
||||
int msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen,
|
||||
int startoffset, int options, int *ovector, int ovecsize, char **error_msg)
|
||||
@ -153,7 +237,41 @@ int msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen,
|
||||
if (error_msg == NULL) return -1000; /* To differentiate from PCRE as it already uses -1. */
|
||||
*error_msg = NULL;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
{
|
||||
PCRE2_SPTR pcre2_s;
|
||||
int pcre2_ret;
|
||||
pcre2_match_data *match_data;
|
||||
PCRE2_SIZE *pcre2_ovector = NULL;
|
||||
|
||||
pcre2_s = (PCRE2_SPTR)s;
|
||||
match_data = pcre2_match_data_create_from_pattern(regex->re, NULL);
|
||||
|
||||
pcre2_ret = pcre2_match(regex->re, pcre2_s, (PCRE2_SIZE)strlen(s),
|
||||
(PCRE2_SIZE)(startoffset), (uint32_t)options, match_data, regex->match_context);
|
||||
if (match_data != NULL) {
|
||||
if (ovector != NULL) {
|
||||
pcre2_ovector = pcre2_get_ovector_pointer(match_data);
|
||||
if (pcre2_ovector != NULL) {
|
||||
for (int i = 0; ((i < pcre2_ret) && ((i*2) <= ovecsize)); i++) {
|
||||
if ((i*2) < ovecsize) {
|
||||
ovector[2*i] = pcre2_ovector[2*i];
|
||||
ovector[2*i+1] = pcre2_ovector[2*i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pcre2_match_data_free(match_data);
|
||||
}
|
||||
if ((pcre2_ret*2) > ovecsize) {
|
||||
return 0;
|
||||
} else {
|
||||
return pcre2_ret;
|
||||
}
|
||||
}
|
||||
#else
|
||||
return pcre_exec(regex->re, regex->pe, s, slen, startoffset, options, ovector, ovecsize);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,6 +306,10 @@ int msc_regexec(msc_regex_t *regex, const char *s, unsigned int slen,
|
||||
*/
|
||||
int msc_fullinfo(msc_regex_t *regex, int what, void *where)
|
||||
{
|
||||
#ifdef WITH_PCRE2
|
||||
return pcre2_pattern_info(regex->re, (uint32_t)what, where);
|
||||
#else
|
||||
return pcre_fullinfo(regex->re, regex->pe, what, where);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -17,7 +17,14 @@
|
||||
|
||||
typedef struct msc_regex_t msc_regex_t;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
#define PCRE2_CODE_UNIT_WIDTH 8
|
||||
#include "pcre2.h"
|
||||
#else
|
||||
#include "pcre.h"
|
||||
#endif
|
||||
|
||||
#ifndef WITH_PCRE2
|
||||
|
||||
#ifndef PCRE_ERROR_MATCHLIMIT
|
||||
/* Define for compile, but not valid in this version of PCRE. */
|
||||
@ -29,12 +36,19 @@ typedef struct msc_regex_t msc_regex_t;
|
||||
#define PCRE_ERROR_RECURSIONLIMIT (-21)
|
||||
#endif /* PCRE_ERROR_RECURSIONLIMIT */
|
||||
|
||||
#endif
|
||||
|
||||
#include "apr_general.h"
|
||||
#include "modsecurity.h"
|
||||
|
||||
struct msc_regex_t {
|
||||
#ifdef WITH_PCRE2
|
||||
pcre2_code *re;
|
||||
pcre2_match_context *match_context;
|
||||
#else
|
||||
void *re;
|
||||
void *pe;
|
||||
#endif
|
||||
const char *pattern;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -345,8 +345,13 @@ int DSOLOCAL msc_beacon_string (char *beacon_string, int beacon_string_max_len)
|
||||
|
||||
apr = APR_VERSION_STRING;
|
||||
apr_loaded = apr_version_string();
|
||||
#ifdef WITH_PCRE2
|
||||
apr_snprintf(pcre, 7, "%d.%d", PCRE2_MAJOR, PCRE2_MINOR);
|
||||
pcre_loaded = ""; /* complete this if/when status reactivated */
|
||||
#else
|
||||
apr_snprintf(pcre, 7, "%d.%d", PCRE_MAJOR, PCRE_MINOR);
|
||||
pcre_loaded = pcre_version();
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
lua = LUA_VERSION;
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -697,7 +697,12 @@ static int msre_op_validateHash_param_init(msre_rule *rule, char **error_msg) {
|
||||
|
||||
/* Compile pattern */
|
||||
if(strstr(pattern,"%{") == NULL) {
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
#ifdef WITH_PCRE2
|
||||
int options = PCRE2_DOTALL | PCRE2_DOLLAR_ENDONLY;
|
||||
#else
|
||||
int options = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
|
||||
#endif
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -747,6 +752,7 @@ static int msre_op_validateHash_execute(modsec_rec *msr, msre_rule *rule, msre_v
|
||||
const char *target;
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
unsigned int target_length;
|
||||
char *my_error_msg = NULL;
|
||||
int ovector[33];
|
||||
@ -786,7 +792,12 @@ static int msre_op_validateHash_execute(modsec_rec *msr, msre_rule *rule, msre_v
|
||||
msr_log(msr, 6, "Escaping pattern [%s]",pattern);
|
||||
}
|
||||
|
||||
regex = msc_pregcomp_ex(msr->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr,
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_DOLLAR_ENDONLY;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
|
||||
#endif
|
||||
regex = msc_pregcomp_ex(msr->mp, pattern, options, &errptr,
|
||||
&erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Error compiling pattern (offset %d): %s",
|
||||
@ -831,7 +842,11 @@ static int msre_op_validateHash_execute(modsec_rec *msr, msre_rule *rule, msre_v
|
||||
* and no memory has to be allocated for any backreferences.
|
||||
*/
|
||||
rc = msc_regexec_capture(regex, target, target_length, ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -861,7 +876,11 @@ static int msre_op_validateHash_execute(modsec_rec *msr, msre_rule *rule, msre_v
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
/* We no longer escape the pattern here as it is done when logging */
|
||||
char *pattern = apr_pstrdup(msr->mp, log_escape(msr->mp, regex->pattern ? regex->pattern : "<Unknown Match>"));
|
||||
char *hmac = NULL, *valid = NULL;
|
||||
@ -940,7 +959,12 @@ static int msre_op_rx_param_init(msre_rule *rule, char **error_msg) {
|
||||
|
||||
/* Compile pattern */
|
||||
if(strstr(pattern,"%{") == NULL) {
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
#ifdef WITH_PCRE2
|
||||
int options = PCRE2_DOTALL | PCRE2_DOLLAR_ENDONLY;
|
||||
#else
|
||||
int options = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
|
||||
#endif
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, pattern, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -979,6 +1003,7 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
const char *target;
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
unsigned int target_length;
|
||||
char *my_error_msg = NULL;
|
||||
int ovector[33];
|
||||
@ -1020,7 +1045,12 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
msr_log(msr, 6, "Escaping pattern [%s]",pattern);
|
||||
}
|
||||
|
||||
regex = msc_pregcomp_ex(msr->mp, pattern, PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_DOLLAR_ENDONLY;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_DOLLAR_ENDONLY;
|
||||
#endif
|
||||
regex = msc_pregcomp_ex(msr->mp, pattern, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(msr->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -1075,7 +1105,11 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
/* Show when the regex captures but "capture" is not set */
|
||||
if (msr->txcfg->debuglog_level >= 6) {
|
||||
int capcount = 0;
|
||||
#ifdef WITH_PCRE2
|
||||
rc = msc_fullinfo(regex, PCRE2_INFO_CAPTURECOUNT, &capcount);
|
||||
#else
|
||||
rc = msc_fullinfo(regex, PCRE_INFO_CAPTURECOUNT, &capcount);
|
||||
#endif
|
||||
if (msr->txcfg->debuglog_level >= 6) {
|
||||
if ((capture == 0) && (capcount > 0)) {
|
||||
msr_log(msr, 6, "Ignoring regex captures since \"capture\" action is not enabled.");
|
||||
@ -1087,7 +1121,11 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
* and no memory has to be allocated for any backreferences.
|
||||
*/
|
||||
rc = msc_regexec_capture(regex, target, target_length, ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
if ((rc == PCRE2_ERROR_MATCHLIMIT) || (rc == PCRE2_ERROR_RECURSIONLIMIT)) {
|
||||
#else
|
||||
if ((rc == PCRE_ERROR_MATCHLIMIT) || (rc == PCRE_ERROR_RECURSIONLIMIT)) {
|
||||
#endif
|
||||
msc_string *s = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string));
|
||||
|
||||
if (s == NULL) return -1;
|
||||
@ -1178,7 +1216,11 @@ static int msre_op_rx_execute(modsec_rec *msr, msre_rule *rule, msre_var *var, c
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc != PCRE2_ERROR_NOMATCH) { /* Match. */
|
||||
#else
|
||||
if (rc != PCRE_ERROR_NOMATCH) { /* Match. */
|
||||
#endif
|
||||
/* We no longer escape the pattern here as it is done when logging */
|
||||
char *pattern = apr_pstrdup(msr->mp, log_escape(msr->mp, regex->pattern ? regex->pattern : "<Unknown Match>"));
|
||||
|
||||
@ -1623,13 +1665,19 @@ static int verify_gsb(gsb_db *gsb, modsec_rec *msr, const char *match, unsigned
|
||||
static int msre_op_gsbLookup_param_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
msc_regex_t *regex;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
/* Compile rule->op_param */
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_MULTILINE;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_MULTILINE;
|
||||
#endif
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
@ -1659,6 +1707,7 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
char *my_error_msg = NULL;
|
||||
int ovector[33];
|
||||
unsigned int offset = 0;
|
||||
int options = 0;
|
||||
gsb_db *gsb = msr->txcfg->gsb;
|
||||
const char *match = NULL;
|
||||
unsigned int match_length;
|
||||
@ -1697,7 +1746,12 @@ static int msre_op_gsbLookup_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
|
||||
memcpy(data,var->value,var->value_len);
|
||||
|
||||
while (offset < size && (rv = msc_regexec_ex(regex, data, size, offset, PCRE_NOTEMPTY, ovector, 30, &my_error_msg)) >= 0)
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_NOTEMPTY;
|
||||
#else
|
||||
options = PCRE_NOTEMPTY;
|
||||
#endif
|
||||
while (offset < size && (rv = msc_regexec_ex(regex, data, size, offset, options, ovector, 30, &my_error_msg)) >= 0)
|
||||
{
|
||||
for(i = 0; i < rv; ++i)
|
||||
{
|
||||
@ -2731,13 +2785,19 @@ static int luhn_verify(const char *ccnumber, int len) {
|
||||
static int msre_op_verifyCC_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
msc_regex_t *regex;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_MULTILINE;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_MULTILINE;
|
||||
#endif
|
||||
/* Compile rule->op_param */
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -2758,6 +2818,7 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
int rc;
|
||||
int is_cc = 0;
|
||||
int offset;
|
||||
int options = 0;
|
||||
int matched_bytes = 0;
|
||||
char *qspos = NULL;
|
||||
const char *parm = NULL;
|
||||
@ -2817,10 +2878,19 @@ static int msre_op_verifyCC_execute(modsec_rec *msr, msre_rule *rule, msre_var *
|
||||
}
|
||||
}
|
||||
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, PCRE_NOTEMPTY, ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_NOTEMPTY;
|
||||
#else
|
||||
options = PCRE_NOTEMPTY;
|
||||
#endif
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, options, ovector, 30, &my_error_msg);
|
||||
|
||||
/* If there was no match, then we are done. */
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc == PCRE2_ERROR_NOMATCH) {
|
||||
#else
|
||||
if (rc == PCRE_ERROR_NOMATCH) {
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3029,13 +3099,19 @@ static int cpf_verify(const char *cpfnumber, int len) {
|
||||
static int msre_op_verifyCPF_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
msc_regex_t *regex;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_MULTILINE;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_MULTILINE;
|
||||
#endif
|
||||
/* Compile rule->op_param */
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -3068,6 +3144,7 @@ static int msre_op_verifyCPF_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
int rc;
|
||||
int is_cpf = 0;
|
||||
int offset;
|
||||
int options = 0;
|
||||
int matched_bytes = 0;
|
||||
char *qspos = NULL;
|
||||
const char *parm = NULL;
|
||||
@ -3127,10 +3204,19 @@ static int msre_op_verifyCPF_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
}
|
||||
}
|
||||
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, PCRE_NOTEMPTY, ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_NOTEMPTY;
|
||||
#else
|
||||
options = PCRE_NOTEMPTY;
|
||||
#endif
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, options, ovector, 30, &my_error_msg);
|
||||
|
||||
/* If there was no match, then we are done. */
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc == PCRE2_ERROR_NOMATCH) {
|
||||
#else
|
||||
if (rc == PCRE_ERROR_NOMATCH) {
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3323,13 +3409,19 @@ invalid:
|
||||
static int msre_op_verifySSN_init(msre_rule *rule, char **error_msg) {
|
||||
const char *errptr = NULL;
|
||||
int erroffset;
|
||||
int options = 0;
|
||||
msc_regex_t *regex;
|
||||
|
||||
if (error_msg == NULL) return -1;
|
||||
*error_msg = NULL;
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_MULTILINE;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_MULTILINE;
|
||||
#endif
|
||||
/* Compile rule->op_param */
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, PCRE_DOTALL | PCRE_MULTILINE, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
regex = msc_pregcomp_ex(rule->ruleset->mp, rule->op_param, options, &errptr, &erroffset, msc_pcre_match_limit, msc_pcre_match_limit_recursion);
|
||||
if (regex == NULL) {
|
||||
*error_msg = apr_psprintf(rule->ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
@ -3362,6 +3454,7 @@ static int msre_op_verifySSN_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
int rc;
|
||||
int is_ssn = 0;
|
||||
int offset;
|
||||
int options = 0;
|
||||
int matched_bytes = 0;
|
||||
char *qspos = NULL;
|
||||
const char *parm = NULL;
|
||||
@ -3421,10 +3514,19 @@ static int msre_op_verifySSN_execute(modsec_rec *msr, msre_rule *rule, msre_var
|
||||
}
|
||||
}
|
||||
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, PCRE_NOTEMPTY, ovector, 30, &my_error_msg);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_NOTEMPTY;
|
||||
#else
|
||||
options = PCRE_NOTEMPTY;
|
||||
#endif
|
||||
rc = msc_regexec_ex(regex, target, target_length, offset, options, ovector, 30, &my_error_msg);
|
||||
|
||||
/* If there was no match, then we are done. */
|
||||
#ifdef WITH_PCRE2
|
||||
if (rc == PCRE2_ERROR_NOMATCH) {
|
||||
#else
|
||||
if (rc == PCRE_ERROR_NOMATCH) {
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@ -21,6 +21,9 @@
|
||||
|
||||
#include "libxml/xpathInternals.h"
|
||||
|
||||
#ifdef WITH_PCRE2
|
||||
#define PCRE_ERROR_NOMATCH PCRE2_ERROR_NOMATCH
|
||||
#endif
|
||||
/**
|
||||
* Generates a variable from a string and a length.
|
||||
*/
|
||||
@ -64,12 +67,18 @@ static char *var_generic_list_validate(msre_ruleset *ruleset, msre_var *var) {
|
||||
msc_regex_t *regex = NULL;
|
||||
const char *errptr = NULL;
|
||||
const char *pattern = NULL;
|
||||
int options = 0;
|
||||
int erroffset;
|
||||
|
||||
pattern = apr_pstrmemdup(ruleset->mp, var->param + 1, strlen(var->param + 1) - 1);
|
||||
if (pattern == NULL) return FATAL_ERROR;
|
||||
|
||||
regex = msc_pregcomp(ruleset->mp, pattern, PCRE_DOTALL | PCRE_CASELESS | PCRE_DOLLAR_ENDONLY, &errptr, &erroffset);
|
||||
#ifdef WITH_PCRE2
|
||||
options = PCRE2_DOTALL | PCRE2_CASELESS | PCRE2_DOLLAR_ENDONLY;
|
||||
#else
|
||||
options = PCRE_DOTALL | PCRE_CASELESS | PCRE_DOLLAR_ENDONLY;
|
||||
#endif
|
||||
regex = msc_pregcomp(ruleset->mp, pattern, options, &errptr, &erroffset);
|
||||
if (regex == NULL) {
|
||||
return apr_psprintf(ruleset->mp, "Error compiling pattern (offset %d): %s",
|
||||
erroffset, errptr);
|
||||
|
@ -82,7 +82,6 @@ AC_SUBST(PCRE_LD_PATH)
|
||||
|
||||
if test -z "${PCRE_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** pcre library not found.])
|
||||
ifelse([$2], , AC_MSG_ERROR([pcre library is required]), $2)
|
||||
else
|
||||
AC_MSG_NOTICE([using pcre v${PCRE_VERSION}])
|
||||
ifelse([$1], , , $1)
|
||||
|
87
build/find_pcre2.m4
Normal file
87
build/find_pcre2.m4
Normal file
@ -0,0 +1,87 @@
|
||||
dnl Check for PCRE2 Libraries
|
||||
dnl CHECK_PCRE2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND])
|
||||
dnl Sets:
|
||||
dnl PCRE2_CFLAGS
|
||||
dnl PCRE2_LIBS
|
||||
|
||||
PCRE2_CONFIG=""
|
||||
PCRE2_VERSION=""
|
||||
PCRE2_CPPFLAGS=""
|
||||
PCRE2_CFLAGS=""
|
||||
PCRE2_LDFLAGS=""
|
||||
PCRE2_LDADD=""
|
||||
PCRE_LD_PATH=""
|
||||
|
||||
AC_DEFUN([CHECK_PCRE2],
|
||||
[dnl
|
||||
|
||||
AC_ARG_WITH(
|
||||
pcre2,
|
||||
[AC_HELP_STRING([--with-pcre2=PATH],[Path to pcre2 prefix or config script])],
|
||||
, with_pcre2=yes)
|
||||
|
||||
AS_CASE(["${with_pcre2}"],
|
||||
[no], [test_paths=],
|
||||
[yes], [test_paths="/usr/local/libpcre2 /usr/local/pcre2 /usr/local /opt/libpcre2 /opt/pcre2 /opt /usr"],
|
||||
[test_paths="${with_pcre2}"])
|
||||
|
||||
AC_MSG_CHECKING([for libpcre2 config script])
|
||||
|
||||
for x in ${test_paths}; do
|
||||
dnl # Determine if the script was specified and use it directly
|
||||
if test ! -d "$x" -a -e "$x"; then
|
||||
PCRE2_CONFIG=$x
|
||||
pcre2_path="no"
|
||||
break
|
||||
fi
|
||||
|
||||
dnl # Try known config script names/locations
|
||||
for PCRE2_CONFIG in pcre2-config; do
|
||||
if test -e "${x}/bin/${PCRE2_CONFIG}"; then
|
||||
pcre2_path="${x}/bin"
|
||||
break
|
||||
elif test -e "${x}/${PCRE2_CONFIG}"; then
|
||||
pcre2_path="${x}"
|
||||
break
|
||||
else
|
||||
pcre2_path=""
|
||||
fi
|
||||
done
|
||||
if test -n "$pcre2_path"; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if test -n "${pcre2_path}"; then
|
||||
if test "${pcre2_path}" != "no"; then
|
||||
PCRE2_CONFIG="${pcre2_path}/${PCRE2_CONFIG}"
|
||||
fi
|
||||
AC_MSG_RESULT([${PCRE2_CONFIG}])
|
||||
PCRE2_VERSION="`${PCRE2_CONFIG} --version`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre2 VERSION: $PCRE2_VERSION); fi
|
||||
PCRE2_CFLAGS="`${PCRE2_CONFIG} --cflags`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre2 CFLAGS: $PCRE2_CFLAGS); fi
|
||||
PCRE2_LDADD="`${PCRE2_CONFIG} --libs8`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre2 LDADD: $PCRE2_LDADD); fi
|
||||
PCRE_LD_PATH="/`${PCRE2_CONFIG} --libs8 | cut -d'/' -f2,3,4,5,6 | cut -d ' ' -f1`"
|
||||
if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre2 PCRE_LD_PATH: $PCRE_LD_PATH); fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_SUBST(PCRE2_CONFIG)
|
||||
AC_SUBST(PCRE2_VERSION)
|
||||
AC_SUBST(PCRE2_CPPFLAGS)
|
||||
AC_SUBST(PCRE2_CFLAGS)
|
||||
AC_SUBST(PCRE2_LDFLAGS)
|
||||
AC_SUBST(PCRE2_LDADD)
|
||||
AC_SUBST(PCRE_LD_PATH)
|
||||
|
||||
if test -z "${PCRE2_VERSION}"; then
|
||||
AC_MSG_NOTICE([*** pcre2 library not found.])
|
||||
else
|
||||
AC_MSG_NOTICE([using pcre2 v${PCRE2_VERSION}])
|
||||
PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}"
|
||||
ifelse([$1], , , $1)
|
||||
fi
|
||||
])
|
@ -865,6 +865,7 @@ AC_SUBST(APXS_MODULES)
|
||||
AC_SUBST(APXS_HTTPD)
|
||||
|
||||
CHECK_PCRE()
|
||||
CHECK_PCRE2()
|
||||
if test "$build_apache2_module" -ne 0 -o "$build_mlogc" -ne 0; then
|
||||
CHECK_APR()
|
||||
CHECK_APU()
|
||||
|
Loading…
x
Reference in New Issue
Block a user