BUG/MEDIUM: acl: correctly compute the output type when a converter is used

Sample expressions involving converters in expression simply do not work
if the converter changes the sample type from the original keyword. Either
the keyword is a sample fetch keyword and its own type is used, or it's an
ACL keyword, and the keyword's parse/index/match functions are used despite
the converters. Thus it causes such a stupid error :

     redirect location / if { date,ltime(%a) -i Fri }

[ALERT] 240/171746 (29127) : parsing [bug-conv.cfg:35] : error detected in proxy 'svc' while parsing redirect rule : error in condition: 'Fri' is not a number.

In fact now in ACLs, the case where the ACL keyword is alone is an exception
(eventhough the most common one). It's an exception to the sample expression
parsing rules since ACLs allow to redefine alternate parsing functions.

This fix does two things :
  - it voids any references to the ACL keyword when a converter is involved
    since we certainly not want to enforce a parser for a wrong data type ;
  - it ensures that for all other cases (sample expressions), the type of
    the expression is used instead of the type of the fetch keyword.

A significant cleanup of the code should be done, but this patch only aims
fixing the bug.

The fix should be backported into 1.5 since this appeared along the redesign
of the acl/pattern processing.
(cherry picked from commit 6f0ddca67a0d261886d4e665c241e80243186be0)
diff --git a/src/acl.c b/src/acl.c
index 69da28d..3e04874 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -161,6 +161,7 @@
 	struct pat_ref *ref;
 	struct pattern_expr *pattern_expr;
 	int load_as_map = 0;
+	int acl_conv_found = 0;
 
 	/* First, we look for an ACL keyword. And if we don't find one, then
 	 * we look for a sample fetch expression starting with a sample fetch
@@ -229,6 +230,10 @@
 
 		/* look for the begining of the converters list. Those directly attached
 		 * to the ACL keyword are found just after <arg> which points to the comma.
+		 * If we find any converter, then we don't use the ACL keyword's match
+		 * anymore but the one related to the converter's output type, so we'll
+		 * kill the ACL kw to avoid any future reference to it (since in fact we'll
+		 * only be using it as a sample fetch function).
 		 */
 		prev_type = smp->fetch->out_type;
 		while (*arg) {
@@ -302,6 +307,7 @@
 
 			LIST_ADDQ(&(smp->conv_exprs), &(conv_expr->list));
 			conv_expr->conv = conv;
+			acl_conv_found = 1;
 
 			if (arg != endw) {
 				int err_arg;
@@ -347,8 +353,15 @@
 			memprintf(err, "%s in ACL expression '%s'", *err, *args);
 			goto out_return;
 		}
+		prev_type = smp_expr_output_type(smp);
 	}
 
+	/* From now on, prev_type is the expression's output type.
+	 * Stop relying on ACL keyword if a converter is used.
+	 */
+	if (acl_conv_found)
+		aclkw = NULL;
+
 	expr = (struct acl_expr *)calloc(1, sizeof(*expr));
 	if (!expr) {
 		memprintf(err, "out of memory when parsing ACL expression");
@@ -363,7 +376,7 @@
 	expr->pat.match = aclkw ? aclkw->match : NULL;
 	expr->pat.delete = aclkw ? aclkw->delete : NULL;
 	expr->pat.prune = aclkw ? aclkw->prune : NULL;
-	expr->pat.expect_type = smp->fetch->out_type;
+	expr->pat.expect_type = prev_type;
 	expr->smp = smp;
 	smp = NULL;
 
@@ -388,7 +401,7 @@
 	if (!expr->pat.parse) {
 		/* some types can be automatically converted */
 
-		switch (expr->smp ? expr->smp->fetch->out_type : aclkw->smp->out_type) {
+		switch (prev_type) {
 		case SMP_T_BOOL:
 			expr->pat.parse = pat_parse_fcts[PAT_MATCH_BOOL];
 			expr->pat.index = pat_index_fcts[PAT_MATCH_BOOL];