Fixed: backend exit when receiving invalid NETCONF get select XPath

Added XML encoding to XPaths in `select` attribute
This commit is contained in:
Olof hagsand 2024-05-15 13:44:12 +02:00
parent 989a7b38ee
commit 03a9c03b1c
11 changed files with 152 additions and 83 deletions

View file

@ -45,8 +45,18 @@ Users may have to change how they access the system
* If backend is started with `-s startup` or `-s running` then `<db>_db` is read if `<db>.d/0.xml` is not found * If backend is started with `-s startup` or `-s running` then `<db>_db` is read if `<db>.d/0.xml` is not found
* Openssl mandatory for all configs, not only restconf * Openssl mandatory for all configs, not only restconf
### C/CLI-API changes on existing features
Developers may need to change their code
* XML encoding added a `quotes` parameter for attribute encoding, update as follows:
* `xml_chardata_encode(e, fmt,...)` --> `xml_chardata_encode(e, 0, fmt,...)`
* `xml_chardata_cbuf_append(cb, str)` --> `xml_chardata_cbuf_append(cb, 0, str)`
### Corrected Bugs ### Corrected Bugs
* Fixed: backend exit when receiving invalid NETCONF get select XPath
* Added XML encoding to XPaths in `select` attribute
* Fixed: Fail on return errors when reading from datastore * Fixed: Fail on return errors when reading from datastore
* Can happen if running is not upgraded for example * Can happen if running is not upgraded for example
* Fixed: [Duplicate config files in configdir causes merge problems -> set ? = NULL](https://github.com/clicon/clixon/issues/510) * Fixed: [Duplicate config files in configdir causes merge problems -> set ? = NULL](https://github.com/clicon/clixon/issues/510)

View file

@ -1326,7 +1326,7 @@ from_client_get_schema(clixon_handle h,
if (clicon_file_cbuf(filename, cbyang) < 0) if (clicon_file_cbuf(filename, cbyang) < 0)
goto done; goto done;
} }
xml_chardata_cbuf_append(cbret, cbuf_get(cbyang)); xml_chardata_cbuf_append(cbret, 0, cbuf_get(cbyang));
cprintf(cbret, "</data></rpc-reply>"); cprintf(cbret, "</data></rpc-reply>");
ok: ok:
retval = 0; retval = 0;
@ -1677,7 +1677,7 @@ from_client_msg(clixon_handle h,
if ((ret = clixon_xml_parse_string(msg, YB_RPC, yspec, &xt, &xret)) < 0){ if ((ret = clixon_xml_parse_string(msg, YB_RPC, yspec, &xt, &xret)) < 0){
if (netconf_malformed_message(cbret, "XML parse error") < 0) if (netconf_malformed_message(cbret, "XML parse error") < 0)
goto done; goto done;
goto done; goto reply;
} }
if (ret == 0){ if (ret == 0){
if (clixon_xml2cbuf(cbret, xret, 0, 0, NULL, -1, 0) < 0) if (clixon_xml2cbuf(cbret, xret, 0, 0, NULL, -1, 0) < 0)

View file

@ -808,6 +808,7 @@ get_common(clixon_handle h,
char *reason = NULL; char *reason = NULL;
cbuf *cbmsg = NULL; /* For error msg */ cbuf *cbmsg = NULL; /* For error msg */
char *xpath0; char *xpath0;
char *xpath01 = NULL;
cbuf *cbreason = NULL; cbuf *cbreason = NULL;
int list_pagination = 0; int list_pagination = 0;
cxobj **xvec = NULL; cxobj **xvec = NULL;
@ -828,6 +829,8 @@ get_common(clixon_handle h,
if ((xfilter = xml_find(xe, "filter")) != NULL){ if ((xfilter = xml_find(xe, "filter")) != NULL){
if ((xpath0 = xml_find_value(xfilter, "select"))==NULL) if ((xpath0 = xml_find_value(xfilter, "select"))==NULL)
xpath0 = "/"; xpath0 = "/";
if (xml_chardata_decode(&xpath01, "%s", xpath0) < 0)
goto done;
/* Create namespace context for xpath from <filter> /* Create namespace context for xpath from <filter>
* The set of namespace declarations are those in scope on the * The set of namespace declarations are those in scope on the
* <filter> element. * <filter> element.
@ -835,7 +838,7 @@ get_common(clixon_handle h,
else else
if (xml_nsctx_node(xfilter, &nsc0) < 0) if (xml_nsctx_node(xfilter, &nsc0) < 0)
goto done; goto done;
if ((ret = xpath2canonical(xpath0, nsc0, yspec, &xpath, &nsc, &cbreason)) < 0) if ((ret = xpath2canonical(xpath01, nsc0, yspec, &xpath, &nsc, &cbreason)) < 0)
goto done; goto done;
if (ret == 0){ if (ret == 0){
if (netconf_bad_attribute(cbret, "application", if (netconf_bad_attribute(cbret, "application",
@ -1037,6 +1040,8 @@ get_common(clixon_handle h,
xml_free(xerr); xml_free(xerr);
if (xpath) if (xpath)
free(xpath); free(xpath);
if (xpath01)
free(xpath01);
return retval; return retval;
} }

View file

@ -95,8 +95,8 @@ char *clixon_string_del_join(char *str1, char *del, char *str2);
int clixon_strsplit(char *nodeid, const int delim, char **prefix, char **id); int clixon_strsplit(char *nodeid, const int delim, char **prefix, char **id);
int uri_str2cvec(char *string, char delim1, char delim2, int decode, cvec **cvp); int uri_str2cvec(char *string, char delim1, char delim2, int decode, cvec **cvp);
int uri_percent_encode(char **encp, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); int uri_percent_encode(char **encp, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
int xml_chardata_encode(char **escp, const char *fmt, ... ) __attribute__ ((format (printf, 2, 3))); int xml_chardata_encode(char **escp, int quote, const char *fmt, ... ) __attribute__ ((format (printf, 3, 4)));
int xml_chardata_cbuf_append(cbuf *cb, char *str); int xml_chardata_cbuf_append(cbuf *cb, int quote, char *str);
int xml_chardata_decode(char **escp, const char *fmt,...); int xml_chardata_decode(char **escp, const char *fmt,...);
int uri_percent_decode(char *enc, char **str); int uri_percent_decode(char *enc, char **str);

View file

@ -134,7 +134,7 @@ netconf_in_use(cbuf *cb,
type) <0) type) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -189,7 +189,7 @@ netconf_invalid_value_xml(cxobj **xret,
"<error-severity>error</error-severity>", type) < 0) "<error-severity>error</error-severity>", type) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-message>%s</error-message>", encstr) < 0) "<error-message>%s</error-message>", encstr) < 0)
@ -256,7 +256,7 @@ netconf_too_big(cbuf *cb,
type) <0) type) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -313,7 +313,7 @@ netconf_missing_attribute_xml(cxobj **xret,
"<error-severity>error</error-severity>", type, attr) < 0) "<error-severity>error</error-severity>", type, attr) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -429,7 +429,7 @@ netconf_bad_attribute_xml(cxobj **xret,
"<error-severity>error</error-severity>", type, info) < 0) "<error-severity>error</error-severity>", type, info) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -469,7 +469,7 @@ netconf_unknown_attribute(cbuf *cb,
NETCONF_BASE_NAMESPACE, type, info) <0) NETCONF_BASE_NAMESPACE, type, info) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -529,7 +529,7 @@ netconf_common_xml(cxobj **xret,
type, tag, infotag, element, infotag) < 0) type, tag, infotag, element, infotag) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -799,7 +799,7 @@ netconf_access_denied_xml(cxobj **xret,
"<error-severity>error</error-severity>", type) < 0) "<error-severity>error</error-severity>", type) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -838,7 +838,7 @@ netconf_lock_denied(cbuf *cb,
NETCONF_BASE_NAMESPACE, info) <0) NETCONF_BASE_NAMESPACE, info) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -879,7 +879,7 @@ netconf_resource_denied(cbuf *cb,
NETCONF_BASE_NAMESPACE, type) <0) NETCONF_BASE_NAMESPACE, type) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -921,7 +921,7 @@ netconf_rollback_failed(cbuf *cb,
NETCONF_BASE_NAMESPACE, type) <0) NETCONF_BASE_NAMESPACE, type) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -962,7 +962,7 @@ netconf_data_exists(cbuf *cb,
NETCONF_BASE_NAMESPACE) <0) NETCONF_BASE_NAMESPACE) <0)
goto err; goto err;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0) if (cprintf(cb, "<error-message>%s</error-message>", encstr) < 0)
goto err; goto err;
@ -1047,7 +1047,7 @@ netconf_data_missing_xml(cxobj **xret,
"<error-severity>error</error-severity>") < 0) "<error-severity>error</error-severity>") < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-message>%s</error-message>", encstr) < 0) "<error-message>%s</error-message>", encstr) < 0)
@ -1101,7 +1101,7 @@ netconf_missing_choice_xml(cxobj **xret,
/* error-path: Path to the element with the missing choice. */ /* error-path: Path to the element with the missing choice. */
if (xml2xpath(x, NULL, 0, 0, &path) < 0) if (xml2xpath(x, NULL, 0, 0, &path) < 0)
goto done; goto done;
if (xml_chardata_encode(&encpath, "%s", path) < 0) if (xml_chardata_encode(&encpath, 0, "%s", path) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-type>application</error-type>" "<error-type>application</error-type>"
@ -1115,7 +1115,7 @@ netconf_missing_choice_xml(cxobj **xret,
name) < 0) name) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL,
"<error-message>%s</error-message>", encstr) < 0) "<error-message>%s</error-message>", encstr) < 0)
@ -1178,7 +1178,7 @@ netconf_operation_not_supported_xml(cxobj **xret,
type) < 0) type) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -1296,7 +1296,7 @@ netconf_operation_failed_xml(cxobj **xret,
type) < 0) type) < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -1384,7 +1384,7 @@ netconf_malformed_message_xml(cxobj **xret,
"<error-severity>error</error-severity>") < 0) "<error-severity>error</error-severity>") < 0)
goto done; goto done;
if (message){ if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0) if (xml_chardata_encode(&encstr, 0, "%s", message) < 0)
goto done; goto done;
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>", if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0) encstr) < 0)
@ -1479,7 +1479,7 @@ netconf_data_not_unique_xml(cxobj **xret,
goto done; goto done;
if (xml2xpath(x, NULL, 0, 0, &path) < 0) if (xml2xpath(x, NULL, 0, 0, &path) < 0)
goto done; goto done;
if (xml_chardata_encode(&encpath, "%s", path) < 0) if (xml_chardata_encode(&encpath, 0, "%s", path) < 0)
goto done; goto done;
while ((cvi = cvec_each(cvk, cvi)) != NULL){ while ((cvi = cvec_each(cvk, cvi)) != NULL){
if (clixon_xml_parse_va(YB_NONE, NULL, &xinfo, NULL, if (clixon_xml_parse_va(YB_NONE, NULL, &xinfo, NULL,
@ -1539,7 +1539,7 @@ netconf_minmax_elements_xml(cxobj **xret,
if (xml_parent(xp)){ /* Dont include root, eg <config> */ if (xml_parent(xp)){ /* Dont include root, eg <config> */
if (xml2xpath(xp, NULL, 0, 0, &path) < 0) if (xml2xpath(xp, NULL, 0, 0, &path) < 0)
goto done; goto done;
if (xml_chardata_encode(&encpath, "%s", path) < 0) if (xml_chardata_encode(&encpath, 0, "%s", path) < 0)
goto done; goto done;
} }
if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>protocol</error-type>" if (clixon_xml_parse_va(YB_NONE, NULL, &xerr, NULL, "<error-type>protocol</error-type>"
@ -1817,7 +1817,7 @@ netconf_capabilites(clixon_handle h,
/* Check if RFC7895 loaded and revision found */ /* Check if RFC7895 loaded and revision found */
if ((ietf_yang_library_revision = yang_modules_revision(h)) != NULL){ if ((ietf_yang_library_revision = yang_modules_revision(h)) != NULL){
if (xml_chardata_encode(&encstr, "urn:ietf:params:netconf:capability:yang-library:1.0?revision=%s&module-set-id=%s", if (xml_chardata_encode(&encstr, 0, "urn:ietf:params:netconf:capability:yang-library:1.0?revision=%s&module-set-id=%s",
ietf_yang_library_revision, ietf_yang_library_revision,
module_set_id) < 0) module_set_id) < 0)
goto done; goto done;
@ -1838,7 +1838,7 @@ netconf_capabilites(clixon_handle h,
cprintf(cb, "<capability>urn:ietf:params:netconf:capability:xpath:1.0</capability>"); cprintf(cb, "<capability>urn:ietf:params:netconf:capability:xpath:1.0</capability>");
/* rfc6243 with-defaults capability modes */ /* rfc6243 with-defaults capability modes */
cprintf(cb, "<capability>"); cprintf(cb, "<capability>");
xml_chardata_cbuf_append(cb, "urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged"); xml_chardata_cbuf_append(cb, 0, "urn:ietf:params:netconf:capability:with-defaults:1.0?basic-mode=explicit&also-supported=report-all,trim,report-all-tagged");
cprintf(cb, "</capability>"); cprintf(cb, "</capability>");
/* RFC5277 Notification Capability */ /* RFC5277 Notification Capability */
cprintf(cb, "<capability>%s</capability>", NETCONF_NOTIFICATION_CAPABILITY); cprintf(cb, "<capability>%s</capability>", NETCONF_NOTIFICATION_CAPABILITY);

View file

@ -826,9 +826,9 @@ clixon_process_status(clixon_handle h,
* command) and therefore needs explicit encoding */ * command) and therefore needs explicit encoding */
for (i=0; i<pe->pe_argc-1; i++){ for (i=0; i<pe->pe_argc-1; i++){
if (i) if (i)
if (xml_chardata_cbuf_append(cbret, " ") < 0) if (xml_chardata_cbuf_append(cbret, 0, " ") < 0)
goto done; goto done;
if (xml_chardata_cbuf_append(cbret, pe->pe_argv[i]) < 0) if (xml_chardata_cbuf_append(cbret, 0, pe->pe_argv[i]) < 0)
goto done; goto done;
} }
cprintf(cbret, "</command>"); cprintf(cbret, "</command>");

View file

@ -549,9 +549,11 @@ clicon_rpc_get_config(clixon_handle h,
cprintf(cb, " %s", NETCONF_MESSAGE_ID_ATTR); /* XXX: use incrementing sequence */ cprintf(cb, " %s", NETCONF_MESSAGE_ID_ATTR); /* XXX: use incrementing sequence */
cprintf(cb, "><get-config><source><%s/></source>", db); cprintf(cb, "><get-config><source><%s/></source>", db);
if (xpath && strlen(xpath)){ if (xpath && strlen(xpath)){
cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"%s\"", cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"",
NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX);
xpath); if (xml_chardata_cbuf_append(cb, 1, xpath) < 0)
goto done;
cprintf(cb, "\"");
if (xml_nsctx_cbuf(cb, nsc) < 0) if (xml_nsctx_cbuf(cb, nsc) < 0)
goto done; goto done;
cprintf(cb, "/>"); cprintf(cb, "/>");
@ -1051,9 +1053,11 @@ clicon_rpc_get2(clixon_handle h,
cprintf(cb, ">"); /* get */ cprintf(cb, ">"); /* get */
/* If xpath, add a filter */ /* If xpath, add a filter */
if (xpath && strlen(xpath)) { if (xpath && strlen(xpath)) {
cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"%s\"", cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"",
NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX);
xpath); if (xml_chardata_cbuf_append(cb, 1, xpath) < 0)
goto done;
cprintf(cb, "\"");
if (xml_nsctx_cbuf(cb, nsc) < 0) if (xml_nsctx_cbuf(cb, nsc) < 0)
goto done; goto done;
cprintf(cb, "/>"); cprintf(cb, "/>");
@ -1208,9 +1212,11 @@ clicon_rpc_get_pageable_list(clixon_handle h,
cprintf(cb, ">"); /* get */ cprintf(cb, ">"); /* get */
/* If xpath, add a filter */ /* If xpath, add a filter */
if (xpath && strlen(xpath)) { if (xpath && strlen(xpath)) {
cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"%s\"", cprintf(cb, "<%s:filter %s:type=\"xpath\" %s:select=\"",
NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX, NETCONF_BASE_PREFIX);
xpath); if (xml_chardata_cbuf_append(cb, 1, xpath) < 0)
goto done;
cprintf(cb, "\"");
if (xml_nsctx_cbuf(cb, nsc) < 0) if (xml_nsctx_cbuf(cb, nsc) < 0)
goto done; goto done;
cprintf(cb, "/>"); cprintf(cb, "/>");
@ -1668,11 +1674,14 @@ clicon_rpc_create_subscription(clixon_handle h,
cprintf(cb, ">"); cprintf(cb, ">");
cprintf(cb, "<create-subscription xmlns=\"%s\">" cprintf(cb, "<create-subscription xmlns=\"%s\">"
"<stream>%s</stream>" "<stream>%s</stream>"
"<filter type=\"xpath\" select=\"%s\" />" "<filter type=\"xpath\" select=\"",
"</create-subscription>",
EVENT_RFC5277_NAMESPACE, EVENT_RFC5277_NAMESPACE,
stream?stream:"", stream?stream:"");
filter?filter:""); if (filter) {
if (xml_chardata_cbuf_append(cb, 1, filter) < 0)
goto done;
}
cprintf(cb, "\" />" "</create-subscription>");
cprintf(cb, "</rpc>"); cprintf(cb, "</rpc>");
if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL) if ((msg = clicon_msg_encode(session_id, "%s", cbuf_get(cb))) == NULL)
goto done; goto done;

View file

@ -374,10 +374,9 @@ uri_percent_encode(char **encp,
va_start(args, fmt); /* real */ va_start(args, fmt); /* real */
fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1; fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1;
va_end(args); va_end(args);
/* Now str is the combined fmt + ... */ /* Now str is the combined fmt + ...
* Step (2) encode and expand str --> enc
/* Step (2) encode and expand str --> enc */ * This is max */
/* This is max */
len = strlen(str)*3+1; len = strlen(str)*3+1;
if ((enc = malloc(len)) == NULL){ if ((enc = malloc(len)) == NULL){
clixon_err(OE_UNIX, errno, "malloc"); clixon_err(OE_UNIX, errno, "malloc");
@ -462,13 +461,14 @@ uri_percent_decode(char *enc,
/*! Encode escape characters according to XML definition /*! Encode escape characters according to XML definition
* *
* @param[out] encp Encoded malloced output string * @param[out] encp Encoded malloced output string
* @param[in] quote Also encode ' and " (eg for attributes)
* @param[in] fmt Not-encoded input string (stdarg format string) * @param[in] fmt Not-encoded input string (stdarg format string)
* @param[in] ... stdarg variable parameters * @param[in] ... stdarg variable parameters
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* @code * @code
* char *encstr = NULL; * char *encstr = NULL;
* if (xml_chardata_encode(&encstr, "fmtstr<>& %s", "substr<>") < 0) * if (xml_chardata_encode(&encstr, 0, "fmtstr<>& %s", "substr<>") < 0)
* err; * err;
* if (encstr) * if (encstr)
* free(encstr); * free(encstr);
@ -487,6 +487,7 @@ uri_percent_decode(char *enc,
*/ */
int int
xml_chardata_encode(char **escp, xml_chardata_encode(char **escp,
int quote,
const char *fmt,...) const char *fmt,...)
{ {
int retval = -1; int retval = -1;
@ -512,10 +513,9 @@ xml_chardata_encode(char **escp,
va_start(args, fmt); /* real */ va_start(args, fmt); /* real */
fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1; fmtlen = vsnprintf(str, fmtlen, fmt, args) + 1;
va_end(args); va_end(args);
/* Now str is the combined fmt + ... */ /* Now str is the combined fmt + ...
* Step (2) encode and expand str --> enc
/* Step (2) encode and expand str --> enc */ * First compute length (do nothing) */
/* First compute length (do nothing) */
len = 0; cdata = 0; len = 0; cdata = 0;
slen = strlen(str); slen = strlen(str);
for (i=0; i<slen; i++){ for (i=0; i<slen; i++){
@ -540,6 +540,18 @@ xml_chardata_encode(char **escp,
case '>': case '>':
len += strlen("&gt;"); len += strlen("&gt;");
break; break;
case '\'':
if (quote)
len += strlen("&apos;");
else
len++;
break;
case '"':
if (quote)
len += strlen("&quot;");
else
len++;
break;
default: default:
len++; len++;
} }
@ -551,7 +563,6 @@ xml_chardata_encode(char **escp,
goto done; goto done;
} }
memset(esc, 0, len); memset(esc, 0, len);
/* Same code again, but now actually encode into output buffer */ /* Same code again, but now actually encode into output buffer */
j = 0; cdata = 0; j = 0; cdata = 0;
slen = strlen(str); slen = strlen(str);
@ -592,6 +603,28 @@ xml_chardata_encode(char **escp,
} }
j += l; j += l;
break; break;
case '\'':
if (quote){
if ((l=snprintf(&esc[j], 7, "&apos;")) < 0){
clixon_err(OE_UNIX, errno, "snprintf");
goto done;
}
j += l;
}
else
esc[j++] = str[i];
break;
case '"':
if (quote){
if ((l=snprintf(&esc[j], 7, "&quot;")) < 0){
clixon_err(OE_UNIX, errno, "snprintf");
goto done;
}
j += l;
}
else
esc[j++] = str[i];
break;
default: default:
esc[j++] = str[i]; esc[j++] = str[i];
} }
@ -609,24 +642,25 @@ xml_chardata_encode(char **escp,
/*! Escape characters according to XML definition and append to cbuf /*! Escape characters according to XML definition and append to cbuf
* *
* @param[in] cb CLIgen buf * @param[in] cb CLIgen buf
* @param[in] quote Also encode ' and " (eg for attributes)
* @param[in] str Not-encoded input string * @param[in] str Not-encoded input string
* @retdata 0 OK * @retdata 0 OK
* @see xml_chardata_encode for the generic function * @see xml_chardata_encode for the generic function
*/ */
int int
xml_chardata_cbuf_append(cbuf *cb, xml_chardata_cbuf_append(cbuf *cb,
int quote,
char *str) char *str)
{ {
int retval = -1; int retval = -1;
int i; int i;
int cdata; /* when set, skip encoding */ int cdata; /* when set, skip encoding */
size_t len; size_t len;
/* The orignal of this code is in xml_chardata_encode */ /* The orignal of this code is in xml_chardata_encode */
/* Step: encode and expand str --> enc */ /* Step: encode and expand str --> enc */
/* Same code again, but now actually encode into output buffer */ /* Same code again, but now actually encode into output buffer */
cdata = 0; cdata = 0;
len = strlen(str); len = strlen(str);
for (i=0; i<len; i++){ for (i=0; i<len; i++){
if (cdata){ if (cdata){
@ -638,27 +672,38 @@ xml_chardata_cbuf_append(cbuf *cb,
cbuf_append(cb, str[i]); cbuf_append(cb, str[i]);
} }
else else
switch (str[i]){ switch (str[i]){
case '&': case '&':
cbuf_append_str(cb, "&amp;"); cbuf_append_str(cb, "&amp;");
break;
case '<':
if (strncmp(&str[i], "<![CDATA[", strlen("<![CDATA[")) == 0){
cbuf_append(cb, str[i]);
cdata++;
break; break;
case '<':
if (strncmp(&str[i], "<![CDATA[", strlen("<![CDATA[")) == 0){
cbuf_append(cb, str[i]);
cdata++;
break;
}
cbuf_append_str(cb, "&lt;");
break;
case '>':
cbuf_append_str(cb, "&gt;");
break;
case '\'':
if (quote)
cbuf_append_str(cb, "&apos;");
else
cbuf_append(cb, str[i]);
break;
case '"':
if (quote)
cbuf_append_str(cb, "&quot;");
else
cbuf_append(cb, str[i]);
break;
default:
cbuf_append(cb, str[i]);
} }
cbuf_append_str(cb, "&lt;");
break;
case '>':
cbuf_append_str(cb, "&gt;");
break;
default:
cbuf_append(cb, str[i]);
}
} }
retval = 0; retval = 0;
// done:
return retval; return retval;
} }

View file

@ -264,7 +264,7 @@ xml2file_recurse(FILE *f,
case CX_BODY: case CX_BODY:
if ((val = xml_value(x)) == NULL) /* incomplete tree */ if ((val = xml_value(x)) == NULL) /* incomplete tree */
break; break;
if (xml_chardata_encode(&encstr, "%s", val) < 0) if (xml_chardata_encode(&encstr, 0, "%s", val) < 0)
goto done; goto done;
(*fn)(f, "%s", encstr); (*fn)(f, "%s", encstr);
break; break;
@ -586,7 +586,7 @@ xml2cbuf_recurse(cbuf *cb,
case CX_BODY: case CX_BODY:
if ((val = xml_value(x)) == NULL) /* incomplete tree */ if ((val = xml_value(x)) == NULL) /* incomplete tree */
break; break;
if (xml_chardata_cbuf_append(cb, val) < 0) if (xml_chardata_cbuf_append(cb, 0, val) < 0)
goto done; goto done;
break; break;
case CX_ATTR: case CX_ATTR:
@ -856,7 +856,7 @@ _xml_parse(const char *str,
int failed = 0; /* yang assignment */ int failed = 0; /* yang assignment */
int i; int i;
clixon_debug(CLIXON_DBG_XML | CLIXON_DBG_DETAIL, ""); clixon_debug(CLIXON_DBG_PARSE, "%s", str);
if (strlen(str) == 0){ if (strlen(str) == 0){
return 1; /* OK */ return 1; /* OK */
} }
@ -899,7 +899,6 @@ _xml_parse(const char *str,
if (ret == 0) if (ret == 0)
failed++; failed++;
break; break;
case YB_MODULE_NEXT: case YB_MODULE_NEXT:
if ((ret = xml_bind_yang(NULL, x, YB_MODULE, yspec, xerr)) < 0) if ((ret = xml_bind_yang(NULL, x, YB_MODULE, yspec, xerr)) < 0)
goto done; goto done;
@ -935,6 +934,7 @@ _xml_parse(const char *str,
goto done; goto done;
retval = 1; retval = 1;
done: done:
clixon_debug(CLIXON_DBG_PARSE, "retval:%d", retval);
clixon_xml_parsel_exit(&xy); clixon_xml_parsel_exit(&xy);
if (xy.xy_parse_string != NULL) if (xy.xy_parse_string != NULL)
free(xy.xy_parse_string); free(xy.xy_parse_string);
@ -1332,13 +1332,13 @@ xml_diff2cbuf_leaf(cbuf *cb,
} }
/* Encode data to XML */ /* Encode data to XML */
if (b0){ if (b0){
if (xml_chardata_encode(&e0, "%s", b0) < 0) if (xml_chardata_encode(&e0, 0, "%s", b0) < 0)
goto done; goto done;
} }
else else
e0 = NULL; e0 = NULL;
if (b1){ if (b1){
if (xml_chardata_encode(&e1, "%s", b1) < 0) if (xml_chardata_encode(&e1, 0, "%s", b1) < 0)
goto done; goto done;
} }
else else

View file

@ -1397,7 +1397,7 @@ xml_find_index_yang(cxobj *xp,
revert++; revert++;
break; break;
} }
if (xml_chardata_encode(&encstr, "%s", cv_string_get(cvi)) < 0) if (xml_chardata_encode(&encstr, 0, "%s", cv_string_get(cvi)) < 0)
goto done; goto done;
cprintf(cb, "<%s>%s</%s>", kname, encstr, kname); cprintf(cb, "<%s>%s</%s>", kname, encstr, kname);
free(encstr); free(encstr);
@ -1413,7 +1413,7 @@ xml_find_index_yang(cxobj *xp,
goto done; goto done;
} }
cvi = cvec_i(cvk, 0); cvi = cvec_i(cvk, 0);
if (xml_chardata_encode(&encstr, "%s", cv_string_get(cvi)) < 0) if (xml_chardata_encode(&encstr, 0, "%s", cv_string_get(cvi)) < 0)
goto done; goto done;
cprintf(cb, "<%s>%s</%s>", name, encstr, name); cprintf(cb, "<%s>%s</%s>", name, encstr, name);
free(encstr); free(encstr);
@ -1433,7 +1433,7 @@ xml_find_index_yang(cxobj *xp,
yang_flag_get(yi, YANG_FLAG_INDEX) == 0) yang_flag_get(yi, YANG_FLAG_INDEX) == 0)
goto revert; goto revert;
cbuf_reset(cb); cbuf_reset(cb);
if (xml_chardata_encode(&encstr, "%s", cv_string_get(cvi)) < 0) if (xml_chardata_encode(&encstr, 0, "%s", cv_string_get(cvi)) < 0)
goto done; goto done;
cprintf(cb, "<%s><%s>%s</%s></%s>", name, iname, encstr, iname, name); cprintf(cb, "<%s><%s>%s</%s></%s>", name, iname, encstr, iname, name);
free(encstr); free(encstr);

View file

@ -637,7 +637,7 @@ yang_schema_mount_statistics(clixon_handle h,
if (xml2xpath(xmp, NULL, 1, 0, &xpath) < 0) if (xml2xpath(xmp, NULL, 1, 0, &xpath) < 0)
goto done; goto done;
cprintf(cb, "<module-set><name>mountpoint: "); cprintf(cb, "<module-set><name>mountpoint: ");
xml_chardata_cbuf_append(cb, xpath); xml_chardata_cbuf_append(cb, 0, xpath);
cprintf(cb, "</name>"); cprintf(cb, "</name>");
nr = 0; sz = 0; nr = 0; sz = 0;
if (yang_stats(yspec, &nr, &sz) < 0) if (yang_stats(yspec, &nr, &sz) < 0)