From b31297cb212d6427d9a048c84be132c24a2ecec9 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 21 Feb 2020 10:23:42 +0100 Subject: [PATCH] memory leaks --- lib/src/clixon_xml.c | 16 ++++---- lib/src/clixon_xml_map.c | 78 +++++++++++++++++++++++++++++++++++++- lib/src/clixon_xml_parse.y | 18 +++++---- test/mem.sh | 2 +- test/test_leafref_state.sh | 1 + 5 files changed, 98 insertions(+), 17 deletions(-) diff --git a/lib/src/clixon_xml.c b/lib/src/clixon_xml.c index e3302fe5..21b0912c 100644 --- a/lib/src/clixon_xml.c +++ b/lib/src/clixon_xml.c @@ -1706,15 +1706,15 @@ xml_find_body_obj(cxobj *xt, int xml_free(cxobj *x) { - int i; + int i; cxobj *xc; if (x->x_name) free(x->x_name); - if (x->x_value_cb) - cbuf_free(x->x_value_cb); if (x->x_prefix) free(x->x_prefix); + if (x->x_value_cb) + cbuf_free(x->x_value_cb); for (i=0; ix_childvec_len; i++){ if ((xc = x->x_childvec[i]) != NULL){ xml_free(xc); @@ -2032,12 +2032,12 @@ _xml_parse(const char *str, cxobj *xt, cxobj **xerr) { - int retval = -1; + int retval = -1; clixon_xml_yacc ya = {0,}; - cxobj *x; - int ret; - int failed = 0; /* yang assignment */ - int i; + cxobj *x; + int ret; + int failed = 0; /* yang assignment */ + int i; clicon_debug(1, "%s %s", __FUNCTION__, str); if (strlen(str) == 0) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 5046533c..f02497d1 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -601,6 +601,82 @@ xml_diff(yang_stmt *yspec, * @note This function seems a little too complex semantics * @see xml_tree_prune_flagged for a simpler variant */ +#if 1 +int +xml_tree_prune_flagged_sub(cxobj *xt, + int flag, + int test, + int *upmark) +{ + int retval = -1; + int submark; + int mark; + cxobj *x; + cxobj *xprev; + int iskey; + int anykey=0; + yang_stmt *yt; + + mark = 0; + yt = xml_spec(xt); /* xan be null */ + x = NULL; + xprev = x = NULL; + while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) { + if (xml_flag(x, flag) == test?flag:0){ + /* Pass test */ + mark++; + xprev = x; + continue; /* mark and stop here */ + } + /* If it is key dont remove it yet (see second round) */ + if (yt){ + if ((iskey = yang_key_match(yt, xml_name(x))) < 0) + goto done; + if (iskey){ + anykey++; + xprev = x; /* skip if this is key */ + continue; + } + } + if (xml_tree_prune_flagged_sub(x, flag, test, &submark) < 0) + goto done; + /* if xt is list and submark anywhere, then key subs are also marked + */ + if (submark) + mark++; + else{ /* Safe with xml_child_each if last */ + if (xml_purge(x) < 0) + goto done; + x = xprev; + } + xprev = x; + } + /* Second round: if any keys were found, and no marks detected, purge now */ + if (anykey && !mark){ + x = NULL; + xprev = x = NULL; + while ((x = xml_child_each(xt, x, CX_ELMNT)) != NULL) { + /* If it is key remove it here */ + if (yt){ + if ((iskey = yang_key_match(yt, xml_name(x))) < 0) + goto done; + if (iskey && xml_purge(x) < 0) + goto done; + x = xprev; + } + xprev = x; + } + } + retval = 0; + done: + if (upmark) + *upmark = mark; + return retval; +} +#else +/* This is optimized in the sense that xml_purge is replaced with xml_child_rm but it leaks memory, + * in poarticualr attributes and namespace caches + */ int xml_tree_prune_flagged_sub(cxobj *xt, int flag, @@ -687,7 +763,7 @@ xml_tree_prune_flagged_sub(cxobj *xt, *upmark = mark; return retval; } - +#endif /*! Prune everything that passes test * @param[in] xt XML tree with some node marked * @param[in] flag Which flag to test for diff --git a/lib/src/clixon_xml_parse.y b/lib/src/clixon_xml_parse.y index a8813271..78e3a217 100644 --- a/lib/src/clixon_xml_parse.y +++ b/lib/src/clixon_xml_parse.y @@ -178,8 +178,8 @@ xml_parse_version(clixon_xml_yacc *ya, */ static int xml_parse_prefixed_name(clixon_xml_yacc *ya, - char *prefix, - char *name) + char *prefix, + char *name) { int retval = -1; cxobj *x; @@ -201,7 +201,8 @@ xml_parse_prefixed_name(clixon_xml_yacc *ya, done: if (prefix) free(prefix); - free(name); + if (name) + free(name); return retval; } @@ -242,8 +243,8 @@ xml_parse_endslash_post(clixon_xml_yacc *ya) */ static int xml_parse_bslash(clixon_xml_yacc *ya, - char *prefix, - char *name) + char *prefix, + char *name) { int retval = -1; cxobj *x = ya->ya_xelement; @@ -279,7 +280,10 @@ xml_parse_bslash(clixon_xml_yacc *ya, } retval = 0; done: - free(name); + if (prefix) + free(prefix); + if (name) + free(name); return retval; } @@ -412,7 +416,7 @@ comment : BCOMMENT ECOMMENT pi : BQMARK NAME EQMARK {clicon_debug(2, "pi -> "); free($2); } | BQMARK NAME STRING EQMARK - {clicon_debug(2, "pi -> "); free($2); free($3);} + { clicon_debug(2, "pi -> "); free($2); free($3);} ; diff --git a/test/mem.sh b/test/mem.sh index a5b33714..503d60f7 100755 --- a/test/mem.sh +++ b/test/mem.sh @@ -31,7 +31,7 @@ memonce(){ perfnr=100 # test_perf.sh restconf put more or less stops perfreq=10 - clixon_backend="/usr/bin/valgrind --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=yes --log-file=$valgrindfile clixon_backend" + clixon_backend="/usr/bin/valgrind --num-callers=50 --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=yes --log-file=$valgrindfile clixon_backend" ;; 'restconf') valgrindtest=3 # This means backend valgrind test diff --git a/test/test_leafref_state.sh b/test/test_leafref_state.sh index 09a87ca5..a586135e 100755 --- a/test/test_leafref_state.sh +++ b/test/test_leafref_state.sh @@ -10,6 +10,7 @@ # with different paths. # Using the -sS state capability of the main example, that is why CLICON_BACKEND_DIR is # /usr/local/lib/$APPNAME/backend so that the main backend plugins is included. +# These tests require VALIDATE_STATE_XML to be set # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi