bugfix: in (non)equal comparisons the position of arrays influenced result

This behaviour is OK for "contains"-type of comparisons (which have quite
different semantics), but not for == and <>, which shall be commutative.
This has been fixed now, so there is no difference any longer if the
constant string array is the left or right hand operand. We solved this
via the optimizer, as it keeps the actual script execution code small.
This commit is contained in:
Rainer Gerhards 2012-10-09 15:24:04 +02:00
parent f4f55b6b9d
commit 431932d8d6
2 changed files with 22 additions and 1 deletions

View File

@ -1,6 +1,12 @@
---------------------------------------------------------------------------
Version 7.1.9 [beta] 2012-10-??
- bugfix: comments inside objects (e.g. action()) were not properly handled
- bugfix: in (non)equa comparisons the position of arrays influenced result
This behaviour is OK for "contains"-type of comparisons (which have quite
different semantics), but not for == and <>, which shall be commutative.
This has been fixed now, so there is no difference any longer if the
constant string array is the left or right hand operand. We solved this
via the optimizer, as it keeps the actual script execution code small.
---------------------------------------------------------------------------
Version 7.1.8 [beta] 2012-10-02
- bugfix: ruleset(){} directive errornously changed default ruleset

View File

@ -1173,6 +1173,8 @@ evalVar(struct cnfvar *var, void *usrptr, struct var *ret)
* that one one comparison is true, the whole construct is true.
* TODO: we can obviously optimize this process. One idea is to
* compile a regex, which should work faster than serial comparison.
* Note: compiling a regex does NOT work at all. I experimented with that
* and it was generally 5 to 10 times SLOWER than what we do here...
*/
static int
evalStrArrayCmp(es_str_t *estr_l, struct cnfarray* ar, int cmpop)
@ -1756,7 +1758,6 @@ cnfexprPrint(struct cnfexpr *expr, int indent)
struct cnffunc *func;
int i;
dbgprintf("expr %p, indent %d, type '%c'\n", expr, indent, expr->nodetype);
switch(expr->nodetype) {
case CMP_EQ:
cnfexprPrint(expr->l, indent+1);
@ -2322,6 +2323,7 @@ void
cnfexprOptimize(struct cnfexpr *expr)
{
long long ln, rn;
struct cnfexpr *exprswap;
dbgprintf("optimize expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
switch(expr->nodetype) {
@ -2358,6 +2360,19 @@ cnfexprOptimize(struct cnfexpr *expr)
((struct cnfnumval*)expr)->val = ln % rn;
}
break;
case CMP_NE:
case CMP_EQ:
if(expr->l->nodetype == 'A') {
if(expr->r->nodetype == 'A') {
parser_errmsg("warning: '==' or '<>' "
"comparison of two constant string "
"arrays makes no sense");
} else { /* swap for simpler execution step */
exprswap = expr->l;
expr->l = expr->r;
expr->r = exprswap;
}
}
default:/* nodetype we cannot optimize */
break;
}