"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "apache2/msc_pcre.c" between
modsecurity-2.9.6.tar.gz and modsecurity-2.9.7.tar.gz

About: ModSecurity is an intrusion detection and prevention module (web application firewall) for the Apache (and Nginx) Web servers.

msc_pcre.c  (modsecurity-2.9.6):msc_pcre.c  (modsecurity-2.9.7)
/* /*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/ * 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 * You may not use this file except in compliance with
* the License.  You may obtain a copy of the License at * the License.  You may obtain a copy of the License at
* *
*     http://www.apache.org/licenses/LICENSE-2.0 *     http://www.apache.org/licenses/LICENSE-2.0
* *
* If any of the files related to licensing are missing or if you have any * If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc. * other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org. * directly using the email address security@modsecurity.org.
*/ */
#include "msc_pcre.h" #include "msc_pcre.h"
#include "apr_strings.h" #include "apr_strings.h"
/** /**
* Releases the resources used by a single regular expression pattern. * Releases the resources used by a single regular expression pattern.
*/ */
static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) { static apr_status_t msc_pcre_cleanup(msc_regex_t *regex) {
if (regex != NULL) { 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 (regex->pe != NULL) {
#if defined(VERSION_NGINX) #if defined(VERSION_NGINX)
pcre_free(regex->pe); pcre_free(regex->pe);
#else #else
free(regex->pe); free(regex->pe);
#endif #endif
regex->pe = NULL; regex->pe = NULL;
} }
if (regex->re != NULL) { if (regex->re != NULL) {
pcre_free(regex->re); pcre_free(regex->re);
regex->re = NULL; regex->re = NULL;
} }
#endif
} }
return APR_SUCCESS; return APR_SUCCESS;
} }
/** /**
* Compiles the provided regular expression pattern. The _err* * Compiles the provided regular expression pattern. The _err*
* parameters are optional, but if they are provided and an error * parameters are optional, but if they are provided and an error
* occurs they will contain the error message and the offset in * occurs they will contain the error message and the offset in
* the pattern where the offending part of the pattern begins. The * the pattern where the offending part of the pattern begins. The
* match_limit* parameters are optional and if >0, then will set * match_limit* parameters are optional and if >0, then will set
* match limits. * match limits.
*/ */
void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options, void *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset, const char **_errptr, int *_erroffset,
int match_limit, int match_limit_recursion) 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;
}
#ifdef WITH_PCRE_JIT
regex->jit_compile_rc = pcre2_jit_compile(regex->re, PCRE2_JIT_COMPLETE);
#endif
/* 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; const char *errptr = NULL;
int erroffset; int erroffset;
msc_regex_t *regex; msc_regex_t *regex;
pcre_extra *pe = NULL; pcre_extra *pe = NULL;
regex = apr_pcalloc(pool, sizeof(msc_regex_t)); regex = apr_pcalloc(pool, sizeof(msc_regex_t));
if (regex == NULL) return NULL; if (regex == NULL) return NULL;
regex->pattern = pattern; regex->pattern = pattern;
skipping to change at line 134 skipping to change at line 219
#pragma message ( "This PCRE version does not support match recursion limits! U pgrade to at least PCRE v6.5." ) #pragma message ( "This PCRE version does not support match recursion limits! U pgrade to at least PCRE v6.5." )
#endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */ #endif /* PCRE_EXTRA_MATCH_LIMIT_RECURSION */
regex->pe = pe; regex->pe = pe;
apr_pool_cleanup_register(pool, (void *)regex, apr_pool_cleanup_register(pool, (void *)regex,
(apr_status_t (*)(void *))msc_pcre_cleanup, apr_pool_cleanup_null); (apr_status_t (*)(void *))msc_pcre_cleanup, apr_pool_cleanup_null);
return regex; return regex;
} }
#endif /* WITH_PCRE2 */
/** /**
* Compiles the provided regular expression pattern. Calls msc_pregcomp_ex() * Compiles the provided regular expression pattern. Calls msc_pregcomp_ex()
* with default limits. * with default limits.
*/ */
void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options, void *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options,
const char **_errptr, int *_erroffset) const char **_errptr, int *_erroffset)
{ {
return msc_pregcomp_ex(pool, pattern, options, _errptr, _erroffset, 0, 0); return msc_pregcomp_ex(pool, pattern, options, _errptr, _erroffset, 0, 0);
} }
/** /**
* Executes regular expression with extended options. * Executes regular expression with extended options (or match context)
* Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1 * Returns PCRE_ERROR_NOMATCH (or PCRE2_ERROR_NOMATCH),
* on errors, and a value > 0 when there is a match. * 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 msc_regexec_ex(msc_regex_t *regex, const char *s, unsigned int slen,
int startoffset, int options, int *ovector, int ovecsize, char **error_msg) int startoffset, int options, int *ovector, int ovecsize, char **error_msg)
{ {
if (error_msg == NULL) return -1000; /* To differentiate from PCRE as it alr eady uses -1. */ if (error_msg == NULL) return -1000; /* To differentiate from PCRE as it alr eady uses -1. */
*error_msg = NULL; *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);
#ifdef WITH_PCRE_JIT
if (regex->jit_compile_rc == 0) {
pcre2_ret = pcre2_jit_match(regex->re, pcre2_s, slen,
(PCRE2_SIZE)(startoffset), (uint32_t)options, match_data, regex-
>match_context);
}
if (regex->jit_compile_rc != 0 || pcre2_ret == PCRE2_ERROR_JIT_STACKLIMI
T) {
pcre2_ret = pcre2_match(regex->re, pcre2_s, slen,
(PCRE2_SIZE)(startoffset), (PCRE2_NO_JIT | (uint32_t)options), m
atch_data, regex->match_context);
}
#else
pcre2_ret = pcre2_match(regex->re, pcre2_s, slen,
(PCRE2_SIZE)(startoffset), (uint32_t)options, match_data, regex->mat
ch_context);
#endif
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, ovecto r, ovecsize); return pcre_exec(regex->re, regex->pe, s, slen, startoffset, options, ovecto r, ovecsize);
#endif
} }
/** /**
* Executes regular expression, capturing subexpressions in the given * Executes regular expression, capturing subexpressions in the given
* vector. Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1 * vector. Returns PCRE_ERROR_NOMATCH when there is no match, error code < -1
* on errors, and a value > 0 when there is a match. * on errors, and a value > 0 when there is a match.
*/ */
int msc_regexec_capture(msc_regex_t *regex, const char *s, unsigned int slen, int msc_regexec_capture(msc_regex_t *regex, const char *s, unsigned int slen,
int *ovector, int ovecsize, char **error_msg) int *ovector, int ovecsize, char **error_msg)
{ {
skipping to change at line 191 skipping to change at line 322
*error_msg = NULL; *error_msg = NULL;
return msc_regexec_ex(regex, s, slen, 0, 0, NULL, 0, error_msg); return msc_regexec_ex(regex, s, slen, 0, 0, NULL, 0, error_msg);
} }
/** /**
* Gets info on a compiled regex. * Gets info on a compiled regex.
*/ */
int msc_fullinfo(msc_regex_t *regex, int what, void *where) 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); return pcre_fullinfo(regex->re, regex->pe, what, where);
#endif
} }
 End of changes. 10 change blocks. 
4 lines changed or deleted 144 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)