diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 2eea8f80..8af9e6d6 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -281,8 +281,11 @@ check_body_namespace(cxobj *x0, * @retval 1 OK * @retval 0 Failed (cbret set) * @retval -1 Error - * XXX this code is a mess. It tries multiple methods, one after the other. The solution - * is probably to make xpath evaluation namespace aware in combination with XML evaluation + * XXX this code is a mess. It tries multiple methods, one after the other. + * Observations: + * (1) is enough and required by clixon/controller tests + * (1+4+6) is required by some Arista machines + * The solution is probably to make xpath evaluation namespace aware in combination with XML evaluation * (3+4) */ static int @@ -316,9 +319,10 @@ check_when_condition(cxobj *x0p, goto done; if (nr != 0) goto ok; + /* 2. Try yang context for incoming xml */ if (xml_nsctx_node(x1p, &nnsc) < 0) goto done; - /* 2. Try yang context for incoming xml */ +#if 0 if ((nr = xpath_vec_bool(x1p, nsc, "%s", xpath)) < 0) goto done; if (nr != 0) @@ -328,18 +332,21 @@ check_when_condition(cxobj *x0p, goto done; if (nr != 0) goto ok; +#endif /* 4. Try xml context for existing xml */ if ((nr = xpath_vec_bool(x0p, nnsc, "%s", xpath)) < 0) /* Try request */ goto done; if (nr != 0) goto ok; + /* 5. Try yang canonical context for incoming xml */ if (yang_when_canonical_xpath_get(y, &cxpath, &cnsc) < 0) goto done; - /* 5. Try yang canonical context for incoming xml */ +#if 0 if ((nr = xpath_vec_bool(x1p, cnsc, "%s", cxpath)) < 0) goto done; if (nr != 0) goto ok; +#endif /* 6. Try yang canonical context for existing xml */ if ((nr = xpath_vec_bool(x0p, cnsc, "%s", cxpath)) < 0) goto done; @@ -361,12 +368,14 @@ check_when_condition(cxobj *x0p, ok: retval = 1; done: + if (cxpath) + free(cxpath); + if (cnsc) + cvec_free(cnsc); if (nsc) cvec_free(nsc); if (cberr) cbuf_free(cberr); - if (cxpath) - free(cxpath); if (nnsc) cvec_free(nnsc); return retval; @@ -498,6 +507,8 @@ choice_other_match(cxobj *x0, ok: retval = 1; done: + if (opstr) + free(opstr); return retval; fail: retval = 0; diff --git a/lib/src/clixon_validate.c b/lib/src/clixon_validate.c index f8b78f70..6485db11 100644 --- a/lib/src/clixon_validate.c +++ b/lib/src/clixon_validate.c @@ -1239,6 +1239,7 @@ xml_yang_validate_all(clixon_handle h, yang_stmt *yc; /* yang child */ yang_stmt *ye; /* yang must error-message */ char *xpath; + char *xpath1 = NULL; int nr; int ret; cxobj *x; @@ -1283,8 +1284,8 @@ xml_yang_validate_all(clixon_handle h, goto fail; } if (yang_config(yt) != 0){ - ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath); - clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath, ret); + ret = yang_check_when_xpath(xt, xml_parent(xt), yt, &hit, &nr, &xpath1); + clixon_debug(CLIXON_DBG_XPATH|CLIXON_DBG_DETAIL, "nr:%d xpath:%s return:%d", nr, xpath1, ret); if (ret < 0) goto done; @@ -1296,7 +1297,7 @@ xml_yang_validate_all(clixon_handle h, cprintf(cb, "Failed WHEN condition of %s in module %s (WHEN xpath is %s)", xml_name(xt), yang_argument_get(ys_module(yt)), - xpath); + xpath1); if (xret && netconf_operation_failed_xml(xret, "application", cbuf_get(cb)) < 0) goto done; @@ -1403,6 +1404,8 @@ xml_yang_validate_all(clixon_handle h, ok: retval = 1; done: + if (xpath1) + free(xpath1); if (cb) cbuf_free(cb); if (nsc) diff --git a/lib/src/clixon_xml_default.c b/lib/src/clixon_xml_default.c index 5a4cd9f1..1186f98f 100644 --- a/lib/src/clixon_xml_default.c +++ b/lib/src/clixon_xml_default.c @@ -299,7 +299,6 @@ xml_default(yang_stmt *yt, cxobj *xc; int top = 0; /* Top symbol (set default namespace) */ int create = 0; - char *xpath; int nr = 0; int hit = 0; cg_var *cv; @@ -336,7 +335,7 @@ xml_default(yang_stmt *yt, } if (!cv_flag(cv, V_UNSET)){ /* Default value exists */ /* Check when condition */ - if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0) + if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0) goto done; if (hit && nr == 0) break; /* Do not create default if xpath fails */ @@ -351,7 +350,7 @@ xml_default(yang_stmt *yt, case Y_CONTAINER: if (yang_find(yc, Y_PRESENCE, NULL) == NULL){ /* Check when condition */ - if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, &xpath) < 0) + if (yang_check_when_xpath(NULL, xt, yc, &hit, &nr, NULL) < 0) goto done; if (hit && nr == 0) break; /* Do not create default if xpath fails */ diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 95f69606..633d6c1f 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -2068,7 +2068,7 @@ xml_copy_marked(cxobj *x0, * @param[in] yn Yang node * @param[out] hit when statement found * @param[out] nrp 1: when stmt evaluates to true - * @param[out] xpathp when stmts xpath + * @param[out] xpathp when stmts xpath, free after use * @retval 0 OK * @retval -1 Error * First variants of WHEN: Augmented and uses when using special info in node @@ -2088,24 +2088,26 @@ yang_check_when_xpath(cxobj *xn, cxobj *x = NULL; int nr = 0; cvec *nsc = NULL; - int xmalloc = 0; /* ugly help variable to clean temporary object */ + int variant = 0; /* ugly help variable to clean temporary object */ - /* First variant */ if (yang_when_canonical_xpath_get(yn, &xpath, &nsc) < 0) goto done; if (xpath != NULL){ x = xp; *hit = 1; } - /* Second variant */ else if ((yc = yang_find(yn, Y_WHEN, NULL)) != NULL){ - xpath = yang_argument_get(yc); /* "when" has xpath argument */ + /* "when" has xpath argument */ + if ((xpath = strdup(yang_argument_get(yc))) == NULL){ + clixon_err(OE_UNIX, errno, "strdup"); + goto done; + } /* Create dummy */ if (xn == NULL){ if ((x = xml_new(yang_argument_get(yn), xp, CX_ELMNT)) == NULL) goto done; xml_spec_set(x, yn); - xmalloc++; + variant = 1; } else x = xn; @@ -2121,12 +2123,16 @@ yang_check_when_xpath(cxobj *xn, } if (nrp) *nrp = nr; - if (xpathp) + if (xpathp){ *xpathp = xpath; + xpath = NULL; + } retval = 0; done: - if (xmalloc) + if (variant) xml_purge(x); + if (xpath) + free(xpath); if (nsc) xml_nsctx_free(nsc); return retval; diff --git a/lib/src/clixon_xpath.c b/lib/src/clixon_xpath.c index 9b174293..6367ac50 100644 --- a/lib/src/clixon_xpath.c +++ b/lib/src/clixon_xpath.c @@ -1147,7 +1147,7 @@ xpath_traverse_canonical(xpath_tree *xs, * @param[in] nsc0 Input namespace context * @param[in] yspec Yang spec containing all modules, associated with namespaces * @param[in] exprstr Interpret strings as : (primaryexpr/literal/string) - * @param[out] xpath1 Output xpath. Free after use with free + * @param[out] xpath1 Output xpath. Free after use * @param[out] nsc1 Output namespace context. Free after use with xml_nsctx_free * @param[out] cbreason reason if retval = 0 * @retval 1 OK, xpath1 and nsc1 allocated @@ -1239,6 +1239,8 @@ xpath2canonical1(const char *xpath0, goto done; } +/*! Backward compatible wrapper around xpath2canonical1 + */ int xpath2canonical(const char *xpath0, cvec *nsc0,