diff --git a/CHANGELOG.md b/CHANGELOG.md index cfc98c42..8a0ddc86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ * Get it with `clicon_nsctx_global_get(h)` * Added wildcard `*` as a mode to `CLICON_MODE` in clispec files * If you set "CLICON_MODE="*";" in a clispec file it means that syntax will appear in all CLI spec modes. -* State callbacks provided by user are validated. If they are invalid an internal error is returned. +* State callbacks provided by user are validated. If they are invalid an internal error is returned, example, with error-tag: `operation-failed`and with error-message containing. `Internal error, state callback returned invalid XML`. * Fixed multi-namespace for augmented state which was not covered in 4.2.0. ### API changes on existing features (you may need to change your code) diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 6ca91325..1dde1a65 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -134,19 +134,25 @@ clixon_plugin_statedata(clicon_handle h, if (ret > 0 && (ret = xml_yang_validate_add(h, x, &xerr)) < 0) goto done; if (ret == 0){ - if ((cberr = cbuf_new()) ==NULL){ - clicon_err(OE_XML, errno, "cbuf_new"); - goto done; + cxobj *xe; + cxobj *xb; + + if ((xe = xpath_first(xerr, NULL, "//error-tag")) != NULL && + (xb = xml_body_get(xe))){ + if (xml_value_set(xb, "operation-failed") < 0) + goto done; + } + if ((xe = xpath_first(xerr, NULL, "//error-message")) != NULL && + (xb = xml_body_get(xe))){ + if (xml_value_append(xb, " Internal error, state callback returned invalid XML") < 0) + goto done; } - cprintf(cberr, "Internal error: state callback returned invalid XML: "); - if (netconf_err2cb(xpath_first(xerr, NULL, "rpc-error"), cberr) < 0) - goto done; if (*xret){ xml_free(*xret); *xret = NULL; } - if (netconf_operation_failed_xml(xret, "application", cbuf_get(cberr))< 0) - goto done; + *xret = xerr; + xerr = NULL; goto fail; } #if 1 diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index 54b9072d..040d65eb 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -953,7 +953,7 @@ netconf_operation_not_supported(cbuf *cb, * some reason not covered by any other error condition. * @param[out] cb CLIgen buf. Error XML is written in this buffer * @param[in] type Error type: "rpc", "application" or "protocol" - * @param[in] message Error message + * @param[in] message Error message (will be XML encoded) * @see netconf_operation_failed_xml Same but returns XML tree */ int @@ -994,6 +994,7 @@ int netconf_operation_failed_xml(cxobj **xret, char *type, char *message) + { int retval =-1; cxobj *xerr; @@ -1009,7 +1010,8 @@ netconf_operation_failed_xml(cxobj **xret, goto done; if (xml_parse_va(&xerr, NULL, "%s" "operation-failed" - "error", type) < 0) + "error", + type) < 0) goto done; if (message){ if (xml_chardata_encode(&encstr, "%s", message) < 0) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 2caaea91..63daa827 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1274,13 +1274,27 @@ xml_yang_validate_all(clicon_handle h, int nr; int ret; cxobj *x; + char *namespace = NULL; + cbuf *cb = NULL; /* if not given by argument (overide) use default link and !Node has a config sub-statement and it is false */ ys=xml_spec(xt); if (ys==NULL){ - if (netconf_unknown_element_xml(xret, "application", xml_name(xt), NULL) < 0) + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; + } + if (xml2ns(xt, xml_prefix(xt), &namespace) < 0) + goto done; + if (namespace){ + cprintf(cb, "namespace is: %s", namespace); + if (netconf_unknown_element_xml(xret, "application", xml_name(xt), cbuf_get(cb)) < 0) + goto done; + } + else + if (netconf_unknown_element_xml(xret, "application", xml_name(xt), NULL) < 0) + goto done; goto fail; } if (yang_config(ys) != 0){ @@ -1326,7 +1340,7 @@ xml_yang_validate_all(clicon_handle h, goto done; if (!nr){ ye = yang_find(yc, Y_ERROR_MESSAGE, NULL); - if (netconf_operation_failed_xml(xret, "application", + if (netconf_operation_failed_xml(xret, "application", ye?ye->ys_argument:"must xpath validation failed") < 0) goto done; goto fail; @@ -1338,7 +1352,7 @@ xml_yang_validate_all(clicon_handle h, if ((nr = xpath_vec_bool(xt, NULL, "%s", xpath)) < 0) goto done; if (!nr){ - if (netconf_operation_failed_xml(xret, "application", + if (netconf_operation_failed_xml(xret, "application", "when xpath validation failed") < 0) goto done; goto fail; @@ -1363,6 +1377,8 @@ xml_yang_validate_all(clicon_handle h, ok: retval = 1; done: + if (cb) + cbuf_free(cb); return retval; fail: retval = 0;