* Added xmlns validation
* for eg <a xmlns:x="uri"><x:b/></a>
This commit is contained in:
parent
39538461c2
commit
849e46191e
6 changed files with 124 additions and 52 deletions
|
|
@ -109,7 +109,7 @@ struct xml{
|
|||
enum cxobj_type x_type; /* type of node: element, attribute, body */
|
||||
char *x_value; /* attribute and body nodes have values */
|
||||
int _x_vector_i; /* internal use: xml_child_each */
|
||||
int x_flags; /* Flags according to XML_FLAG_* above */
|
||||
int x_flags; /* Flags according to XML_FLAG_* */
|
||||
yang_stmt *x_spec; /* Pointer to specification, eg yang, by
|
||||
reference, dont free */
|
||||
cg_var *x_cv; /* If body this contains the typed value */
|
||||
|
|
@ -181,7 +181,7 @@ xml_namespace(cxobj *xn)
|
|||
return xn->x_namespace;
|
||||
}
|
||||
|
||||
/*! Set name of xnode, name is copied
|
||||
/*! Set name space of xnode, namespace is copied
|
||||
* @param[in] xn xml node
|
||||
* @param[in] namespace new namespace, null-terminated string, copied by function
|
||||
* @retval -1 on error with clicon-err set
|
||||
|
|
@ -204,6 +204,71 @@ xml_namespace_set(cxobj *xn,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! See if xmlns:<namespace>=<uri> exists, if so return <uri>
|
||||
*
|
||||
* @param[in] xn XML node
|
||||
* @param[in] nsn Namespace name
|
||||
* @retval URI return associated URI if found
|
||||
* @retval NULL No namespace name binding found for nsn
|
||||
*/
|
||||
static char *
|
||||
xmlns_check(cxobj *xn,
|
||||
char *nsn)
|
||||
{
|
||||
cxobj *x = NULL;
|
||||
char *xns;
|
||||
|
||||
while ((x = xml_child_each(xn, x, -1)) != NULL)
|
||||
if ((xns = xml_namespace(x)) && strcmp(xns, "xmlns")==0 &&
|
||||
strcmp(xml_name(x), nsn) == 0)
|
||||
return xml_value(x);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*! Check namespace of xml node by searhing recursively among ancestors
|
||||
* @param[in] xn xml node
|
||||
* @param[in] namespace check validity of namespace
|
||||
* @retval 0 Found / validated or no yang spec
|
||||
* @retval -1 Not found
|
||||
* @note This function is grossly inefficient
|
||||
*/
|
||||
static int
|
||||
xml_namespace_check(cxobj *xn,
|
||||
void *arg)
|
||||
{
|
||||
cxobj *xp = NULL;
|
||||
char *nsn;
|
||||
char *n;
|
||||
yang_stmt *ys = xml_spec(xn);
|
||||
|
||||
/* No namespace name - comply */
|
||||
if ((nsn = xml_namespace(xn)) == NULL)
|
||||
return 0;
|
||||
/* Check if NSN defined in same node */
|
||||
if (xmlns_check(xn, nsn) != NULL)
|
||||
return 0;
|
||||
/* Check if NSN defined in some ancestor */
|
||||
while ((xp = xml_parent(xn)) != NULL) {
|
||||
if (xmlns_check(xp, nsn) != NULL)
|
||||
return 0;
|
||||
xn = xp;
|
||||
}
|
||||
if (ys == NULL)
|
||||
return 0; /* If no yang spec */
|
||||
else{
|
||||
/* Check if my namespace */
|
||||
if ((n = yang_find_myprefix(ys)) != NULL && strcmp(nsn,n)==0)
|
||||
return 0;
|
||||
/* Check if any imported module */
|
||||
if (yang_find_module_by_prefix(ys, nsn) != NULL)
|
||||
return 0;
|
||||
}
|
||||
/* Not found, error */
|
||||
clicon_err(OE_XML, ENOENT, "Namespace name %s in %s:%s not found",
|
||||
nsn, nsn, xml_name(xn));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*! Get parent of xnode
|
||||
* @param[in] xn xml node
|
||||
* @retval parent xml node
|
||||
|
|
@ -869,7 +934,6 @@ xml_find_value(cxobj *xt,
|
|||
* Explaining picture:
|
||||
* xt --> x --> bx (x_type=CX_BODY)
|
||||
* x_name=name return x_value
|
||||
|
||||
*/
|
||||
char *
|
||||
xml_find_body(cxobj *xt,
|
||||
|
|
@ -1247,6 +1311,9 @@ _xml_parse(const char *str,
|
|||
goto done;
|
||||
if (clixon_xml_parseparse(&ya) != 0) /* yacc returns 1 on error */
|
||||
goto done;
|
||||
/* Verify namespaces after parsing */
|
||||
if (xml_apply0(xt, CX_ELMNT, xml_namespace_check, NULL) < 0)
|
||||
goto done;
|
||||
/* Sort the complete tree after parsing */
|
||||
if (yspec){
|
||||
if (xml_apply0(xt, CX_ELMNT, xml_sort, NULL) < 0)
|
||||
|
|
@ -1658,7 +1725,6 @@ xml_apply0(cxobj *xn,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*! Apply a function call recursively on all ancestors
|
||||
* Recursively traverse upwards to all ancestor nodes in a parse-tree and apply fn(arg) for
|
||||
* each object found. The function is called with the xml node and an
|
||||
|
|
@ -1861,7 +1927,6 @@ xml_operation2str(enum operation_type op)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Turn this on to get a xml parse and pretty print test program
|
||||
* Usage: xpath
|
||||
|
|
@ -1892,7 +1957,7 @@ main(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
if (xml_parse_file(0, "</config>", NULL, &xt) < 0){
|
||||
fprintf(stderr, "parsing 2\n");
|
||||
fprintf(stderr, "xml parse error %s\n", clicon_err_reason);
|
||||
return -1;
|
||||
}
|
||||
xc = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue