From: Willy Tarreau Date: Wed, 25 Apr 2012 15:21:49 +0000 (+0200) Subject: MEDIUM: pattern: ensure that sample types always cast into other types. X-Git-Tag: v1.5-dev9~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12e5011a765e2e65090d3b27c1ecb4a8650f0a5d;p=thirdparty%2Fhaproxy.git MEDIUM: pattern: ensure that sample types always cast into other types. We want to ensure that a dynamically returned type will always have a cast before calling the cast function. This is done in pattern_process() and in stktable_fetch_key(). --- diff --git a/src/pattern.c b/src/pattern.c index f6afb9700c..2820cf60d6 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -487,9 +487,21 @@ struct sample *pattern_process(struct proxy *px, struct session *l4, void *l7, return NULL; list_for_each_entry(conv_expr, &expr->conv_exprs, list) { - if (!pattern_casts[p->type][conv_expr->conv->in_type](p)) + /* we want to ensure that p->type can be casted into + * conv_expr->conv->in_type. We have 3 possibilities : + * - NULL => not castable. + * - c_none => nothing to do (let's optimize it) + * - other => apply cast and prepare to fail + */ + if (!pattern_casts[p->type][conv_expr->conv->in_type]) return NULL; + if (pattern_casts[p->type][conv_expr->conv->in_type] != c_none && + !pattern_casts[p->type][conv_expr->conv->in_type](p)) + return NULL; + + /* OK cast succeeded */ + /* force the output type after a cast */ p->type = conv_expr->conv->in_type; if (!conv_expr->conv->process(conv_expr->arg_p, p)) diff --git a/src/stick_table.c b/src/stick_table.c index 7bff124e99..a6ae3a2979 100644 --- a/src/stick_table.c +++ b/src/stick_table.c @@ -600,6 +600,9 @@ struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, st if (!smp) return NULL; + if (!pattern_to_key[smp->type][t->type]) + return NULL; + static_table_key.key_len = t->key_size; static_table_key.key = pattern_to_key[smp->type][t->type](smp, &static_table_key.data, &static_table_key.key_len);