]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: patterns: last fix was still not enough
authorThierry FOURNIER <tfournier@exceliance.fr>
Mon, 28 Apr 2014 09:18:57 +0000 (11:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 28 Apr 2014 12:19:17 +0000 (14:19 +0200)
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.

include/proto/pattern.h
include/types/acl.h
include/types/pattern.h
src/acl.c
src/dumpstats.c
src/map.c
src/pattern.c
src/proto_http.c

index 22da6d5e8092b14cac1fa9573cd92c839a765c7f..40e87b8a61b568f3b09b43e5a48a682ec2f9b839 100644 (file)
@@ -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);
index c5c2824ecd3fcefa30f2b75f5695cd8f68c85722..80b2c39a6978c6912a4f82162d6336a07b6b4bd8 100644 (file)
@@ -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);
index a20d6d3896d5098d0adac4410e13627903fa22df..492cdd3a3d9debfb42c2bc72f7ad8b3f3e1ba7c1 100644 (file)
@@ -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 *);
index 93cf31cd5c8275cee6969d26f0c6f26a434188d8..10632a7a1744841fb72267e97d6371b1d062a69f 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -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++;
        }
index 7cf4d84cf7e9a9ad272e9b21afb83e49d6c69648..5222534cffe8c646fc5c36d40e637ca252a97953 100644 (file)
@@ -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)
index 570937c5a9b84da1bd0551481aed2c7b6d606624..a4fd54b0ed39f622c224b7ffa9905ffa08ecee7f 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -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;
 
index e741b20d031030f65bad828b660b915e2088edfc..80dbaab91879c7dec478244d9eec99377146021f 100644 (file)
@@ -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;
                }
index b7f6edff81baa3e4bf4f62ee78f7593d4d3778a2..27693ac083ee7085d6e27dc8bcb55fa6ec8ea4c0 100644 (file)
@@ -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;