Fixed issue https://github.com/clicon/clixon/issues/17 special character in strings can break RPCs
This commit is contained in:
parent
7650803475
commit
67c0abead7
15 changed files with 405 additions and 136 deletions
|
|
@ -103,6 +103,7 @@ enables saved files to be used as datastore without any editing. Thanks Matt.
|
|||
* Added cli_show_version()
|
||||
|
||||
### Corrected Bugs
|
||||
* Fixed issue https://github.com/clicon/clixon/issues/17 special character in strings can break RPCs
|
||||
* Fixed three-key list entry problem (reported by jdl@netgate)
|
||||
* Translate xml->json \n correctly
|
||||
* Fix issue: https://github.com/clicon/clixon/issues/15 Replace whole config
|
||||
|
|
|
|||
|
|
@ -1083,12 +1083,12 @@ from_client_msg(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
if (clicon_msg_decode(msg, &xt) < 0){
|
||||
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
|
||||
if (netconf_malformed_message(cbret, "XML parse error")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
if ((x = xpath_first(xt, "/rpc")) == NULL){
|
||||
if (netconf_malformed_message(cbret, "Not recognized, rpc expected")< 0)
|
||||
if (netconf_malformed_message(cbret, "rpc keyword expected")< 0)
|
||||
goto done;
|
||||
goto reply;
|
||||
}
|
||||
|
|
@ -1187,6 +1187,8 @@ from_client_msg(clicon_handle h,
|
|||
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s cbret:%s", __FUNCTION__, cbuf_get(cbret));
|
||||
/* XXX problem here is that cbret has not been parsed so may contain
|
||||
parse errors */
|
||||
if (send_msg_reply(ce->ce_s, cbuf_get(cbret), cbuf_len(cbret)+1) < 0){
|
||||
switch (errno){
|
||||
case EPIPE:
|
||||
|
|
|
|||
|
|
@ -516,12 +516,12 @@ cli_show_config(clicon_handle h,
|
|||
xml2txt(stdout, xc, 0); /* tree-formed text */
|
||||
break;
|
||||
case FORMAT_CLI:
|
||||
/* get CLI generatade mode: VARS|ALL */
|
||||
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
||||
goto done;
|
||||
xc = NULL; /* Dont print xt itself */
|
||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL){
|
||||
if ((gt = clicon_cli_genmodel_type(h)) == GT_ERR)
|
||||
goto done;
|
||||
while ((xc = xml_child_each(xt, xc, -1)) != NULL)
|
||||
xml2cli(stdout, xc, NULL, gt); /* cli syntax */
|
||||
}
|
||||
break;
|
||||
case FORMAT_NETCONF:
|
||||
fprintf(stdout, "<rpc><edit-config><target><candidate/></target><config>\n");
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ append_listkeys(cbuf *ckey,
|
|||
xml_name(xt), keyname);
|
||||
goto done;
|
||||
}
|
||||
if (percent_encode(xml_body(xkey), &bodyenc) < 0)
|
||||
if (uri_percent_encode(xml_body(xkey), &bodyenc) < 0)
|
||||
goto done;
|
||||
if (i++)
|
||||
cprintf(ckey, ",");
|
||||
|
|
@ -328,7 +328,7 @@ get(char *dbname,
|
|||
* If xml element is a leaf-list, then the next element is expected to
|
||||
* be a value
|
||||
*/
|
||||
if (percent_decode(restval, &argdec) < 0)
|
||||
if (uri_percent_decode(restval, &argdec) < 0)
|
||||
goto done;
|
||||
if ((xc = xml_find(x, name))==NULL ||
|
||||
(xb = xml_find(xc, argdec))==NULL){
|
||||
|
|
@ -373,7 +373,7 @@ get(char *dbname,
|
|||
if (j>=nvalvec)
|
||||
break;
|
||||
arg = valvec[j++];
|
||||
if (percent_decode(arg, &argdec) < 0)
|
||||
if (uri_percent_decode(arg, &argdec) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "[%s=%s]", cv_string_get(cvi), argdec);
|
||||
free(argdec);
|
||||
|
|
@ -391,7 +391,7 @@ get(char *dbname,
|
|||
break;
|
||||
arg = valvec[j++];
|
||||
keyname = cv_string_get(cvi);
|
||||
if (percent_decode(arg, &argdec) < 0)
|
||||
if (uri_percent_decode(arg, &argdec) < 0)
|
||||
goto done;
|
||||
if (create_keyvalues(xc,
|
||||
ykey,
|
||||
|
|
@ -681,7 +681,7 @@ put(char *dbfile,
|
|||
goto done;
|
||||
break;
|
||||
case Y_LEAF_LIST:
|
||||
if (percent_encode(body, &bodyenc) < 0)
|
||||
if (uri_percent_encode(body, &bodyenc) < 0)
|
||||
goto done;
|
||||
cprintf(cbxk, "=%s", bodyenc);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -74,8 +74,9 @@ static inline char * strdup4(char *str)
|
|||
char **clicon_strsep(char *string, char *delim, int *nvec0);
|
||||
char *clicon_strjoin (int argc, char **argv, char *delim);
|
||||
int str2cvec(char *string, char delim1, char delim2, cvec **cvp);
|
||||
int percent_encode(char *str, char **escp);
|
||||
int percent_decode(char *esc, char **str);
|
||||
int uri_percent_encode(char *str, char **escp);
|
||||
int uri_percent_decode(char *esc, char **str);
|
||||
int xml_chardata_encode(char *str, char **escp);
|
||||
const char *clicon_int2str(const map_str2int *mstab, int i);
|
||||
int clicon_str2int(const map_str2int *mstab, char *str);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
/* clixon */
|
||||
#include "clixon_queue.h"
|
||||
#include "clixon_hash.h"
|
||||
#include "clixon_string.h"
|
||||
#include "clixon_err.h"
|
||||
#include "clixon_handle.h"
|
||||
#include "clixon_yang.h"
|
||||
|
|
@ -73,20 +74,27 @@ netconf_in_use(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>in-use</error-tag>"
|
||||
"<error-type>%s</error-type>"
|
||||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -105,7 +113,8 @@ netconf_invalid_value(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>invalid-value</error-tag>"
|
||||
|
|
@ -113,12 +122,18 @@ netconf_invalid_value(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -139,6 +154,7 @@ netconf_too_big(cbuf *cb,
|
|||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>too-big</error-tag>"
|
||||
|
|
@ -146,12 +162,18 @@ netconf_too_big(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -172,7 +194,8 @@ netconf_missing_attribute(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-attribute</error-tag>"
|
||||
|
|
@ -181,8 +204,12 @@ netconf_missing_attribute(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
|
|
@ -208,7 +235,8 @@ netconf_bad_attribute(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>bad-attribute</error-tag>"
|
||||
|
|
@ -217,12 +245,18 @@ netconf_bad_attribute(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -243,7 +277,8 @@ netconf_unknown_attribute(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>unknown-attribute</error-tag>"
|
||||
|
|
@ -252,19 +287,24 @@ netconf_unknown_attribute(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/*! Create Netconf missing-element error XML tree according to RFC 6241 App A
|
||||
*
|
||||
* An expected element is missing.
|
||||
|
|
@ -279,7 +319,8 @@ netconf_missing_element(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>missing-element</error-tag>"
|
||||
|
|
@ -288,12 +329,18 @@ netconf_missing_element(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -315,7 +362,8 @@ netconf_bad_element(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>bad-element</error-tag>"
|
||||
|
|
@ -324,12 +372,18 @@ netconf_bad_element(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -350,8 +404,8 @@ netconf_unknown_element(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>unknown-element</error-tag>"
|
||||
|
|
@ -360,12 +414,18 @@ netconf_unknown_element(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -386,7 +446,8 @@ netconf_unknown_namespace(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>unknown-namespace</error-tag>"
|
||||
|
|
@ -395,12 +456,18 @@ netconf_unknown_namespace(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type, info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -420,6 +487,7 @@ netconf_access_denied(cbuf *cb,
|
|||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>access-denied</error-tag>"
|
||||
|
|
@ -427,12 +495,18 @@ netconf_access_denied(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -484,7 +558,8 @@ netconf_lock_denied(cbuf *cb,
|
|||
char *info,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>lock-denied</error-tag>"
|
||||
|
|
@ -493,12 +568,18 @@ netconf_lock_denied(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
info) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -517,20 +598,27 @@ netconf_resource_denied(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>resource-denied</error-tag>"
|
||||
"<error-type>%s</error-type>"
|
||||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -550,7 +638,8 @@ netconf_rollback_failed(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>rollback-failed</error-tag>"
|
||||
|
|
@ -558,12 +647,18 @@ netconf_rollback_failed(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -582,19 +677,26 @@ int
|
|||
netconf_data_exists(cbuf *cb,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>data-exists</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -613,19 +715,26 @@ int
|
|||
netconf_data_missing(cbuf *cb,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>data-missing</error-tag>"
|
||||
"<error-type>application</error-type>"
|
||||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -645,7 +754,8 @@ netconf_operation_not_supported(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-not-supported</error-tag>"
|
||||
|
|
@ -653,12 +763,18 @@ netconf_operation_not_supported(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -678,7 +794,8 @@ netconf_operation_failed(cbuf *cb,
|
|||
char *type,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>operation-failed</error-tag>"
|
||||
|
|
@ -686,12 +803,18 @@ netconf_operation_failed(cbuf *cb,
|
|||
"<error-severity>error</error-severity>",
|
||||
type) <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") < 0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
@ -744,19 +867,26 @@ int
|
|||
netconf_malformed_message(cbuf *cb,
|
||||
char *message)
|
||||
{
|
||||
int retval = -1;
|
||||
int retval = -1;
|
||||
char *encstr = NULL;
|
||||
|
||||
if (cprintf(cb, "<rpc-reply><rpc-error>"
|
||||
"<error-tag>malformed-message</error-tag>"
|
||||
"<error-type>rpc</error-type>"
|
||||
"<error-severity>error</error-severity>") <0)
|
||||
goto err;
|
||||
if (message && cprintf(cb, "<error-message>%s</error-message>", message) < 0)
|
||||
goto err;
|
||||
if (message){
|
||||
if (xml_chardata_encode(message, &encstr) < 0)
|
||||
goto done;
|
||||
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
|
||||
goto err;
|
||||
}
|
||||
if (cprintf(cb, "</rpc-error></rpc-reply>") <0)
|
||||
goto err;
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
err:
|
||||
clicon_err(OE_XML, errno, "cprintf");
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ clicon_strjoin(int argc,
|
|||
}
|
||||
|
||||
static int
|
||||
unreserved(unsigned char in)
|
||||
uri_unreserved(unsigned char in)
|
||||
{
|
||||
switch(in) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
|
|
@ -163,12 +163,18 @@ unreserved(unsigned char in)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*! Percent encoding according to RFC 3896
|
||||
* @param[out] esc Deallocate with free()
|
||||
/*! Percent encoding according to RFC 3986 URI Syntax
|
||||
* @param[in] str Not-encoded input string
|
||||
* @param[out] escp Encoded/escaped malloced output string
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see RFC 3986 Uniform Resource Identifier (URI): Generic Syntax
|
||||
* @see uri_percent_decode
|
||||
* @see xml_chardata_encode
|
||||
*/
|
||||
int
|
||||
percent_encode(char *str,
|
||||
char **escp)
|
||||
uri_percent_encode(char *str,
|
||||
char **escp)
|
||||
{
|
||||
int retval = -1;
|
||||
char *esc = NULL;
|
||||
|
|
@ -184,7 +190,7 @@ percent_encode(char *str,
|
|||
memset(esc, 0, len);
|
||||
j = 0;
|
||||
for (i=0; i<strlen(str); i++){
|
||||
if (unreserved(str[i]))
|
||||
if (uri_unreserved(str[i]))
|
||||
esc[j++] = str[i];
|
||||
else{
|
||||
snprintf(&esc[j], 4, "%%%02X", str[i]&0xff);
|
||||
|
|
@ -199,12 +205,17 @@ percent_encode(char *str,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Percent decoding according to RFC 3896
|
||||
* @param[out] str Deallocate with free()
|
||||
/*! Percent decoding according to RFC 3986 URI Syntax
|
||||
* @param[in] esc Escaped/encoded input string
|
||||
* @param[out] strp Decoded malloced output string. Deallocate with free()
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see RFC 3986 Uniform Resource Identifier (URI): Generic Syntax
|
||||
* @see uri_percent_encode
|
||||
*/
|
||||
int
|
||||
percent_decode(char *esc,
|
||||
char **strp)
|
||||
uri_percent_decode(char *esc,
|
||||
char **strp)
|
||||
{
|
||||
int retval = -1;
|
||||
char *str = NULL;
|
||||
|
|
@ -243,6 +254,98 @@ percent_decode(char *esc,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Escape characters according to XML definition
|
||||
* @param[in] str Not-encoded input string
|
||||
* @param[out] escp Encoded/escaped malloced output string
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
* @see https://www.w3.org/TR/2008/REC-xml-20081126/#syntax chapter 2.6
|
||||
* @see uri_percent_encode
|
||||
* @see AMPERSAND mode in clixon_xml_parse.l
|
||||
* @code
|
||||
* char *encstr = NULL;
|
||||
* char *val = "a<>b";
|
||||
* if (xml_chardata_encode(str, &encstr) < 0)
|
||||
* err;
|
||||
* if (encstr)
|
||||
* free(encstr);
|
||||
* @endcode
|
||||
* Essentially encode as follows:
|
||||
* & -> "& " must
|
||||
* < -> "< " must
|
||||
* > -> "> " must for backward compatibility
|
||||
* ' -> "' " may
|
||||
* ' -> "" " may
|
||||
* Optionally >
|
||||
*/
|
||||
int
|
||||
xml_chardata_encode(char *str,
|
||||
char **escp)
|
||||
{
|
||||
int retval = -1;
|
||||
char *esc = NULL;
|
||||
int l;
|
||||
int len;
|
||||
int i, j;
|
||||
|
||||
len = 0;
|
||||
for (i=0; i<strlen(str); i++){
|
||||
switch (str[i]){
|
||||
case '&':
|
||||
len += strlen("& ");
|
||||
break;
|
||||
case '<':
|
||||
len += strlen("< ");
|
||||
break;
|
||||
case '>':
|
||||
len += strlen("> ");
|
||||
break;
|
||||
default:
|
||||
len++;
|
||||
}
|
||||
}
|
||||
len++; /* trailing \0 */
|
||||
if ((esc = malloc(len)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "malloc");
|
||||
goto done;
|
||||
}
|
||||
memset(esc, 0, len);
|
||||
j = 0;
|
||||
for (i=0; i<strlen(str); i++){
|
||||
switch (str[i]){
|
||||
case '&':
|
||||
if ((l=snprintf(&esc[j], 7, "& ")) < 0){
|
||||
clicon_err(OE_UNIX, errno, "snprintf");
|
||||
goto done;
|
||||
}
|
||||
j += l;
|
||||
break;
|
||||
case '<':
|
||||
if ((l=snprintf(&esc[j], 6, "< ")) < 0){
|
||||
clicon_err(OE_UNIX, errno, "snprintf");
|
||||
goto done;
|
||||
}
|
||||
j += l;
|
||||
break;
|
||||
case '>':
|
||||
if ((l=snprintf(&esc[j], 6, "> ")) < 0){
|
||||
clicon_err(OE_UNIX, errno, "snprintf");
|
||||
goto done;
|
||||
}
|
||||
j += l;
|
||||
break;
|
||||
default:
|
||||
esc[j++] = str[i];
|
||||
}
|
||||
}
|
||||
*escp = esc;
|
||||
retval = 0;
|
||||
done:
|
||||
if (retval < 0 && esc)
|
||||
free(esc);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Split a string into a cligen variable vector using 1st and 2nd delimiter
|
||||
* Split a string first into elements delimited by delim1, then into
|
||||
* pairs delimited by delim2.
|
||||
|
|
@ -295,7 +398,7 @@ str2cvec(char *string,
|
|||
*(snext++) = '\0';
|
||||
if ((val = index(s, delim2)) != NULL){
|
||||
*(val++) = '\0';
|
||||
if (percent_decode(val, &valu) < 0)
|
||||
if (uri_percent_decode(val, &valu) < 0)
|
||||
goto err;
|
||||
if ((cv = cvec_add(cvv, CGV_STRING)) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cvec_add");
|
||||
|
|
|
|||
|
|
@ -950,7 +950,7 @@ xml_free(cxobj *x)
|
|||
* XML printing functions. Output a parse tree to file, string cligen buf
|
||||
*------------------------------------------------------------------------*/
|
||||
|
||||
/*! Print an XML tree structure to an output stream
|
||||
/*! Print an XML tree structure to an output stream and encode chars "<>&"
|
||||
*
|
||||
* Uses clicon_xml2cbuf internally
|
||||
*
|
||||
|
|
@ -975,13 +975,17 @@ clicon_xml2file(FILE *f,
|
|||
int hasbody;
|
||||
int haselement;
|
||||
char *val;
|
||||
|
||||
char *encstr = NULL; /* xml encoded string */
|
||||
|
||||
name = xml_name(x);
|
||||
namespace = xml_namespace(x);
|
||||
switch(xml_type(x)){
|
||||
case CX_BODY:
|
||||
if ((val = xml_value(x)) != NULL) /* incomplete tree */
|
||||
fprintf(f, "%s", xml_value(x));
|
||||
if ((val = xml_value(x)) == NULL) /* incomplete tree */
|
||||
break;
|
||||
if (xml_chardata_encode(val, &encstr) < 0)
|
||||
goto done;
|
||||
fprintf(f, "%s", encstr);
|
||||
break;
|
||||
case CX_ATTR:
|
||||
fprintf(f, " ");
|
||||
|
|
@ -1044,6 +1048,8 @@ clicon_xml2file(FILE *f,
|
|||
}/* switch */
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1063,8 +1069,7 @@ xml_print(FILE *f,
|
|||
return clicon_xml2file(f, xn, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
/*! Print an XML tree structure to a cligen buffer
|
||||
/*! Print an XML tree structure to a cligen buffer and encode chars "<>&"
|
||||
*
|
||||
* @param[in,out] cb Cligen buffer to write to
|
||||
* @param[in] xn Clicon xml tree
|
||||
|
|
@ -1093,12 +1098,18 @@ clicon_xml2cbuf(cbuf *cb,
|
|||
int hasbody;
|
||||
int haselement;
|
||||
char *namespace;
|
||||
|
||||
char *encstr = NULL; /* xml encoded string */
|
||||
char *val;
|
||||
|
||||
name = xml_name(x);
|
||||
namespace = xml_namespace(x);
|
||||
switch(xml_type(x)){
|
||||
case CX_BODY:
|
||||
cprintf(cb, "%s", xml_value(x));
|
||||
if ((val = xml_value(x)) == NULL) /* incomplete tree */
|
||||
break;
|
||||
if (xml_chardata_encode(val, &encstr) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", encstr);
|
||||
break;
|
||||
case CX_ATTR:
|
||||
cprintf(cb, " ");
|
||||
|
|
@ -1130,7 +1141,6 @@ clicon_xml2cbuf(cbuf *cb,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for special case <a/> instead of <a></a> */
|
||||
if (hasbody==0 && haselement==0)
|
||||
cprintf(cb, "/>");
|
||||
|
|
@ -1158,6 +1168,8 @@ clicon_xml2cbuf(cbuf *cb,
|
|||
}/* switch */
|
||||
retval = 0;
|
||||
done:
|
||||
if (encstr)
|
||||
free(encstr);
|
||||
return retval;
|
||||
}
|
||||
/*! Print actual xml tree datastructures (not xml), mainly for debugging
|
||||
|
|
|
|||
|
|
@ -189,7 +189,9 @@ xml2cli(FILE *f,
|
|||
int nr;
|
||||
int i;
|
||||
cbuf *cbpre;
|
||||
// yang_stmt *ys;
|
||||
|
||||
// ys = yang_spec(x);
|
||||
/* Create prepend variable string */
|
||||
if ((cbpre = cbuf_new()) == NULL){
|
||||
clicon_err(OE_PLUGIN, errno, "cbuf_new");
|
||||
|
|
@ -212,15 +214,15 @@ xml2cli(FILE *f,
|
|||
}
|
||||
if (prepend0)
|
||||
cprintf(cbpre, "%s", prepend0);
|
||||
/* bool determines when to print a variable keyword:
|
||||
!leaf T for all (ie parameter)
|
||||
index GT_NONE F
|
||||
index GT_VARS F
|
||||
index GT_ALL T
|
||||
!index GT_NONE F
|
||||
!index GT_VARS T
|
||||
!index GT_ALL T
|
||||
*/
|
||||
/* bool determines when to print a variable keyword:
|
||||
!leaf T for all (ie parameter)
|
||||
index GT_NONE F
|
||||
index GT_VARS F
|
||||
index GT_ALL T
|
||||
!index GT_NONE F
|
||||
!index GT_VARS T
|
||||
!index GT_ALL T
|
||||
*/
|
||||
bool = !leaf(x) || gt == GT_ALL || (gt == GT_VARS);
|
||||
// bool = (!x->xn_index || gt == GT_ALL);
|
||||
if (bool){
|
||||
|
|
@ -269,7 +271,6 @@ validate_leafref(cxobj *xt,
|
|||
char *leafrefbody;
|
||||
char *leafbody;
|
||||
|
||||
|
||||
if ((leafrefbody = xml_body(xt)) == NULL)
|
||||
return 0;
|
||||
if ((ypath = yang_find((yang_node*)ytype, Y_PATH, NULL)) == NULL){
|
||||
|
|
@ -901,7 +902,7 @@ api_path_fmt2api_path(char *api_path_fmt,
|
|||
clicon_err(OE_UNIX, errno, "cv2str_dup");
|
||||
goto done;
|
||||
}
|
||||
if (percent_encode(str, &strenc) < 0)
|
||||
if (uri_percent_encode(str, &strenc) < 0)
|
||||
goto done;
|
||||
cprintf(cb, "%s", strenc);
|
||||
free(strenc); strenc = NULL;
|
||||
|
|
@ -1495,7 +1496,7 @@ api_path2xml_vec(char **vec,
|
|||
if ((restval_enc = index(name, '=')) != NULL){
|
||||
*restval_enc = '\0';
|
||||
restval_enc++;
|
||||
if (percent_decode(restval_enc, &restval) < 0)
|
||||
if (uri_percent_decode(restval_enc, &restval) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Split into prefix and localname, ignore prefix for now */
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ struct xml_parse_yacc_arg{
|
|||
cxobj *ya_xparent; /* xml parent element*/
|
||||
int ya_skipspace; /* If set, remove all non-terminal bodies (strip pretty-print) */
|
||||
yang_spec *ya_yspec; /* If set, top-level yang-spec */
|
||||
int ya_lex_state; /* lex start condition (AMPERSAND) */
|
||||
};
|
||||
|
||||
extern char *clixon_xml_parsetext;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ int clixon_xml_parsewrap(void)
|
|||
|
||||
%x START
|
||||
%s STATEA
|
||||
%s AMPERSAND
|
||||
%s CMNT
|
||||
%s STR
|
||||
%s TEXTDECL
|
||||
|
|
@ -88,24 +89,31 @@ int clixon_xml_parsewrap(void)
|
|||
}
|
||||
<START>[ \t]+ ;
|
||||
<START>\: return *clixon_xml_parsetext;
|
||||
<START>\n { _YA->ya_linenum++;}
|
||||
<START>"<?xml" { BEGIN(TEXTDECL); return BTEXT;}
|
||||
<START>"/>" { BEGIN(STATEA); return ESLASH; }
|
||||
<START>"<!--" { BEGIN(CMNT); return BCOMMENT; }
|
||||
<START>"</" return BSLASH;
|
||||
<START>[/=] return *clixon_xml_parsetext;
|
||||
<START>\< return *clixon_xml_parsetext;
|
||||
<START>\> { BEGIN(STATEA); return *clixon_xml_parsetext; }
|
||||
<START>\n { _YA->ya_linenum++;}
|
||||
<START>"<?xml" { BEGIN(TEXTDECL); return BTEXT;}
|
||||
<START>"/>" { BEGIN(STATEA); return ESLASH; }
|
||||
<START>"<!--" { BEGIN(CMNT); return BCOMMENT; }
|
||||
<START>"</" return BSLASH;
|
||||
<START>[/=] return *clixon_xml_parsetext;
|
||||
<START>\< return *clixon_xml_parsetext;
|
||||
<START>\> { BEGIN(STATEA); return *clixon_xml_parsetext; }
|
||||
|
||||
<START>\" { BEGIN(STR); return *clixon_xml_parsetext; }
|
||||
<START>. { clixon_xml_parselval.string = yytext; return CHAR; /*XXX:optimize*/ }
|
||||
<START>\" { BEGIN(STR); return *clixon_xml_parsetext; }
|
||||
<START>. { clixon_xml_parselval.string = yytext; return CHARDATA; /*XXX:optimize*/ }
|
||||
|
||||
<STATEA>"</" { BEGIN(START); return BSLASH; }
|
||||
<STATEA>"<!--" { BEGIN(CMNT); return BCOMMENT; }
|
||||
<STATEA>\< { BEGIN(START); return *clixon_xml_parsetext; }
|
||||
<STATEA>& { _YA->ya_lex_state =STATEA;BEGIN(AMPERSAND);}
|
||||
<STATEA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHARDATA);}
|
||||
<STATEA>. { clixon_xml_parselval.string = yytext; return CHARDATA; /*XXX:optimize*/}
|
||||
/* @see xml_chardata_encode */
|
||||
<AMPERSAND>"amp; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = strdup("&"); return CHARDATA;}
|
||||
<AMPERSAND>"lt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = strdup("<"); return CHARDATA;}
|
||||
<AMPERSAND>"gt; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = strdup(">"); return CHARDATA;}
|
||||
<AMPERSAND>"apos; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = strdup("'"); return CHARDATA;}
|
||||
<AMPERSAND>"aquot; " {BEGIN(_YA->ya_lex_state); clixon_xml_parselval.string = strdup("'"); return CHARDATA;}
|
||||
|
||||
<STATEA>"</" { BEGIN(START); return BSLASH; }
|
||||
<STATEA>"<!--" { BEGIN(CMNT); return BCOMMENT; }
|
||||
<STATEA>\< { BEGIN(START); return *clixon_xml_parsetext; }
|
||||
<STATEA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHAR);}
|
||||
<STATEA>. { clixon_xml_parselval.string = yytext; return CHAR; /*XXX:optimize*/}
|
||||
|
||||
<CMNT>"-->" { BEGIN(START); return ECOMMENT; }
|
||||
<CMNT>\n _YA->ya_linenum++;
|
||||
|
|
@ -117,15 +125,15 @@ int clixon_xml_parsewrap(void)
|
|||
<TEXTDECL>\" { BEGIN(STRDQ); return *clixon_xml_parsetext; }
|
||||
<TEXTDECL>\' { BEGIN(STRSQ); return *clixon_xml_parsetext; }
|
||||
|
||||
<STR>[^\"]+ { clixon_xml_parselval.string = strdup(yytext); return CHAR; }
|
||||
<STR>[^\"]+ { clixon_xml_parselval.string = strdup(yytext); return CHARDATA; }
|
||||
<STR>\" { BEGIN(START); return *clixon_xml_parsetext; }
|
||||
|
||||
<STRDQ>1\.[0-9]+ { clixon_xml_parselval.string = strdup(yytext); return CHAR; }
|
||||
<STRDQ>[^\"]+ { clixon_xml_parselval.string = strdup(yytext); return CHAR; }
|
||||
<STRDQ>1\.[0-9]+ { clixon_xml_parselval.string = strdup(yytext); return CHARDATA; }
|
||||
<STRDQ>[^\"]+ { clixon_xml_parselval.string = strdup(yytext); return CHARDATA; }
|
||||
<STRDQ>\" { BEGIN(TEXTDECL); return *clixon_xml_parsetext; }
|
||||
|
||||
<STRSQ>1\.[0-9]+ { clixon_xml_parselval.string = strdup(yytext); return CHAR; }
|
||||
<STRSQ>[^\']+ { clixon_xml_parselval.string = strdup(yytext); return CHAR; }
|
||||
<STRSQ>1\.[0-9]+ { clixon_xml_parselval.string = strdup(yytext); return CHARDATA; }
|
||||
<STRSQ>[^\']+ { clixon_xml_parselval.string = strdup(yytext); return CHARDATA; }
|
||||
<STRSQ>\' { BEGIN(TEXTDECL); return *clixon_xml_parsetext; }
|
||||
|
||||
%%
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
%start topxml
|
||||
|
||||
%token <string> NAME CHAR
|
||||
%token <string> NAME CHARDATA
|
||||
%token VER ENC
|
||||
%token BSLASH ESLASH
|
||||
%token BTEXT ETEXT
|
||||
|
|
@ -329,15 +329,15 @@ topxml : list
|
|||
dcl : BTEXT info encode ETEXT { clicon_debug(3, "dcl->info encode"); }
|
||||
;
|
||||
|
||||
info : VER '=' '\"' CHAR '\"'
|
||||
info : VER '=' '\"' CHARDATA '\"'
|
||||
{ if (xml_parse_version(_YA, $4) <0) YYABORT; }
|
||||
| VER '=' '\'' CHAR '\''
|
||||
| VER '=' '\'' CHARDATA '\''
|
||||
{ if (xml_parse_version(_YA, $4) <0) YYABORT; }
|
||||
|
|
||||
;
|
||||
|
||||
encode : ENC '=' '\"' CHAR '\"' {free($4);}
|
||||
| ENC '=' '\'' CHAR '\'' {free($4);}
|
||||
encode : ENC '=' '\"' CHARDATA '\"' {free($4);}
|
||||
| ENC '=' '\'' CHARDATA '\'' {free($4);}
|
||||
;
|
||||
|
||||
element : '<' qname attrs element1
|
||||
|
|
@ -372,8 +372,8 @@ list : list content { clicon_debug(3, "list -> list content"); }
|
|||
|
||||
content : element { clicon_debug(3, "content -> element"); }
|
||||
| comment { clicon_debug(3, "content -> comment"); }
|
||||
| CHAR { if (xml_parse_content(_YA, $1) < 0) YYABORT;
|
||||
clicon_debug(3, "content -> CHAR %s", $1); }
|
||||
| CHARDATA { if (xml_parse_content(_YA, $1) < 0) YYABORT;
|
||||
clicon_debug(3, "content -> CHARDATA %s", $1); }
|
||||
| { clicon_debug(3, "content -> "); }
|
||||
;
|
||||
|
||||
|
|
@ -394,7 +394,7 @@ attqname : NAME {$$ = $1;}
|
|||
;
|
||||
|
||||
|
||||
attvalue : '\"' CHAR '\"' { $$=$2; /* $2 must be consumed */}
|
||||
attvalue : '\"' CHARDATA '\"' { $$=$2; /* $2 must be consumed */}
|
||||
| '\"' '\"' { $$=strdup(""); /* $2 must be consumed */}
|
||||
;
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,11 @@ expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0" "^$"
|
|||
new "cli show configuration"
|
||||
expectfn "$clixon_cli -1 -f $cfg show conf cli" "^interfaces interface name eth/0/0" "interfaces interface enabled true$"
|
||||
|
||||
new "cli configure using encoded chars data <&"
|
||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface eth/0/0 description \"foo<&bar\"" ""
|
||||
new "cli configure using encoded chars name <&"
|
||||
expectfn "$clixon_cli -1 -f $cfg set interfaces interface fddi&< type eth" ""
|
||||
|
||||
new "cli failed validate"
|
||||
expectfn "$clixon_cli -1 -f $cfg -l o validate" "Missing mandatory variable"
|
||||
|
||||
|
|
|
|||
|
|
@ -98,11 +98,17 @@ expecteof "$clixon_netconf -qf $cfg" "<rpc><validate><source><candidate/></sourc
|
|||
new "netconf commit"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf edit config replace XXX is merge?"
|
||||
new "netconf edit config merge"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth2</name><type>eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf edit ampersand encoding(<&): name:'eth&' type:'t<>'"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth& </name><type>t< > </type></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf get replaced config"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><get-config><source><candidate/></source></get-config></rpc>]]>]]>" "^<rpc-reply><data><interfaces><interface><name>eth& </name><type>t< > </type><enabled>true</enabled></interface><interface><name>eth1</name><type>eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>$"
|
||||
|
||||
new "cli show configuration eth& - encoding tests"
|
||||
expectfn "$clixon_cli -1 -f $cfg show conf cli" "interfaces interface name eth&"
|
||||
|
||||
new "netconf discard-changes"
|
||||
expecteof "$clixon_netconf -qf $cfg" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ APPNAME=example
|
|||
cfg=$dir/conf_yang.xml
|
||||
fyang=$dir/type.yang
|
||||
|
||||
|
||||
cat <<EOF > $cfg
|
||||
<config>
|
||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||
|
|
@ -164,7 +163,7 @@ new "netconf validate ok"
|
|||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf set ab wrong"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><list><ip>a.b&c.d</ip></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><list><ip>a.b& c.d</ip></list></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
||||
|
||||
new "netconf validate"
|
||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply><rpc-error>"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue