MEDIUM: pattern: The expected type is stored in the pattern head, and conversion is executed once.
This patch extract the expect_type variable from the "struct pattern" to
"struct pattern_head". This variable is set during the declaration of
ACL and MAP. With this change, the function "pat_parse_len()" become
useless and can be replaced by "pat_parse_int()".
Implicit ACLs by default rely on the fetch's output type, so let's simply do
the same for all other ones. It has been verified that they all match.
diff --git a/include/proto/pattern.h b/include/proto/pattern.h
index a019730..9b7c40e 100644
--- a/include/proto/pattern.h
+++ b/include/proto/pattern.h
@@ -125,9 +125,6 @@
/* Parse an integer. It is put both in min and max. */
int pat_parse_int(const char *text, struct pattern *pattern, char **err);
-/* Parse len like an integer, but specify expected string type */
-int pat_parse_len(const char *text, struct pattern *pattern, 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);
diff --git a/include/types/pattern.h b/include/types/pattern.h
index 7973bce..dfee109 100644
--- a/include/types/pattern.h
+++ b/include/types/pattern.h
@@ -135,7 +135,6 @@
*/
struct pattern {
int type; /* type of the ACL pattern (SMP_T_*) */
- int expect_type; /* type of the expected sample (SMP_T_*) */
union {
int i; /* integer value */
struct {
@@ -209,6 +208,7 @@
struct sample_storage **(*find_smp)(struct pattern_expr *, struct pattern *);
void (*prune)(struct pattern_expr *);
struct pattern *(*match)(struct sample *, struct pattern_expr *, int);
+ int expect_type; /* type of the expected sample (SMP_T_*) */
struct list head; /* This is a list of struct pattern_expr_list. */
};
diff --git a/src/acl.c b/src/acl.c
index fa54ab9..d4d1cfb 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -358,6 +358,7 @@
expr->pat.delete = aclkw ? aclkw->delete : NULL;
expr->pat.prune = aclkw ? aclkw->prune : NULL;
expr->pat.find_smp = aclkw ? aclkw->find_smp : NULL;
+ expr->pat.expect_type = smp->fetch->out_type;
expr->smp = smp;
smp = NULL;
@@ -372,6 +373,7 @@
expr->pat.delete = pat_delete_fcts[PAT_MATCH_BOOL];
expr->pat.prune = pat_prune_fcts[PAT_MATCH_BOOL];
expr->pat.find_smp = pat_find_smp_fcts[PAT_MATCH_BOOL];
+ expr->pat.expect_type = pat_match_types[PAT_MATCH_BOOL];
break;
case SMP_T_SINT:
case SMP_T_UINT:
@@ -381,6 +383,7 @@
expr->pat.delete = pat_delete_fcts[PAT_MATCH_INT];
expr->pat.prune = pat_prune_fcts[PAT_MATCH_INT];
expr->pat.find_smp = pat_find_smp_fcts[PAT_MATCH_INT];
+ expr->pat.expect_type = pat_match_types[PAT_MATCH_INT];
break;
case SMP_T_IPV4:
case SMP_T_IPV6:
@@ -390,6 +393,7 @@
expr->pat.delete = pat_delete_fcts[PAT_MATCH_IP];
expr->pat.prune = pat_prune_fcts[PAT_MATCH_IP];
expr->pat.find_smp = pat_find_smp_fcts[PAT_MATCH_IP];
+ expr->pat.expect_type = pat_match_types[PAT_MATCH_IP];
break;
}
}
@@ -455,6 +459,7 @@
expr->pat.delete = pat_delete_fcts[idx];
expr->pat.prune = pat_prune_fcts[idx];
expr->pat.find_smp = pat_find_smp_fcts[idx];
+ expr->pat.expect_type = pat_match_types[idx];
args++;
}
else if ((*args)[1] == '-') {
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 13bf201..57a9fc5 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -4823,7 +4823,8 @@
sample.flags |= SMP_F_CONST;
sample.data.str.len = appctx->ctx.map.chunk.len;
sample.data.str.str = appctx->ctx.map.chunk.str;
- if (appctx->ctx.map.expr->pat_head->match)
+ if (appctx->ctx.map.expr->pat_head->match &&
+ sample_convert(&sample, appctx->ctx.map.expr->pat_head->expect_type))
pat = appctx->ctx.map.expr->pat_head->match(&sample, appctx->ctx.map.expr, 1);
else
pat = NULL;
diff --git a/src/map.c b/src/map.c
index 064c52e..fced0ed 100644
--- a/src/map.c
+++ b/src/map.c
@@ -258,6 +258,7 @@
desc->pat.delete = pat_delete_fcts[conv->private];
desc->pat.prune = pat_prune_fcts[conv->private];
desc->pat.find_smp = pat_find_smp_fcts[conv->private];
+ desc->pat.expect_type = pat_match_types[conv->private];
/* Set the output parse method. */
switch (desc->conv->out_type) {
diff --git a/src/pattern.c b/src/pattern.c
index 3d87a47..e35a59d 100644
--- a/src/pattern.c
+++ b/src/pattern.c
@@ -46,7 +46,7 @@
[PAT_MATCH_INT] = pat_parse_int,
[PAT_MATCH_IP] = pat_parse_ip,
[PAT_MATCH_BIN] = pat_parse_bin,
- [PAT_MATCH_LEN] = pat_parse_len,
+ [PAT_MATCH_LEN] = pat_parse_int,
[PAT_MATCH_STR] = pat_parse_str,
[PAT_MATCH_BEG] = pat_parse_str,
[PAT_MATCH_SUB] = pat_parse_str,
@@ -219,7 +219,6 @@
int pat_parse_str(const char *text, struct pattern *pattern, char **err)
{
pattern->type = SMP_T_STR;
- pattern->expect_type = SMP_T_STR;
pattern->ptr.str = (char *)text;
pattern->len = strlen(text);
return 1;
@@ -231,7 +230,6 @@
struct chunk *trash;
pattern->type = SMP_T_BIN;
- pattern->expect_type = SMP_T_BIN;
trash = get_trash_chunk();
pattern->len = trash->size;
pattern->ptr.str = trash->str;
@@ -253,7 +251,6 @@
pattern->ptr.reg = (struct my_regex *)trash->str;
pattern->ptr.reg->regstr = (char *)text;
- pattern->expect_type = SMP_T_STR;
return 1;
}
@@ -277,7 +274,6 @@
const char *ptr = text;
pattern->type = SMP_T_UINT;
- pattern->expect_type = SMP_T_UINT;
/* Empty string is not valid */
if (!*text)
@@ -338,15 +334,6 @@
return 0;
}
-int pat_parse_len(const char *text, struct pattern *pattern, char **err)
-{
- int ret;
-
- ret = pat_parse_int(text, pattern, err);
- pattern->expect_type = SMP_T_STR;
- return ret;
-}
-
/* Parse a range of positive 2-component versions delimited by either ':' or
* '-'. The version consists in a major and a minor, both of which must be
* smaller than 65536, because internally they will be represented as a 32-bit
@@ -372,7 +359,6 @@
const char *ptr = text;
pattern->type = SMP_T_UINT;
- pattern->expect_type = SMP_T_UINT;
/* Search ':' or '-' separator. */
while (*ptr != '\0' && *ptr != ':' && *ptr != '-')
@@ -437,7 +423,6 @@
*/
int pat_parse_ip(const char *text, struct pattern *pattern, char **err)
{
- pattern->expect_type = SMP_T_ADDR;
if (str2net(text, &pattern->val.ipv4.addr, &pattern->val.ipv4.mask)) {
pattern->type = SMP_T_IPV4;
return 1;
@@ -479,10 +464,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
/* Lookup a string in the expression's pattern tree. */
if (!eb_is_empty(&expr->pattern_tree)) {
/* we may have to force a trailing zero on the test pattern */
@@ -527,10 +508,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* Convert input to binary. */
- if (!sample_convert(smp, SMP_T_BIN))
- return NULL;
-
/* Look in the list. */
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
@@ -553,10 +530,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
/* look in the list */
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
@@ -574,10 +547,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
@@ -601,10 +570,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
@@ -632,10 +597,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
@@ -727,10 +688,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
if (match_word(smp, pattern, make_4delim('/', '?', '?', '?')))
@@ -748,10 +705,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
if (match_word(smp, pattern, make_4delim('/', '?', '.', ':')))
@@ -766,10 +719,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to integer */
- if (!sample_convert(smp, SMP_T_UINT))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.uint) &&
@@ -785,10 +734,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to string */
- if (!sample_convert(smp, SMP_T_STR))
- return NULL;
-
list_for_each_entry(lst, &expr->patterns, list) {
pattern = &lst->pat;
if ((!pattern->val.range.min_set || pattern->val.range.min <= smp->data.str.len) &&
@@ -808,10 +753,6 @@
struct pattern_list *lst;
struct pattern *pattern;
- /* convert input to addr */
- if (!sample_convert(smp, SMP_T_ADDR))
- return NULL;
-
/* The input sample is IPv4. Try to match in the trees. */
if (smp->type == SMP_T_IPV4) {
/* Lookup an IPv4 address in the expression's pattern tree using
@@ -2174,6 +2115,10 @@
return &static_pattern;
}
+ /* convert input to string */
+ if (!sample_convert(smp, head->expect_type))
+ return NULL;
+
list_for_each_entry(list, &head->head, list) {
pat = head->match(smp, list->expr, fill);
if (pat)
diff --git a/src/proto_http.c b/src/proto_http.c
index bd7bfff..feaf475 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -9002,13 +9002,11 @@
return 0;
}
pattern->ptr.str = trash->str;
- pattern->expect_type = SMP_T_STR;
pattern->len = len;
}
else {
pattern->ptr.str = NULL;
pattern->len = 0;
- pattern->expect_type = SMP_T_UINT;
}
return 1;
}