From ed5a4aefaee68e1046a55218be7853739e3484c0 Mon Sep 17 00:00:00 2001 From: Thierry FOURNIER Date: Mon, 14 Oct 2013 14:07:36 +0200 Subject: [PATCH] CLEANUP: regex: Create regex_comp function that compiles regex using compilation options The current file "regex.h" define an abstraction for the regex. It provides the same struct name and the same "regexec" function for the 3 regex types supported: standard libc, basic pcre and jit pcre. The regex compilation function is not provided by this file. If the developper wants to use regex, he must write regex compilation code containing "#define *JIT*". This patch provides a unique regex compilation function according to the compilation options. In addition, the "regex.h" file checks the presence of the "#define PCRE_CONFIG_JIT" when "USE_PCRE_JIT" is enabled. If this flag is not present, the pcre lib doesn't support JIT and "#error" is emitted. --- include/common/regex.h | 14 ++++++++++++++ src/acl.c | 28 +--------------------------- src/regex.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 27 deletions(-) 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: