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.
This commit is contained in:
Thierry FOURNIER 2014-01-27 14:19:53 +01:00 committed by Willy Tarreau
parent c5959fd5d4
commit 5d34408785
7 changed files with 14 additions and 67 deletions

View File

@ -125,9 +125,6 @@ int pat_parse_nothing(const char *text, struct pattern *pattern, 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);
/* 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);

View File

@ -135,7 +135,6 @@ struct pattern_tree {
*/
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 pattern_head {
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. */
};

View File

@ -358,6 +358,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
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 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
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 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
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 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
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 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
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] == '-') {

View File

@ -4823,7 +4823,8 @@ static int stats_map_lookup(struct stream_interface *si)
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;

View File

@ -258,6 +258,7 @@ static int sample_load_map(struct arg *arg, struct sample_conv *conv, char **err
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) {

View File

@ -46,7 +46,7 @@ int (*pat_parse_fcts[PAT_MATCH_NUM])(const char *, struct pattern *, char **) =
[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_nothing(const char *text, struct pattern *pattern, char **err)
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 @@ int pat_parse_bin(const char *text, struct pattern *pattern, char **err)
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 @@ int pat_parse_reg(const char *text, struct pattern *pattern, char **err)
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 @@ int pat_parse_int(const char *text, struct pattern *pattern, char **err)
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 @@ int pat_parse_int(const char *text, struct pattern *pattern, char **err)
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 @@ int pat_parse_dotted_ver(const char *text, struct pattern *pattern, char **err)
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_dotted_ver(const char *text, struct pattern *pattern, char **err)
*/
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 *pat_match_str(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_bin(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_reg(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_beg(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_end(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_sub(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_dir(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_dom(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_int(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_len(struct sample *smp, struct pattern_expr *expr, int
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 *pat_match_ip(struct sample *smp, struct pattern_expr *expr, int
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 @@ struct pattern *pattern_exec_match(struct pattern_head *head, struct sample *smp
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)

View File

@ -9002,13 +9002,11 @@ static int pat_parse_meth(const char *text, struct pattern *pattern, char **err)
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;
}