Fixed memory leak in xmld database put code
C: refactored choice validate code
This commit is contained in:
parent
b67ef69b7f
commit
1eefadfc74
2 changed files with 123 additions and 35 deletions
|
|
@ -130,8 +130,11 @@ attr_ns_value(cxobj *x,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*valp = val;
|
*valp = val;
|
||||||
|
val = NULL;
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (val)
|
||||||
|
free(val);
|
||||||
return retval;
|
return retval;
|
||||||
fail:
|
fail:
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
@ -945,8 +948,16 @@ text_modify(clicon_handle h,
|
||||||
} /* else Y_CONTAINER */
|
} /* else Y_CONTAINER */
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
if (valstr)
|
||||||
|
free(valstr);
|
||||||
|
if (keystr)
|
||||||
|
free(keystr);
|
||||||
|
if (instr)
|
||||||
|
free(instr);
|
||||||
if (opstr)
|
if (opstr)
|
||||||
free(opstr);
|
free(opstr);
|
||||||
|
if (createstr)
|
||||||
|
free(createstr);
|
||||||
if (nscx1)
|
if (nscx1)
|
||||||
xml_nsctx_free(nscx1);
|
xml_nsctx_free(nscx1);
|
||||||
/* Remove dangling added objects */
|
/* Remove dangling added objects */
|
||||||
|
|
@ -996,7 +1007,7 @@ text_modify_top(clicon_handle h,
|
||||||
cxobj *x1c; /* mod child */
|
cxobj *x1c; /* mod child */
|
||||||
yang_stmt *yc; /* yang child */
|
yang_stmt *yc; /* yang child */
|
||||||
yang_stmt *ymod;/* yang module */
|
yang_stmt *ymod;/* yang module */
|
||||||
char *opstr;
|
char *opstr = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
char *createstr = NULL;
|
char *createstr = NULL;
|
||||||
|
|
||||||
|
|
@ -1121,6 +1132,8 @@ text_modify_top(clicon_handle h,
|
||||||
done:
|
done:
|
||||||
if (opstr)
|
if (opstr)
|
||||||
free(opstr);
|
free(opstr);
|
||||||
|
if (createstr)
|
||||||
|
free(createstr);
|
||||||
return retval;
|
return retval;
|
||||||
fail: /* cbret set */
|
fail: /* cbret set */
|
||||||
retval = 0;
|
retval = 0;
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@
|
||||||
#include "clixon_xpath.h"
|
#include "clixon_xpath.h"
|
||||||
#include "clixon_yang_module.h"
|
#include "clixon_yang_module.h"
|
||||||
#include "clixon_yang_type.h"
|
#include "clixon_yang_type.h"
|
||||||
#include "clixon_xml_map.h"
|
|
||||||
#include "clixon_xml_default.h"
|
#include "clixon_xml_default.h"
|
||||||
|
#include "clixon_xml_map.h"
|
||||||
#include "clixon_xml_bind.h"
|
#include "clixon_xml_bind.h"
|
||||||
#include "clixon_validate_minmax.h"
|
#include "clixon_validate_minmax.h"
|
||||||
#include "clixon_validate.h"
|
#include "clixon_validate.h"
|
||||||
|
|
@ -479,46 +479,34 @@ xml_yang_validate_rpc_reply(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Check if an xml node is a part of a choice and have >1 siblings
|
/*! Check if an xml choice node xp has children in same case
|
||||||
* @param[in] xt XML node to be validated
|
*
|
||||||
* @param[in] yt xt:s yang statement
|
* @param[in] xp XML choice node to be validated
|
||||||
* @param[out] xret Error XML tree. Free with xml_free after use
|
* @param[in] ytchoice Yang spec of choice
|
||||||
* @retval 1 Validation OK
|
* @param[in] ytcase Yang spec of case, optional
|
||||||
* @retval 0 Validation failed (cbret set)
|
* @param[in] xt XML child
|
||||||
* @retval -1 Error
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
* Check if xt is part of valid choice
|
* @retval 1 Validation OK
|
||||||
|
* @retval 0 Validation failed (cbret set)
|
||||||
|
* @retval -1 Error
|
||||||
|
* From RFC7950 Sec 7.9.3
|
||||||
|
* 1. Default case, the default if no child nodes from any of the choice's cases exist
|
||||||
|
* 2. Default for child nodes under a case are only used if one of the nodes under that case
|
||||||
|
* is present
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
check_choice(cxobj *xt,
|
check_choice(cxobj *xp,
|
||||||
|
yang_stmt *ytchoice,
|
||||||
|
yang_stmt *ytcase,
|
||||||
|
cxobj *xt,
|
||||||
yang_stmt *yt,
|
yang_stmt *yt,
|
||||||
cxobj **xret)
|
cxobj **xret)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
yang_stmt *y;
|
|
||||||
yang_stmt *ytp; /* yt:s parent */
|
|
||||||
yang_stmt *ytcase = NULL; /* yt:s parent case if any */
|
|
||||||
yang_stmt *ytchoice = NULL;
|
|
||||||
yang_stmt *yp;
|
|
||||||
cxobj *x;
|
cxobj *x;
|
||||||
cxobj *xp;
|
yang_stmt *y;
|
||||||
|
yang_stmt *yp;
|
||||||
|
|
||||||
if ((ytp = yang_parent_get(yt)) == NULL)
|
|
||||||
goto ok;
|
|
||||||
/* Return OK if xt is not choice */
|
|
||||||
switch (yang_keyword_get(ytp)){
|
|
||||||
case Y_CASE:
|
|
||||||
ytcase = ytp;
|
|
||||||
ytchoice = yang_parent_get(ytp);
|
|
||||||
break;
|
|
||||||
case Y_CHOICE:
|
|
||||||
ytchoice = ytp;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto ok; /* Not choice */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((xp = xml_parent(xt)) == NULL)
|
|
||||||
goto ok;
|
|
||||||
x = NULL; /* Find a child with same yang spec */
|
x = NULL; /* Find a child with same yang spec */
|
||||||
while ((x = xml_child_each(xp, x, CX_ELMNT)) != NULL) {
|
while ((x = xml_child_each(xp, x, CX_ELMNT)) != NULL) {
|
||||||
if (x == xt)
|
if (x == xt)
|
||||||
|
|
@ -546,6 +534,93 @@ check_choice(cxobj *xt,
|
||||||
goto done;
|
goto done;
|
||||||
goto fail;
|
goto fail;
|
||||||
} /* while */
|
} /* while */
|
||||||
|
retval = 1;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
fail:
|
||||||
|
retval = 0;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Check if an xml node xt is a part of a choice and have >1 siblings
|
||||||
|
* @param[in] xt XML node to be validated
|
||||||
|
* @param[in] yt xt:s yang statement
|
||||||
|
* @param[out] xret Error XML tree. Free with xml_free after use
|
||||||
|
* @retval 1 Validation OK
|
||||||
|
* @retval 0 Validation failed (cbret set)
|
||||||
|
* @retval -1 Error
|
||||||
|
* Check if xt is part of valid choice
|
||||||
|
* XXX does not check: xt is choice and has n children, but there exists a default child
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
check_choice_child(cxobj *xt,
|
||||||
|
yang_stmt *yt,
|
||||||
|
cxobj **xret)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
|
||||||
|
yang_stmt *ytp; /* yt:s parent */
|
||||||
|
yang_stmt *ytcase = NULL; /* yt:s parent case if any */
|
||||||
|
yang_stmt *ytchoice = NULL;
|
||||||
|
int ret;
|
||||||
|
cxobj *xp;
|
||||||
|
#if 0
|
||||||
|
cxobj *x;
|
||||||
|
yang_stmt *yp;
|
||||||
|
yang_stmt *y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((ytp = yang_parent_get(yt)) == NULL)
|
||||||
|
goto ok;
|
||||||
|
/* Return OK if xt is not choice */
|
||||||
|
switch (yang_keyword_get(ytp)){
|
||||||
|
case Y_CASE:
|
||||||
|
ytcase = ytp;
|
||||||
|
ytchoice = yang_parent_get(ytp);
|
||||||
|
break;
|
||||||
|
case Y_CHOICE:
|
||||||
|
ytchoice = ytp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto ok; /* Not choice */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((xp = xml_parent(xt)) == NULL)
|
||||||
|
goto ok;
|
||||||
|
#if 1
|
||||||
|
if ((ret = check_choice(xp, ytchoice, ytcase, xt, yt, xret)) < 0)
|
||||||
|
goto done;
|
||||||
|
if (ret == 0)
|
||||||
|
goto fail;
|
||||||
|
#else
|
||||||
|
x = NULL; /* Find a child with same yang spec */
|
||||||
|
while ((x = xml_child_each(xp, x, CX_ELMNT)) != NULL) {
|
||||||
|
if (x == xt)
|
||||||
|
continue;
|
||||||
|
y = xml_spec(x);
|
||||||
|
if (y == yt) /* eg same list */
|
||||||
|
continue;
|
||||||
|
yp = yang_parent_get(y);
|
||||||
|
switch (yang_keyword_get(yp)){
|
||||||
|
case Y_CASE:
|
||||||
|
if (yang_parent_get(yp) != ytchoice) /* Not same choice (not relevant) */
|
||||||
|
continue;
|
||||||
|
if (yp == ytcase) /* same choice but different case */
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
case Y_CHOICE:
|
||||||
|
if (yp != ytchoice) /* Not same choice (not relevant) */
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
continue; /* not choice */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (xret && netconf_bad_element_xml(xret, "application", xml_name(x), "Element in choice statement already exists") < 0)
|
||||||
|
goto done;
|
||||||
|
goto fail;
|
||||||
|
} /* while */
|
||||||
|
#endif
|
||||||
ok:
|
ok:
|
||||||
retval = 1;
|
retval = 1;
|
||||||
done:
|
done:
|
||||||
|
|
@ -919,7 +994,7 @@ xml_yang_validate_add(clicon_handle h,
|
||||||
/* if not given by argument (overide) use default link
|
/* if not given by argument (overide) use default link
|
||||||
and !Node has a config sub-statement and it is false */
|
and !Node has a config sub-statement and it is false */
|
||||||
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
if ((yt = xml_spec(xt)) != NULL && yang_config(yt) != 0){
|
||||||
if ((ret = check_choice(xt, yt, xret)) < 0)
|
if ((ret = check_choice_child(xt, yt, xret)) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue