summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2012-06-14 18:18:53 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2012-06-14 18:18:53 +0200
commit488d0aaaa2a6d55e016d6b5b097cb3e20e49e191 (patch)
tree41bfe0b9e03f22bcba3d19a40dba1a6477034b95 /grammar
parentba00396eee5b8f8717639da396b010631ad5baa7 (diff)
downloadrsyslog-488d0aaaa2a6d55e016d6b5b097cb3e20e49e191.tar.gz
rsyslog-488d0aaaa2a6d55e016d6b5b097cb3e20e49e191.tar.xz
rsyslog-488d0aaaa2a6d55e016d6b5b097cb3e20e49e191.zip
fixing memory leaks in expression-based filters
most recently added by re_match() function
Diffstat (limited to 'grammar')
-rw-r--r--grammar/rainerscript.c74
-rw-r--r--grammar/rainerscript.h1
2 files changed, 75 insertions, 0 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 2f7057c5..be8272b4 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -821,6 +821,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
es_tolower(estr);
ret->datatype = 'S';
ret->d.estr = estr;
+ if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
break;
case CNFFUNC_CSTR:
cnfexprEval(func->expr[0], &r[0], usrptr);
@@ -829,6 +830,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
estr = es_strdup(estr);
ret->datatype = 'S';
ret->d.estr = estr;
+ if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
break;
case CNFFUNC_CNUM:
if(func->expr[0]->nodetype == 'N') {
@@ -859,6 +861,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
ret->datatype = 'N';
if(bMustFree) es_deleteStr(estr);
free(str);
+ if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
break;
default:
if(Debug) {
@@ -1221,6 +1224,77 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
}
}
+//---------------------------------------------------------
+
+static inline void
+cnffuncDestruct(struct cnffunc *func)
+{
+ unsigned short i;
+
+ for(i = 0 ; i < func->nParams ; ++i) {
+ cnfexprDestruct(func->expr[i]);
+ }
+ /* some functions require special destruction */
+ switch(func->fID) {
+ case CNFFUNC_RE_MATCH:
+ regexp.regfree(func->funcdata);
+ free(func->funcdata);
+ break;
+ default:break;
+ }
+}
+
+/* Destruct an expression and all sub-expressions contained in it.
+ */
+void
+cnfexprDestruct(struct cnfexpr *expr)
+{
+
+ dbgprintf("cnfexprDestruct expr %p, type '%c'(%u)\n", expr, expr->nodetype, expr->nodetype);
+ switch(expr->nodetype) {
+ case CMP_NE:
+ case CMP_EQ:
+ case CMP_LE:
+ case CMP_GE:
+ case CMP_LT:
+ case CMP_GT:
+ case CMP_STARTSWITH:
+ case CMP_STARTSWITHI:
+ case CMP_CONTAINS:
+ case CMP_CONTAINSI:
+ case OR:
+ case AND:
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%': /* binary */
+ cnfexprDestruct(expr->l);
+ cnfexprDestruct(expr->r);
+ break;
+ case NOT:
+ case 'M': /* unary */
+ cnfexprDestruct(expr->r);
+ break;
+ case 'N':
+ break;
+ case 'S':
+ es_deleteStr(((struct cnfstringval*)expr)->estr);
+ break;
+ case 'V':
+ free(((struct cnfvar*)expr)->name);
+ break;
+ case 'F':
+ cnffuncDestruct((struct cnffunc*)expr);
+ break;
+ default:break;
+ }
+ free(expr);
+}
+
+//---- END
+
+
/* Evaluate an expression as a bool. This is added because expressions are
* mostly used inside filters, and so this function is quite common and
* important.
diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h
index b8d6e772..5ff71bee 100644
--- a/grammar/rainerscript.h
+++ b/grammar/rainerscript.h
@@ -235,6 +235,7 @@ struct cnfexpr* cnfexprNew(unsigned nodetype, struct cnfexpr *l, struct cnfexpr
void cnfexprPrint(struct cnfexpr *expr, int indent);
void cnfexprEval(struct cnfexpr *expr, struct var *ret, void *pusr);
int cnfexprEvalBool(struct cnfexpr *expr, void *usrptr);
+void cnfexprDestruct(struct cnfexpr *expr);
struct cnfnumval* cnfnumvalNew(long long val);
struct cnfstringval* cnfstringvalNew(es_str_t *estr);
struct cnfrule * cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst);