mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-01 22:48:25 +00:00
BUG/MEDIUM: patterns: last fix was still not enough
Last fix did address the issue for inlined patterns, but it was not
enough because the flags are lost as well when updating patterns
dynamically over the CLI.
Also if the same file was used once with -i and another time without
-i, their references would have been merged and both would have used
the same matching method.
It's appear that the patterns have two types of flags. The first
ones are relative to the pattern matching, and the second are
relative to the pattern storage. The pattern matching flags are
the same for all the patterns of one expression. Now they are
stored in the expression. The storage flags are information
returned by the pattern mathing function. This information is
relative to each entry and is stored in the "struct pattern".
Now, the expression matching flags are forwarded to the parse
and index functions. These flags are stored during the
configuration parsing, and they are used during the parse and
index actions.
This issue was introduced in dev23 with the major pattern rework,
and is a continuation of commit a631fc8
("BUG/MAJOR: patterns: -i
and -n are ignored for inlined patterns"). No backport is needed.
This commit is contained in:
parent
a631fc8de8
commit
e47e4e2385
@ -30,7 +30,7 @@
|
||||
|
||||
/* pattern management function arrays */
|
||||
extern char *pat_match_names[PAT_MATCH_NUM];
|
||||
extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, char **);
|
||||
extern int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, int, char **);
|
||||
extern int (*pat_index_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pattern *, char **);
|
||||
extern void (*pat_delete_fcts[PAT_MATCH_NUM])(struct pattern_expr *, struct pat_ref_elt *);
|
||||
extern void (*pat_prune_fcts[PAT_MATCH_NUM])(struct pattern_expr *);
|
||||
@ -101,34 +101,34 @@ void pat_prune_reg(struct pattern_expr *expr);
|
||||
|
||||
|
||||
/* ignore the current line */
|
||||
int pat_parse_nothing(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_nothing(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse an integer. It is put both in min and max. */
|
||||
int pat_parse_int(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_int(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse an version. It is put both in min and max. */
|
||||
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse a range of integers delimited by either ':' or '-'. If only one
|
||||
* integer is read, it is set as both min and max.
|
||||
*/
|
||||
int pat_parse_range(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_range(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse a string. It is allocated and duplicated. */
|
||||
int pat_parse_str(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_str(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse a hexa binary definition. It is allocated and duplicated. */
|
||||
int pat_parse_bin(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_bin(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse a regex. It is allocated. */
|
||||
int pat_parse_reg(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_reg(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* Parse an IP address and an optional mask in the form addr[/mask].
|
||||
* The addr may either be an IPv4 address or a hostname. The mask
|
||||
* may either be a dotted mask or a number of bits. Returns 1 if OK,
|
||||
* otherwise 0.
|
||||
*/
|
||||
int pat_parse_ip(const char *text, struct pattern *pattern, char **err);
|
||||
int pat_parse_ip(const char *text, struct pattern *pattern, int mflags, char **err);
|
||||
|
||||
/* NB: For two strings to be identical, it is required that their lengths match */
|
||||
struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int fill);
|
||||
@ -183,7 +183,7 @@ struct pat_ref *pat_ref_new(const char *reference, const char *display, unsigned
|
||||
struct pat_ref *pat_ref_newid(int unique_id, const char *display, unsigned int flags);
|
||||
struct pat_ref_elt *pat_ref_find_elt(struct pat_ref *ref, const char *key);
|
||||
int pat_ref_append(struct pat_ref *ref, char *pattern, char *sample, int line);
|
||||
int pat_ref_add(struct pat_ref *ref, const char *pattern, const char *sample, int patflags, char **err);
|
||||
int pat_ref_add(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
|
||||
int pat_ref_set(struct pat_ref *ref, const char *pattern, const char *sample, char **err);
|
||||
int pat_ref_set_by_id(struct pat_ref *ref, struct pat_ref_elt *refelt, const char *value, char **err);
|
||||
int pat_ref_delete(struct pat_ref *ref, const char *key);
|
||||
|
@ -93,7 +93,7 @@ struct acl_keyword {
|
||||
const char *kw;
|
||||
char *fetch_kw;
|
||||
int match_type; /* Contain PAT_MATCH_* */
|
||||
int (*parse)(const char *text, struct pattern *pattern, char **err);
|
||||
int (*parse)(const char *text, struct pattern *pattern, int flags, char **err);
|
||||
int (*index)(struct pattern_expr *expr, struct pattern *pattern, char **err);
|
||||
void (*delete)(struct pattern_expr *expr, struct pat_ref_elt *);
|
||||
void (*prune)(struct pattern_expr *expr);
|
||||
|
@ -61,11 +61,15 @@ enum pat_match_res {
|
||||
PAT_MATCH = 3, /* sample matched at least one pattern */
|
||||
};
|
||||
|
||||
/* possible flags for expressions or patterns */
|
||||
/* possible flags for patterns matching or parsing */
|
||||
enum {
|
||||
PAT_F_IGNORE_CASE = 1 << 0, /* ignore case */
|
||||
PAT_F_TREE = 1 << 1, /* some patterns are arranged in a tree */
|
||||
PAT_F_NO_DNS = 1 << 2, /* dont perform any DNS requests */
|
||||
PAT_MF_IGNORE_CASE = 1 << 0, /* ignore case */
|
||||
PAT_MF_NO_DNS = 1 << 1, /* dont perform any DNS requests */
|
||||
};
|
||||
|
||||
/* possible flags for patterns storage */
|
||||
enum {
|
||||
PAT_SF_TREE = 1 << 0, /* some patterns are arranged in a tree */
|
||||
};
|
||||
|
||||
/* ACL match methods */
|
||||
@ -163,7 +167,7 @@ struct pattern {
|
||||
struct my_regex *reg; /* a compiled regex */
|
||||
} ptr; /* indirect values, allocated */
|
||||
int len; /* data length when required */
|
||||
int flags; /* expr or pattern flags. */
|
||||
int sflags; /* flags relative to the storage method. */
|
||||
struct sample_storage *smp; /* used to store a pointer to sample value associated
|
||||
with the match. It is used with maps */
|
||||
struct pat_ref_elt *ref;
|
||||
@ -191,6 +195,7 @@ struct pattern_expr {
|
||||
struct list patterns; /* list of acl_patterns */
|
||||
struct eb_root pattern_tree; /* may be used for lookup in large datasets */
|
||||
struct eb_root pattern_tree_2; /* may be used for different types */
|
||||
int mflags; /* flags relative to the parsing or matching method. */
|
||||
};
|
||||
|
||||
/* This is a list of expression. A struct pattern_expr can be used by
|
||||
@ -205,7 +210,7 @@ struct pattern_expr_list {
|
||||
|
||||
/* This struct contain a list of pattern expr */
|
||||
struct pattern_head {
|
||||
int (*parse)(const char *text, struct pattern *pattern, char **err);
|
||||
int (*parse)(const char *text, struct pattern *pattern, int flags, char **err);
|
||||
int (*parse_smp)(const char *text, struct sample_storage *smp);
|
||||
int (*index)(struct pattern_expr *, struct pattern *, char **);
|
||||
void (*delete)(struct pattern_expr *, struct pat_ref_elt *);
|
||||
|
@ -445,9 +445,9 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
||||
unique_id = -1;
|
||||
while (**args == '-') {
|
||||
if ((*args)[1] == 'i')
|
||||
patflags |= PAT_F_IGNORE_CASE;
|
||||
patflags |= PAT_MF_IGNORE_CASE;
|
||||
else if ((*args)[1] == 'n')
|
||||
patflags |= PAT_F_NO_DNS;
|
||||
patflags |= PAT_MF_NO_DNS;
|
||||
else if ((*args)[1] == 'u') {
|
||||
unique_id = strtol(args[1], &error, 10);
|
||||
if (*error != '\0') {
|
||||
@ -534,6 +534,9 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
||||
if (!pattern_expr)
|
||||
goto out_free_expr;
|
||||
|
||||
/* Copy the pattern matching and indexing flags. */
|
||||
pattern_expr->mflags = patflags;
|
||||
|
||||
/* now parse all patterns */
|
||||
while (**args) {
|
||||
arg = *args;
|
||||
@ -659,7 +662,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
||||
/* Add sample to the reference, and try to compile it fior each pattern
|
||||
* using this value.
|
||||
*/
|
||||
if (!pat_ref_add(ref, arg, NULL, patflags, err))
|
||||
if (!pat_ref_add(ref, arg, NULL, err))
|
||||
goto out_free_expr;
|
||||
args++;
|
||||
}
|
||||
|
@ -2055,9 +2055,9 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
|
||||
/* Add value. */
|
||||
err = NULL;
|
||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
||||
ret = pat_ref_add(appctx->ctx.map.ref, args[3], args[4], 0, &err);
|
||||
ret = pat_ref_add(appctx->ctx.map.ref, args[3], args[4], &err);
|
||||
else
|
||||
ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, 0, &err);
|
||||
ret = pat_ref_add(appctx->ctx.map.ref, args[3], NULL, &err);
|
||||
if (!ret) {
|
||||
if (err)
|
||||
memprintf(&err, "%s.\n", err);
|
||||
@ -5012,6 +5012,12 @@ static int stats_map_lookup(struct stream_interface *si)
|
||||
else
|
||||
chunk_appendf(&trash, "type=%s", pat_match_names[match_method]);
|
||||
|
||||
/* case sensitive */
|
||||
if (appctx->ctx.map.expr->mflags & PAT_MF_IGNORE_CASE)
|
||||
chunk_appendf(&trash, ", case=insensitive");
|
||||
else
|
||||
chunk_appendf(&trash, ", case=sensitive");
|
||||
|
||||
/* Display no match, and set default value */
|
||||
if (!pat) {
|
||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP)
|
||||
@ -5029,17 +5035,11 @@ static int stats_map_lookup(struct stream_interface *si)
|
||||
chunk_appendf(&trash, ", match=yes");
|
||||
|
||||
/* display index mode */
|
||||
if (pat->flags & PAT_F_TREE)
|
||||
if (pat->sflags & PAT_SF_TREE)
|
||||
chunk_appendf(&trash, ", idx=tree");
|
||||
else
|
||||
chunk_appendf(&trash, ", idx=list");
|
||||
|
||||
/* case sensitive */
|
||||
if (pat->flags & PAT_F_IGNORE_CASE)
|
||||
chunk_appendf(&trash, ", case=insensitive");
|
||||
else
|
||||
chunk_appendf(&trash, ", case=sensitive");
|
||||
|
||||
/* display pattern */
|
||||
if (appctx->ctx.map.display_flags == PAT_REF_MAP) {
|
||||
if (pat->ref && pat->ref->pattern)
|
||||
|
@ -153,7 +153,7 @@ static int sample_load_map(struct arg *arg, struct sample_conv *conv,
|
||||
}
|
||||
|
||||
/* Load map. */
|
||||
if (!pattern_read_from_file(&desc->pat, PAT_REF_MAP, arg[0].data.str.str, PAT_F_NO_DNS,
|
||||
if (!pattern_read_from_file(&desc->pat, PAT_REF_MAP, arg[0].data.str.str, PAT_MF_NO_DNS,
|
||||
1, err, file, line))
|
||||
return 0;
|
||||
|
||||
|
@ -41,7 +41,7 @@ char *pat_match_names[PAT_MATCH_NUM] = {
|
||||
[PAT_MATCH_REG] = "reg",
|
||||
};
|
||||
|
||||
int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, char **) = {
|
||||
int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, int, char **) = {
|
||||
[PAT_MATCH_FOUND] = pat_parse_nothing,
|
||||
[PAT_MATCH_BOOL] = pat_parse_nothing,
|
||||
[PAT_MATCH_INT] = pat_parse_int,
|
||||
@ -194,13 +194,13 @@ static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsig
|
||||
*/
|
||||
|
||||
/* ignore the current line */
|
||||
int pat_parse_nothing(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_nothing(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse a string. It is allocated and duplicated. */
|
||||
int pat_parse_str(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_str(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
pattern->type = SMP_T_STR;
|
||||
pattern->ptr.str = (char *)text;
|
||||
@ -209,7 +209,7 @@ int pat_parse_str(const char *text, struct pattern *pattern, char **err)
|
||||
}
|
||||
|
||||
/* Parse a binary written in hexa. It is allocated. */
|
||||
int pat_parse_bin(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_bin(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
struct chunk *trash;
|
||||
|
||||
@ -221,7 +221,7 @@ int pat_parse_bin(const char *text, struct pattern *pattern, char **err)
|
||||
}
|
||||
|
||||
/* Parse a regex. It is allocated. */
|
||||
int pat_parse_reg(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_reg(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
struct chunk *trash;
|
||||
|
||||
@ -252,7 +252,7 @@ int pat_parse_reg(const char *text, struct pattern *pattern, char **err)
|
||||
* non-zero on success.
|
||||
*
|
||||
*/
|
||||
int pat_parse_int(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_int(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
const char *ptr = text;
|
||||
|
||||
@ -337,7 +337,7 @@ int pat_parse_int(const char *text, struct pattern *pattern, char **err)
|
||||
* acl valid_ssl ssl_req_proto 3.0-3.1
|
||||
*
|
||||
*/
|
||||
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_dotted_ver(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
const char *ptr = text;
|
||||
|
||||
@ -404,9 +404,9 @@ int pat_parse_dotted_ver(const char *text, struct pattern *pattern, char **err)
|
||||
* may either be a dotted mask or a number of bits. Returns 1 if OK,
|
||||
* otherwise 0. NOTE: IP address patterns are typed (IPV4/IPV6).
|
||||
*/
|
||||
int pat_parse_ip(const char *text, struct pattern *pattern, char **err)
|
||||
int pat_parse_ip(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
if (str2net(text, !(pattern->flags & PAT_F_NO_DNS) && (global.mode & MODE_STARTING),
|
||||
if (str2net(text, !(mflags & PAT_MF_NO_DNS) && (global.mode & MODE_STARTING),
|
||||
&pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
|
||||
pattern->type = SMP_T_IPV4;
|
||||
return 1;
|
||||
@ -438,7 +438,6 @@ struct pattern *pat_match_nothing(struct sample *smp, struct pattern_expr *expr,
|
||||
if (fill) {
|
||||
static_pattern.smp = NULL;
|
||||
static_pattern.ref = NULL;
|
||||
static_pattern.flags = 0;
|
||||
static_pattern.type = 0;
|
||||
static_pattern.ptr.str = NULL;
|
||||
}
|
||||
@ -474,7 +473,7 @@ struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.smp = elt->smp;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.flags = PAT_F_TREE;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
static_pattern.type = SMP_T_STR;
|
||||
static_pattern.ptr.str = (char *)elt->node.key;
|
||||
}
|
||||
@ -489,7 +488,7 @@ struct pattern *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
|
||||
if (pattern->len != smp->data.str.len)
|
||||
continue;
|
||||
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = expr->mflags & PAT_MF_IGNORE_CASE;
|
||||
if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0) ||
|
||||
(!icase && strncmp(pattern->ptr.str, smp->data.str.str, smp->data.str.len) == 0))
|
||||
return pattern;
|
||||
@ -549,7 +548,7 @@ struct pattern *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int
|
||||
if (pattern->len > smp->data.str.len)
|
||||
continue;
|
||||
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = expr->mflags & PAT_MF_IGNORE_CASE;
|
||||
if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0) ||
|
||||
(!icase && strncmp(pattern->ptr.str, smp->data.str.str, pattern->len) != 0))
|
||||
continue;
|
||||
@ -572,7 +571,7 @@ struct pattern *pat_match_end(struct sample *smp, struct pattern_expr *expr, int
|
||||
if (pattern->len > smp->data.str.len)
|
||||
continue;
|
||||
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = expr->mflags & PAT_MF_IGNORE_CASE;
|
||||
if ((icase && strncasecmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0) ||
|
||||
(!icase && strncmp(pattern->ptr.str, smp->data.str.str + smp->data.str.len - pattern->len, pattern->len) != 0))
|
||||
continue;
|
||||
@ -600,7 +599,7 @@ struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int
|
||||
continue;
|
||||
|
||||
end = smp->data.str.str + smp->data.str.len - pattern->len;
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = expr->mflags & PAT_MF_IGNORE_CASE;
|
||||
if (icase) {
|
||||
for (c = smp->data.str.str; c <= end; c++) {
|
||||
if (tolower(*c) != tolower(*pattern->ptr.str))
|
||||
@ -626,7 +625,7 @@ struct pattern *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int
|
||||
* provided as an unsigned int made by make_4delim() and match up to 4 different
|
||||
* delimiters. Delimiters are stripped at the beginning and end of the pattern.
|
||||
*/
|
||||
static int match_word(struct sample *smp, struct pattern *pattern, unsigned int delimiters)
|
||||
static int match_word(struct sample *smp, struct pattern *pattern, int mflags, unsigned int delimiters)
|
||||
{
|
||||
int may_match, icase;
|
||||
char *c, *end;
|
||||
@ -648,7 +647,7 @@ static int match_word(struct sample *smp, struct pattern *pattern, unsigned int
|
||||
return PAT_NOMATCH;
|
||||
|
||||
may_match = 1;
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = mflags & PAT_MF_IGNORE_CASE;
|
||||
end = smp->data.str.str + smp->data.str.len - pl;
|
||||
for (c = smp->data.str.str; c <= end; c++) {
|
||||
if (is_delimiter(*c, delimiters)) {
|
||||
@ -686,7 +685,7 @@ struct pattern *pat_match_dir(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
if (match_word(smp, pattern, make_4delim('/', '?', '?', '?')))
|
||||
if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '?', '?')))
|
||||
return pattern;
|
||||
}
|
||||
return NULL;
|
||||
@ -703,7 +702,7 @@ struct pattern *pat_match_dom(struct sample *smp, struct pattern_expr *expr, int
|
||||
|
||||
list_for_each_entry(lst, &expr->patterns, list) {
|
||||
pattern = &lst->pat;
|
||||
if (match_word(smp, pattern, make_4delim('/', '?', '.', ':')))
|
||||
if (match_word(smp, pattern, expr->mflags, make_4delim('/', '?', '.', ':')))
|
||||
return pattern;
|
||||
}
|
||||
return NULL;
|
||||
@ -761,7 +760,7 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.smp = elt->smp;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.flags = PAT_F_TREE;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
static_pattern.type = SMP_T_IPV4;
|
||||
memcpy(&static_pattern.val.ipv4.addr.s_addr, elt->node.key, 4);
|
||||
if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
|
||||
@ -783,7 +782,7 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.smp = elt->smp;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.flags = PAT_F_TREE;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
static_pattern.type = SMP_T_IPV6;
|
||||
memcpy(&static_pattern.val.ipv6.addr, elt->node.key, 16);
|
||||
static_pattern.val.ipv6.mask = elt->node.node.pfx;
|
||||
@ -803,7 +802,7 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.smp = elt->smp;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.flags = PAT_F_TREE;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
static_pattern.type = SMP_T_IPV6;
|
||||
memcpy(&static_pattern.val.ipv6.addr, elt->node.key, 16);
|
||||
static_pattern.val.ipv6.mask = elt->node.node.pfx;
|
||||
@ -837,7 +836,7 @@ struct pattern *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
|
||||
elt = ebmb_entry(node, struct pattern_tree, node);
|
||||
static_pattern.smp = elt->smp;
|
||||
static_pattern.ref = elt->ref;
|
||||
static_pattern.flags = PAT_F_TREE;
|
||||
static_pattern.sflags = PAT_SF_TREE;
|
||||
static_pattern.type = SMP_T_IPV4;
|
||||
memcpy(&static_pattern.val.ipv4.addr.s_addr, elt->node.key, 4);
|
||||
if (!cidr2dotted(elt->node.node.pfx, &static_pattern.val.ipv4.mask))
|
||||
@ -1049,7 +1048,7 @@ int pat_idx_list_reg(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||
}
|
||||
|
||||
/* compile regex */
|
||||
if (!regex_comp(pat->ptr.str, patl->pat.ptr.reg, !(patl->pat.flags & PAT_F_IGNORE_CASE), 0, err)) {
|
||||
if (!regex_comp(pat->ptr.str, patl->pat.ptr.reg, !(expr->mflags & PAT_MF_IGNORE_CASE), 0, err)) {
|
||||
free(patl);
|
||||
free(patl->pat.ptr.reg);
|
||||
return 0;
|
||||
@ -1143,7 +1142,7 @@ int pat_idx_tree_str(struct pattern_expr *expr, struct pattern *pat, char **err)
|
||||
}
|
||||
|
||||
/* If the flag PAT_F_IGNORE_CASE is set, we cannot use trees */
|
||||
if (pat->flags & PAT_F_IGNORE_CASE)
|
||||
if (expr->mflags & PAT_MF_IGNORE_CASE)
|
||||
return pat_idx_list_str(expr, pat, err);
|
||||
|
||||
/* Process the key len */
|
||||
@ -1670,12 +1669,11 @@ int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr,
|
||||
|
||||
/* initialise pattern */
|
||||
memset(&pattern, 0, sizeof(pattern));
|
||||
pattern.flags = patflags;
|
||||
pattern.smp = smp;
|
||||
pattern.ref = elt;
|
||||
|
||||
/* parse pattern */
|
||||
if (!expr->pat_head->parse(elt->pattern, &pattern, err)) {
|
||||
if (!expr->pat_head->parse(elt->pattern, &pattern, expr->mflags, err)) {
|
||||
free(smp);
|
||||
return 0;
|
||||
}
|
||||
@ -1697,7 +1695,7 @@ int pat_ref_push(struct pat_ref_elt *elt, struct pattern_expr *expr,
|
||||
*/
|
||||
int pat_ref_add(struct pat_ref *ref,
|
||||
const char *pattern, const char *sample,
|
||||
int patflags, char **err)
|
||||
char **err)
|
||||
{
|
||||
struct pat_ref_elt *elt;
|
||||
struct pattern_expr *expr;
|
||||
@ -1732,7 +1730,7 @@ int pat_ref_add(struct pat_ref *ref,
|
||||
LIST_ADDQ(&ref->head, &elt->list);
|
||||
|
||||
list_for_each_entry(expr, &ref->pat, list) {
|
||||
if (!pat_ref_push(elt, expr, patflags, err)) {
|
||||
if (!pat_ref_push(elt, expr, 0, err)) {
|
||||
/* If the insertion fails, try to delete all the added entries. */
|
||||
pat_ref_delete_by_id(ref, elt);
|
||||
return 0;
|
||||
@ -2108,10 +2106,11 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
||||
* doesn't exists, create it.
|
||||
*/
|
||||
expr = pattern_lookup_expr(head, ref);
|
||||
if (!expr) {
|
||||
if (!expr || (expr->mflags != patflags)) {
|
||||
expr = pattern_new_expr(head, ref, err);
|
||||
if (!expr)
|
||||
return 0;
|
||||
expr->mflags = patflags;
|
||||
}
|
||||
|
||||
/* Load reference content in the pattern expression. */
|
||||
@ -2142,7 +2141,7 @@ struct pattern *pattern_exec_match(struct pattern_head *head, struct sample *smp
|
||||
if (fill) {
|
||||
static_pattern.smp = NULL;
|
||||
static_pattern.ref = NULL;
|
||||
static_pattern.flags = 0;
|
||||
static_pattern.sflags = 0;
|
||||
static_pattern.type = SMP_T_UINT;
|
||||
static_pattern.val.i = 1;
|
||||
}
|
||||
|
@ -3260,7 +3260,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
/* perform update */
|
||||
/* add entry only if it does not already exist */
|
||||
if (pat_ref_find_elt(ref, key) == NULL)
|
||||
pat_ref_add(ref, key, NULL, 0, NULL);
|
||||
pat_ref_add(ref, key, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -3295,7 +3295,7 @@ http_req_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
pat_ref_set(ref, key, value, NULL);
|
||||
else
|
||||
/* insert a new entry */
|
||||
pat_ref_add(ref, key, value, 0, NULL);
|
||||
pat_ref_add(ref, key, value, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -3441,7 +3441,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
/* perform update */
|
||||
/* check if the entry already exists */
|
||||
if (pat_ref_find_elt(ref, key) == NULL)
|
||||
pat_ref_add(ref, key, NULL, 0, NULL);
|
||||
pat_ref_add(ref, key, NULL, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -3476,7 +3476,7 @@ http_res_get_intercept_rule(struct proxy *px, struct list *rules, struct session
|
||||
pat_ref_set(ref, key, value, NULL);
|
||||
else
|
||||
/* insert a new entry */
|
||||
pat_ref_add(ref, key, value, 0, NULL);
|
||||
pat_ref_add(ref, key, value, NULL);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -9590,7 +9590,7 @@ smp_prefetch_http(struct proxy *px, struct session *s, void *l7, unsigned int op
|
||||
* We use the pre-parsed method if it is known, and store its number as an
|
||||
* integer. If it is unknown, we use the pointer and the length.
|
||||
*/
|
||||
static int pat_parse_meth(const char *text, struct pattern *pattern, char **err)
|
||||
static int pat_parse_meth(const char *text, struct pattern *pattern, int mflags, char **err)
|
||||
{
|
||||
int len, meth;
|
||||
struct chunk *trash;
|
||||
@ -9670,7 +9670,7 @@ static struct pattern *pat_match_meth(struct sample *smp, struct pattern_expr *e
|
||||
if (pattern->len != smp->data.meth.str.len)
|
||||
continue;
|
||||
|
||||
icase = pattern->flags & PAT_F_IGNORE_CASE;
|
||||
icase = expr->mflags & PAT_MF_IGNORE_CASE;
|
||||
if ((icase && strncasecmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) != 0) ||
|
||||
(!icase && strncmp(pattern->ptr.str, smp->data.meth.str.str, smp->data.meth.str.len) != 0))
|
||||
return pattern;
|
||||
|
Loading…
Reference in New Issue
Block a user