MEDIUM: regex: replace all standard regex function by own functions
This patch remove all references of standard regex in haproxy. The last
remaining references are only in the regex.[ch] files.
In the file src/checks.c, the original function uses a "pmatch" array.
In fact this array is unused. This patch remove it.
diff --git a/include/common/regex.h b/include/common/regex.h
index cec68c8..29a6ace 100644
--- a/include/common/regex.h
+++ b/include/common/regex.h
@@ -60,7 +60,7 @@
struct hdr_exp {
struct hdr_exp *next;
- const regex_t *preg; /* expression to look for */
+ struct my_regex *preg; /* expression to look for */
int action; /* ACT_ALLOW, ACT_REPLACE, ACT_REMOVE, ACT_DENY */
const char *replace; /* expression to set instead */
void *cond; /* a possible condition or NULL */
@@ -81,7 +81,7 @@
int regex_comp(const char *str, struct my_regex *regex, int cs, int cap, char **err);
int exp_replace(char *dst, unsigned int dst_size, 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,
+const char *chain_regex(struct hdr_exp **head, struct my_regex *preg,
int action, const char *replace, void *cond);
/* If the function doesn't match, it returns false, else it returns true.
diff --git a/include/types/checks.h b/include/types/checks.h
index d5038eb..a50043b 100644
--- a/include/types/checks.h
+++ b/include/types/checks.h
@@ -177,7 +177,7 @@
/* sent string is string */
char *string; /* sent or expected string */
int string_len; /* string lenght */
- regex_t *expect_regex; /* expected */
+ struct my_regex *expect_regex; /* expected */
int inverse; /* 0 = regular match, 1 = inverse match */
unsigned short port; /* port to connect to */
unsigned short conn_opts; /* options when setting up a new connection */
diff --git a/include/types/proto_http.h b/include/types/proto_http.h
index ff196a0..affc231 100644
--- a/include/types/proto_http.h
+++ b/include/types/proto_http.h
@@ -419,7 +419,7 @@
char *name; /* header name */
int name_len; /* header name's length */
struct list fmt; /* log-format compatible expression */
- regex_t* re; /* used by replace-header and replace-value */
+ struct my_regex re; /* used by replace-header and replace-value */
} hdr_add; /* args used by "add-header" and "set-header" */
struct redirect_rule *redir; /* redirect rule or "http-request redirect" */
int nice; /* nice value for HTTP_REQ_ACT_SET_NICE */
@@ -445,7 +445,7 @@
char *name; /* header name */
int name_len; /* header name's length */
struct list fmt; /* log-format compatible expression */
- regex_t* re; /* used by replace-header and replace-value */
+ struct my_regex re; /* used by replace-header and replace-value */
} hdr_add; /* args used by "add-header" and "set-header" */
int nice; /* nice value for HTTP_RES_ACT_SET_NICE */
int loglevel; /* log-level value for HTTP_RES_ACT_SET_LOGL */
diff --git a/include/types/proxy.h b/include/types/proxy.h
index 33524f3..b33b634 100644
--- a/include/types/proxy.h
+++ b/include/types/proxy.h
@@ -343,7 +343,7 @@
char *check_req; /* HTTP or SSL request to use for PR_O_HTTP_CHK|PR_O_SSL3_CHK */
int check_len; /* Length of the HTTP or SSL3 request */
char *expect_str; /* http-check expected content : string or text version of the regex */
- regex_t *expect_regex; /* http-check expected content */
+ struct my_regex *expect_regex; /* http-check expected content */
struct chunk errmsg[HTTP_ERR_SIZE]; /* default or customized error messages for known errors */
int uuid; /* universally unique proxy ID, used for SNMP */
unsigned int backlog; /* force the frontend's listen backlog */
diff --git a/src/cfgparse.c b/src/cfgparse.c
index eb40833..762978a 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -1527,11 +1527,14 @@
const char *cmd, const char *reg, const char *repl,
const char **cond_start)
{
- regex_t *preg = NULL;
+ struct my_regex *preg = NULL;
char *errmsg = NULL;
const char *err;
+ char *error;
int ret_code = 0;
struct acl_cond *cond = NULL;
+ int cs;
+ int cap;
if (px == &defproxy) {
Alert("parsing [%s:%d] : '%s' not allowed in 'defaults' section.\n", file, line, cmd);
@@ -1570,15 +1573,19 @@
((px->cap & PR_CAP_BE) ? SMP_VAL_BE_HRS_HDR : SMP_VAL_FE_HRS_HDR),
file, line);
- preg = calloc(1, sizeof(regex_t));
+ preg = calloc(1, sizeof(*preg));
if (!preg) {
Alert("parsing [%s:%d] : '%s' : not enough memory to build regex.\n", file, line, cmd);
ret_code = ERR_ALERT | ERR_FATAL;
goto err;
}
- if (regcomp(preg, reg, REG_EXTENDED | flags) != 0) {
- Alert("parsing [%s:%d] : '%s' : bad regular expression '%s'.\n", file, line, cmd, reg);
+ cs = !(flags & REG_ICASE);
+ cap = !(flags & REG_NOSUB);
+ error = NULL;
+ if (!regex_comp(reg, preg, cs, cap, &error)) {
+ Alert("parsing [%s:%d] : '%s' : regular expression '%s' : %s\n", file, line, cmd, reg, error);
+ free(error);
ret_code = ERR_ALERT | ERR_FATAL;
goto err;
}
@@ -1598,7 +1605,7 @@
return ret_code;
err_free:
- regfree(preg);
+ regex_free(preg);
err:
free(preg);
free(errmsg);
@@ -1811,6 +1818,7 @@
{
static struct proxy *curproxy = NULL;
const char *err;
+ char *error;
int rc;
unsigned val;
int err_code = 0;
@@ -1971,8 +1979,8 @@
curproxy->expect_str = strdup(defproxy.expect_str);
if (defproxy.expect_regex) {
/* note: this regex is known to be valid */
- curproxy->expect_regex = calloc(1, sizeof(regex_t));
- regcomp(curproxy->expect_regex, defproxy.expect_str, REG_EXTENDED);
+ curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
+ regex_comp(defproxy.expect_str, curproxy->expect_regex, 1, 1, NULL);
}
}
@@ -2119,7 +2127,7 @@
defproxy.server_id_hdr_len = 0;
free(defproxy.expect_str);
if (defproxy.expect_regex) {
- regfree(defproxy.expect_regex);
+ regex_free(defproxy.expect_regex);
free(defproxy.expect_regex);
defproxy.expect_regex = NULL;
}
@@ -4213,15 +4221,17 @@
curproxy->options2 |= PR_O2_EXP_RSTS;
free(curproxy->expect_str);
if (curproxy->expect_regex) {
- regfree(curproxy->expect_regex);
+ regex_free(curproxy->expect_regex);
free(curproxy->expect_regex);
curproxy->expect_regex = NULL;
}
curproxy->expect_str = strdup(args[cur_arg + 1]);
- curproxy->expect_regex = calloc(1, sizeof(regex_t));
- if (regcomp(curproxy->expect_regex, args[cur_arg + 1], REG_EXTENDED) != 0) {
- Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s'.\n",
- file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1]);
+ curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
+ error = NULL;
+ if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
+ Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
+ file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
+ free(error);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@@ -4236,15 +4246,17 @@
curproxy->options2 |= PR_O2_EXP_RSTR;
free(curproxy->expect_str);
if (curproxy->expect_regex) {
- regfree(curproxy->expect_regex);
+ regex_free(curproxy->expect_regex);
free(curproxy->expect_regex);
curproxy->expect_regex = NULL;
}
curproxy->expect_str = strdup(args[cur_arg + 1]);
- curproxy->expect_regex = calloc(1, sizeof(regex_t));
- if (regcomp(curproxy->expect_regex, args[cur_arg + 1], REG_EXTENDED) != 0) {
- Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s'.\n",
- file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1]);
+ curproxy->expect_regex = calloc(1, sizeof(*curproxy->expect_regex));
+ error = NULL;
+ if (!regex_comp(args[cur_arg + 1], curproxy->expect_regex, 1, 1, &error)) {
+ Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
+ file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
+ free(error);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
@@ -4456,10 +4468,12 @@
tcpcheck->action = TCPCHK_ACT_EXPECT;
tcpcheck->string_len = 0;
tcpcheck->string = NULL;
- tcpcheck->expect_regex = calloc(1, sizeof(regex_t));
- if (regcomp(tcpcheck->expect_regex, args[cur_arg + 1], REG_EXTENDED) != 0) {
- Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s'.\n",
- file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1]);
+ tcpcheck->expect_regex = calloc(1, sizeof(*tcpcheck->expect_regex));
+ error = NULL;
+ if (!regex_comp(args[cur_arg + 1], tcpcheck->expect_regex, 1, 1, &error)) {
+ Alert("parsing [%s:%d] : '%s %s %s' : bad regular expression '%s': %s.\n",
+ file, linenum, args[0], args[1], ptr_arg, args[cur_arg + 1], error);
+ free(error);
err_code |= ERR_ALERT | ERR_FATAL;
goto out;
}
diff --git a/src/checks.c b/src/checks.c
index 6b501de..cba0018 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1730,7 +1730,7 @@
if ((s->proxy->options2 & PR_O2_EXP_TYPE) == PR_O2_EXP_STS)
ret = strncmp(s->proxy->expect_str, status_code, 3) == 0;
else
- ret = regexec(s->proxy->expect_regex, status_code, MAX_MATCH, pmatch, 0) == 0;
+ ret = regex_exec(s->proxy->expect_regex, status_code);
/* we necessarily have the response, so there are no partial failures */
if (s->proxy->options2 & PR_O2_EXP_INV)
@@ -1782,7 +1782,7 @@
if ((s->proxy->options2 & PR_O2_EXP_TYPE) == PR_O2_EXP_STR)
ret = strstr(contentptr, s->proxy->expect_str) != NULL;
else
- ret = regexec(s->proxy->expect_regex, contentptr, MAX_MATCH, pmatch, 0) == 0;
+ ret = regex_exec(s->proxy->expect_regex, contentptr);
/* if we don't match, we may need to wait more */
if (!ret && !done)
@@ -2135,7 +2135,7 @@
if (cur->string != NULL)
ret = my_memmem(contentptr, check->bi->i, cur->string, cur->string_len) != NULL;
else if (cur->expect_regex != NULL)
- ret = regexec(cur->expect_regex, contentptr, MAX_MATCH, pmatch, 0) == 0;
+ ret = regex_exec(cur->expect_regex, contentptr);
if (!ret && !done)
continue; /* try to read more */
diff --git a/src/haproxy.c b/src/haproxy.c
index cd42b34..9f742c7 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1034,8 +1034,8 @@
for (exp = p->req_exp; exp != NULL; ) {
if (exp->preg) {
- regfree((regex_t *)exp->preg);
- free((regex_t *)exp->preg);
+ regex_free(exp->preg);
+ free(exp->preg);
}
if (exp->replace && exp->action != ACT_SETBE)
@@ -1047,8 +1047,8 @@
for (exp = p->rsp_exp; exp != NULL; ) {
if (exp->preg) {
- regfree((regex_t *)exp->preg);
- free((regex_t *)exp->preg);
+ regex_free(exp->preg);
+ free(exp->preg);
}
if (exp->replace && exp->action != ACT_SETBE)
diff --git a/src/proto_http.c b/src/proto_http.c
index 572739d..e61f512 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -3179,10 +3179,10 @@
/* Returns the number of characters written to destination,
* -1 on internal error and -2 if no replacement took place.
*/
-static int http_replace_header(regex_t* re, char* dst, uint dst_size, char* val,
- const char* rep_str)
+static int http_replace_header(struct my_regex *re, char *dst, uint dst_size, char *val,
+ const char *rep_str)
{
- if (regexec(re, val, MAX_MATCH, pmatch, 0))
+ if (!regex_exec_match(re, val, MAX_MATCH, pmatch))
return -2;
return exp_replace(dst, dst_size, val, rep_str, pmatch);
@@ -3191,8 +3191,8 @@
/* Returns the number of characters written to destination,
* -1 on internal error and -2 if no replacement took place.
*/
-static int http_replace_value(regex_t* re, char* dst, uint dst_size, char* val, char delim,
- const char* rep_str)
+static int http_replace_value(struct my_regex *re, char *dst, uint dst_size, char *val, char delim,
+ const char *rep_str)
{
char* p = val;
char* dst_end = dst + dst_size;
@@ -3209,7 +3209,7 @@
tok_end = p + strlen(p);
}
- if (regexec(re, p, MAX_MATCH, pmatch, 0) == 0) {
+ if (regex_exec_match(re, p, MAX_MATCH, pmatch)) {
int replace_n = exp_replace(dst_p, dst_end - dst_p, p, rep_str, pmatch);
if (replace_n < 0)
@@ -3243,7 +3243,7 @@
}
static int http_transform_header(struct session* s, struct http_msg *msg, const char* name, uint name_len,
- char* buf, struct hdr_idx* idx, struct list *fmt, regex_t* re,
+ char* buf, struct hdr_idx* idx, struct list *fmt, struct my_regex *re,
struct hdr_ctx* ctx, int action)
{
ctx->idx = 0;
@@ -3389,7 +3389,7 @@
case HTTP_REQ_ACT_REPLACE_VAL:
if (http_transform_header(s, &txn->req, rule->arg.hdr_add.name, rule->arg.hdr_add.name_len,
txn->req.chn->buf->p, &txn->hdr_idx, &rule->arg.hdr_add.fmt,
- rule->arg.hdr_add.re, &ctx, rule->action))
+ &rule->arg.hdr_add.re, &ctx, rule->action))
return HTTP_RULE_RES_BADREQ;
break;
@@ -3578,7 +3578,7 @@
case HTTP_RES_ACT_REPLACE_VAL:
if (http_transform_header(s, &txn->rsp, rule->arg.hdr_add.name, rule->arg.hdr_add.name_len,
txn->rsp.chn->buf->p, &txn->hdr_idx, &rule->arg.hdr_add.fmt,
- rule->arg.hdr_add.re, &ctx, rule->action))
+ &rule->arg.hdr_add.re, &ctx, rule->action))
return NULL; /* note: we should report an error here */
break;
@@ -6924,7 +6924,7 @@
term = *cur_end;
*cur_end = '\0';
- if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
+ if (regex_exec_match(exp->preg, cur_ptr, MAX_MATCH, pmatch)) {
switch (exp->action) {
case ACT_SETBE:
/* It is not possible to jump a second time.
@@ -7036,7 +7036,7 @@
term = *cur_end;
*cur_end = '\0';
- if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
+ if (regex_exec_match(exp->preg, cur_ptr, MAX_MATCH, pmatch)) {
switch (exp->action) {
case ACT_SETBE:
/* It is not possible to jump a second time.
@@ -7807,7 +7807,7 @@
term = *cur_end;
*cur_end = '\0';
- if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
+ if (regex_exec_match(exp->preg, cur_ptr, MAX_MATCH, pmatch)) {
switch (exp->action) {
case ACT_ALLOW:
txn->flags |= TX_SVALLOW;
@@ -7899,7 +7899,7 @@
term = *cur_end;
*cur_end = '\0';
- if (regexec(exp->preg, cur_ptr, MAX_MATCH, pmatch, 0) == 0) {
+ if (regex_exec_match(exp->preg, cur_ptr, MAX_MATCH, pmatch)) {
switch (exp->action) {
case ACT_ALLOW:
txn->flags |= TX_SVALLOW;
@@ -8895,21 +8895,13 @@
s->rep->analyse_exp = TICK_ETERNITY;
}
-static inline void free_regex(regex_t* re)
-{
- if (re) {
- regfree(re);
- free(re);
- }
-}
-
void free_http_res_rules(struct list *r)
{
struct http_res_rule *tr, *pr;
list_for_each_entry_safe(pr, tr, r, list) {
LIST_DEL(&pr->list);
- free_regex(pr->arg.hdr_add.re);
+ regex_free(&pr->arg.hdr_add.re);
free(pr);
}
}
@@ -8923,7 +8915,7 @@
if (pr->action == HTTP_REQ_ACT_AUTH)
free(pr->arg.auth.realm);
- free_regex(pr->arg.hdr_add.re);
+ regex_free(&pr->arg.hdr_add.re);
free(pr);
}
}
@@ -8934,6 +8926,7 @@
struct http_req_rule *rule;
struct http_req_action_kw *custom = NULL;
int cur_arg;
+ char *error;
rule = (struct http_req_rule*)calloc(1, sizeof(struct http_req_rule));
if (!rule) {
@@ -9081,14 +9074,11 @@
rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name);
LIST_INIT(&rule->arg.hdr_add.fmt);
- if (!(rule->arg.hdr_add.re = calloc(1, sizeof(*rule->arg.hdr_add.re)))) {
- Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
- goto out_err;
- }
-
- if (regcomp(rule->arg.hdr_add.re, args[cur_arg + 1], REG_EXTENDED)) {
- Alert("parsing [%s:%d] : '%s' : bad regular expression.\n", file, linenum,
- args[cur_arg + 1]);
+ error = NULL;
+ if (!regex_comp(args[cur_arg + 1], &rule->arg.hdr_add.re, 1, 1, &error)) {
+ Alert("parsing [%s:%d] : '%s' : %s.\n", file, linenum,
+ args[cur_arg + 1], error);
+ free(error);
goto out_err;
}
@@ -9303,6 +9293,7 @@
struct http_res_rule *rule;
struct http_res_action_kw *custom = NULL;
int cur_arg;
+ char *error;
rule = calloc(1, sizeof(*rule));
if (!rule) {
@@ -9435,14 +9426,11 @@
rule->arg.hdr_add.name_len = strlen(rule->arg.hdr_add.name);
LIST_INIT(&rule->arg.hdr_add.fmt);
- if (!(rule->arg.hdr_add.re = calloc(1, sizeof(*rule->arg.hdr_add.re)))) {
- Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
- goto out_err;
- }
-
- if (regcomp(rule->arg.hdr_add.re, args[cur_arg + 1], REG_EXTENDED)) {
- Alert("parsing [%s:%d] : '%s' : bad regular expression.\n", file, linenum,
- args[cur_arg + 1]);
+ error = NULL;
+ if (!regex_comp(args[cur_arg + 1], &rule->arg.hdr_add.re, 1, 1, &error)) {
+ Alert("parsing [%s:%d] : '%s' : %s.\n", file, linenum,
+ args[cur_arg + 1], error);
+ free(error);
goto out_err;
}
diff --git a/src/regex.c b/src/regex.c
index 8de56e6..2292002 100644
--- a/src/regex.c
+++ b/src/regex.c
@@ -124,7 +124,7 @@
/* returns the pointer to an error in the replacement string, or NULL if OK */
-const char *chain_regex(struct hdr_exp **head, const regex_t *preg,
+const char *chain_regex(struct hdr_exp **head, struct my_regex *preg,
int action, const char *replace, void *cond)
{
struct hdr_exp *exp;