summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-10-25 15:48:23 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-10-25 15:48:23 +0200
commit376c4bd8435d10ac8ad38c61fb26047d98b0f107 (patch)
treea05231e8a0893cf2574743fd130e3fbad248de87 /grammar
parent288b0ad2aab4f8763b68771515e74ee3e7f0bd9d (diff)
parenta3d2ad0addf961abad0b9bc98427d72035347ea0 (diff)
downloadrsyslog-376c4bd8435d10ac8ad38c61fb26047d98b0f107.tar.gz
rsyslog-376c4bd8435d10ac8ad38c61fb26047d98b0f107.tar.bz2
rsyslog-376c4bd8435d10ac8ad38c61fb26047d98b0f107.zip
Merge branch 'v7-stable-varfree' into master-var-refactor
Diffstat (limited to 'grammar')
-rw-r--r--grammar/rainerscript.c72
1 files changed, 45 insertions, 27 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c
index 3295c9c0..f49d2aa1 100644
--- a/grammar/rainerscript.c
+++ b/grammar/rainerscript.c
@@ -1243,6 +1243,23 @@ var2CString(struct var *r, int *bMustFree)
return cstr;
}
+/* frees struct var members, but not the struct itself. This is because
+ * it usually is allocated on the stack. Callers why dynamically allocate
+ * struct var need to free the struct themselfes!
+ */
+static void
+varFreeMembers(struct var *r)
+{
+ /* Note: we do NOT need to free JSON objects, as we use
+ * json_object_object_get() to obtain the values, which does not
+ * increment the reference count. So json_object_put() [free] is
+ * neither required nor permitted (would free the original object!).
+ * So for the time being the string data type is the only one that
+ * we currently need to free.
+ */
+ if(r->datatype == 'S') es_deleteStr(r->d.estr);
+}
+
static rsRetVal
doExtractFieldByChar(uchar *str, uchar delim, int matchnbr, uchar **resstr)
{
@@ -1360,7 +1377,7 @@ doFunc_re_extract(struct cnffunc *func, struct var *ret, void* usrptr)
str = (char*) var2CString(&r[0], &bMustFree);
matchnbr = (short) var2Number(&r[2], NULL);
submatchnbr = (size_t) var2Number(&r[3], NULL);
- if(submatchnbr > sizeof(pmatch)/sizeof(regmatch_t)) {
+ if(submatchnbr >= sizeof(pmatch)/sizeof(regmatch_t)) {
DBGPRINTF("re_extract() submatch %d is too large\n", submatchnbr);
bHadNoMatch = 1;
goto finalize_it;
@@ -1408,11 +1425,12 @@ doFunc_re_extract(struct cnffunc *func, struct var *ret, void* usrptr)
iLenBuf);
}
- if(bMustFree) free(str);
- if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
- if(r[2].datatype == 'S') es_deleteStr(r[2].d.estr);
- if(r[3].datatype == 'S') es_deleteStr(r[3].d.estr);
finalize_it:
+ if(bMustFree) free(str);
+ varFreeMembers(&r[0]);
+ varFreeMembers(&r[2]);
+ varFreeMembers(&r[3]);
+
if(bHadNoMatch) {
cnfexprEval(func->expr[4], &r[4], usrptr);
estr = var2String(&r[4], &bMustFree);
@@ -1479,7 +1497,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
}
ret->datatype = 'S';
if(bMustFree) es_deleteStr(estr);
- if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
+ varFreeMembers(&r[0]);
free(str);
break;
case CNFFUNC_TOLOWER:
@@ -1490,7 +1508,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);
+ varFreeMembers(&r[0]);
break;
case CNFFUNC_CSTR:
cnfexprEval(func->expr[0], &r[0], usrptr);
@@ -1499,7 +1517,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);
+ varFreeMembers(&r[0]);
break;
case CNFFUNC_CNUM:
if(func->expr[0]->nodetype == 'N') {
@@ -1510,7 +1528,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
} else {
cnfexprEval(func->expr[0], &r[0], usrptr);
ret->d.n = var2Number(&r[0], NULL);
- if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
+ varFreeMembers(&r[0]);
}
ret->datatype = 'N';
break;
@@ -1528,7 +1546,7 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
}
ret->datatype = 'N';
if(bMustFree) free(str);
- if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
+ varFreeMembers(&r[0]);
break;
case CNFFUNC_RE_EXTRACT:
doFunc_re_extract(func, ret, usrptr);
@@ -1561,9 +1579,9 @@ doFuncCall(struct cnffunc *func, struct var *ret, void* usrptr)
}
ret->datatype = 'S';
if(bMustFree) free(str);
- if(r[0].datatype == 'S') es_deleteStr(r[0].d.estr);
- if(r[1].datatype == 'S') es_deleteStr(r[1].d.estr);
- if(r[2].datatype == 'S') es_deleteStr(r[2].d.estr);
+ varFreeMembers(&r[0]);
+ varFreeMembers(&r[1]);
+ varFreeMembers(&r[2]);
break;
case CNFFUNC_PRIFILT:
pPrifilt = (struct funcData_prifilt*) func->funcdata;
@@ -1670,8 +1688,8 @@ evalStrArrayCmp(es_str_t *estr_l, struct cnfarray* ar, int cmpop)
}
#define FREE_BOTH_RET \
- if(r.datatype == 'S') es_deleteStr(r.d.estr); \
- if(l.datatype == 'S') es_deleteStr(l.d.estr)
+ varFreeMembers(&r); \
+ varFreeMembers(&l)
#define COMP_NUM_BINOP(x) \
cnfexprEval(expr->l, &l, usrptr); \
@@ -1698,9 +1716,9 @@ evalStrArrayCmp(es_str_t *estr_l, struct cnfarray* ar, int cmpop)
#define FREE_TWO_STRINGS \
if(bMustFree) es_deleteStr(estr_r); \
- if(expr->r->nodetype != 'S' && expr->r->nodetype != 'A' && r.datatype == 'S') es_deleteStr(r.d.estr); \
+ if(expr->r->nodetype != 'S' && expr->r->nodetype != 'A') varFreeMembers(&r); \
if(bMustFree2) es_deleteStr(estr_l); \
- if(l.datatype == 'S') es_deleteStr(l.d.estr)
+ varFreeMembers(&l)
/* evaluate an expression.
* Note that we try to avoid malloc whenever possible (because of
@@ -1751,7 +1769,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
if(bMustFree) es_deleteStr(estr_r);
}
}
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
}
} else if(l.datatype == 'J') {
estr_l = var2String(&l, &bMustFree);
@@ -1773,7 +1791,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
if(bMustFree) es_deleteStr(estr_r);
}
}
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
}
if(bMustFree) es_deleteStr(estr_l);
} else {
@@ -1790,9 +1808,9 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
} else {
ret->d.n = (l.d.n == r.d.n); /*CMP*/
}
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
}
- if(l.datatype == 'S') es_deleteStr(l.d.estr);
+ varFreeMembers(&l);
break;
case CMP_NE:
cnfexprEval(expr->l, &l, usrptr);
@@ -2020,9 +2038,9 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
ret->d.n = 1ll;
else
ret->d.n = 0ll;
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
}
- if(l.datatype == 'S') es_deleteStr(l.d.estr);
+ varFreeMembers(&l);
break;
case AND:
cnfexprEval(expr->l, &l, usrptr);
@@ -2033,17 +2051,17 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
ret->d.n = 1ll;
else
ret->d.n = 0ll;
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
} else {
ret->d.n = 0ll;
}
- if(l.datatype == 'S') es_deleteStr(l.d.estr);
+ varFreeMembers(&l);
break;
case NOT:
cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N';
ret->d.n = !var2Number(&r, &convok_r);
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
break;
case 'N':
ret->datatype = 'N';
@@ -2094,7 +2112,7 @@ cnfexprEval(struct cnfexpr *expr, struct var *ret, void* usrptr)
cnfexprEval(expr->r, &r, usrptr);
ret->datatype = 'N';
ret->d.n = -var2Number(&r, &convok_r);
- if(r.datatype == 'S') es_deleteStr(r.d.estr);
+ varFreeMembers(&r);
break;
case 'F':
doFuncCall((struct cnffunc*) expr, ret, usrptr);