diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2012-06-14 18:18:53 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2012-06-14 18:18:53 +0200 |
commit | 488d0aaaa2a6d55e016d6b5b097cb3e20e49e191 (patch) | |
tree | 41bfe0b9e03f22bcba3d19a40dba1a6477034b95 /grammar/rainerscript.c | |
parent | ba00396eee5b8f8717639da396b010631ad5baa7 (diff) | |
download | rsyslog-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/rainerscript.c')
-rw-r--r-- | grammar/rainerscript.c | 74 |
1 files changed, 74 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. |