summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-10-09 15:24:04 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-10-09 15:24:04 +0200
commit431932d8d63a0f85694c1ec5ec43435a048ffff7 (patch)
treedfdbc3c6df8d48cab801d2eeb89ff2cea73ab6bf /grammar
parentf4f55b6b9d0026d9303978897a8af9c4b72a88bb (diff)
downloadrsyslog-431932d8d63a0f85694c1ec5ec43435a048ffff7.tar.gz
rsyslog-431932d8d63a0f85694c1ec5ec43435a048ffff7.tar.xz
rsyslog-431932d8d63a0f85694c1ec5ec43435a048ffff7.zip
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.
Diffstat (limited to 'grammar')
-rw-r--r--grammar/rainerscript.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 7e75326c..ad6a32e8 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -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;
}