diff --git a/include/common/regex.h b/include/common/regex.h index 1cc471b33..9080bda44 100644 --- a/include/common/regex.h +++ b/include/common/regex.h @@ -31,6 +31,9 @@ #include #ifdef USE_PCRE_JIT +#ifndef PCRE_CONFIG_JIT +#error "The PCRE lib doesn't support JIT. Change your lib, or remove the option USE_PCRE_JIT." +#endif struct jit_regex { pcre *reg; pcre_extra *extra; @@ -64,6 +67,17 @@ struct hdr_exp { extern regmatch_t pmatch[MAX_MATCH]; +/* "str" is the string that contain the regex to compile. + * "regex" is preallocated memory. After the execution of this function, this + * struct contain the compiled regex. + * "cs" is the case sensitive flag. If cs is true, case sensitive is enabled. + * "cap" is capture flag. If cap if true the regex can capture into + * parenthesis strings. + * "err" is the standar error message pointer. + * + * The function return 1 is succes case, else return 0 and err is filled. + */ +int regex_comp(const char *str, regex *regex, int cs, int cap, char **err); int exp_replace(char *dst, char *src, const char *str, const regmatch_t *matches); const char *check_replace_string(const char *str); const char *chain_regex(struct hdr_exp **head, const regex_t *preg, diff --git a/src/acl.c b/src/acl.c index b6e55ec26..7dc25fb9b 100644 --- a/src/acl.c +++ b/src/acl.c @@ -543,11 +543,6 @@ static void acl_free_reg(void *ptr) int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, char **err) { regex *preg; - int icase; -#ifdef USE_PCRE_JIT - const char *error; - int erroffset; -#endif preg = calloc(1, sizeof(*preg)); @@ -556,32 +551,11 @@ int acl_parse_reg(const char **text, struct acl_pattern *pattern, int *opaque, c return 0; } -#ifdef USE_PCRE_JIT - icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? PCRE_CASELESS : 0; - preg->reg = pcre_compile(*text, PCRE_NO_AUTO_CAPTURE | icase, &error, &erroffset, - NULL); - if (!preg->reg) { + if (!regex_comp(*text, preg, !(pattern->flags & ACL_PAT_F_IGNORE_CASE), 0, err)) { free(preg); - memprintf(err, "regex '%s' is invalid (error=%s, erroffset=%d)", *text, error, erroffset); return 0; } - preg->extra = pcre_study(preg->reg, PCRE_STUDY_JIT_COMPILE, &error); - if (!preg->extra) { - pcre_free(preg->reg); - free(preg); - memprintf(err, "failed to compile regex '%s' (error=%s)", *text, error); - return 0; - } -#else - icase = (pattern->flags & ACL_PAT_F_IGNORE_CASE) ? REG_ICASE : 0; - if (regcomp(preg, *text, REG_EXTENDED | REG_NOSUB | icase) != 0) { - free(preg); - memprintf(err, "regex '%s' is invalid", *text); - return 0; - } -#endif - pattern->ptr.reg = preg; pattern->freeptrbuf = &acl_free_reg; return 1; diff --git a/src/regex.c b/src/regex.c index 1455fb452..a268996b0 100644 --- a/src/regex.c +++ b/src/regex.c @@ -122,7 +122,45 @@ const char *chain_regex(struct hdr_exp **head, const regex_t *preg, return NULL; } +int regex_comp(const char *str, regex *regex, int cs, int cap, char **err) +{ +#ifdef USE_PCRE_JIT + int flags = 0; + const char *error; + int erroffset; + if (!cs) + flags |= PCRE_CASELESS; + if (!cap) + flags |= PCRE_NO_AUTO_CAPTURE; + + regex->reg = pcre_compile(str, flags, &error, &erroffset, NULL); + if (!regex->reg) { + memprintf(err, "regex '%s' is invalid (error=%s, erroffset=%d)", str, error, erroffset); + return 0; + } + + regex->extra = pcre_study(regex->reg, PCRE_STUDY_JIT_COMPILE, &error); + if (!regex->extra) { + pcre_free(regex->reg); + memprintf(err, "failed to compile regex '%s' (error=%s)", str, error); + return 0; + } +#else + int flags = REG_EXTENDED; + + if (!cs) + flags |= REG_ICASE; + if (!cap) + flags |= REG_NOSUB; + + if (regcomp(regex, str, flags) != 0) { + memprintf(err, "regex '%s' is invalid", str); + return 0; + } +#endif + return 1; +} /* * Local variables: