diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aefe207..8864ca1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ Developers may need to change their code ### Corrected Bugs +* Fixed error memory in RESTCONF PATCH/PUT when accessing top-level data node. * Fixed: [ Calling copy-config RPC from restconf #158](https://github.com/clicon/clixon/issues/158) * Fixed: [namespace prefix nc is not supported in full #154](https://github.com/clicon/clixon/issues/154) * edit-config "config" parameter did not work with prefix other than null diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 1fb6060f..2b1c77ce 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -479,10 +479,22 @@ api_data_write(clicon_handle h, * Replace xparent with x, ie bottom of api-path with data */ dname = xml_name(xdata); - if (api_path==NULL && strcmp(dname,"data")==0){ + if (api_path==NULL) { + if (strcmp(dname, "data")!=0){ + if (netconf_bad_element_xml(&xerr, "application", dname, + "Data element does not match top-level data") < 0) + goto done; + if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ + clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); + goto done; + } + if (api_return_err(h, req, xe, pretty, media_out, 0) < 0) + goto done; + goto ok; + } if (xml_addsub(NULL, xdata) < 0) goto done; - if (xtop) + if (xtop) /* also xbot */ xml_free(xtop); xtop = xdata; xml_name_set(xtop, "config"); @@ -494,7 +506,7 @@ api_data_write(clicon_handle h, goto done; } } - else { + else { /* api-path != NULL */ /* There is an api-path that defines an element in the datastore tree. * Not top-of-tree. */ @@ -502,7 +514,8 @@ api_data_write(clicon_handle h, /* Check same symbol in api-path as data */ if (strcmp(dname, xml_name(xbot))){ - if (netconf_operation_failed_xml(&xerr, "protocol", "Not same symbol in api-path as data") < 0) + if (netconf_bad_element_xml(&xerr, "application", dname, + "Data element does not match api-path") < 0) goto done; if ((xe = xpath_first(xerr, NULL, "rpc-error")) == NULL){ clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); @@ -564,8 +577,9 @@ api_data_write(clicon_handle h, } } } - xml_purge(xbot); - if (xml_addsub(xparent, xdata) < 0) + if (xtop != xbot) /* Should always be true */ + xml_purge(xbot); + if (xml_addsub(xparent, xdata) < 0) goto done; /* If restconf insert/point attributes are present, translate to netconf */ if (restconf_insert_attributes(xdata, qvec) < 0) @@ -584,7 +598,7 @@ api_data_write(clicon_handle h, if (namespace && strcmp(namespace, xml_value(xa))==0) xml_purge(xa); } - } + } /* api-path != NULL */ /* For internal XML protocol: add username attribute for access control */ username = clicon_username_get(h); diff --git a/test/test_restconf_patch.sh b/test/test_restconf_patch.sh index 0e8baeec..af8dcbca 100755 --- a/test/test_restconf_patch.sh +++ b/test/test_restconf_patch.sh @@ -236,6 +236,12 @@ expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H 'Content-Type: application/ new "The key leaf values MUST be the same as the key leaf values in the request" expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data/example-jukebox:jukebox/library/artist=Clash/album=London%20Calling -d '{"example-jukebox:album":{"name":"The Clash"}}')" 0 'HTTP/1.1 412 Precondition Failed' +new "PATCH on root resource extra c" # merge extra/c +expectpart "$(curl -u andy:bar $CURLOPTS -X PATCH -H "Content-Type: application/yang-data+json" $RCPROTO://localhost/restconf/data -d '{"ietf-restconf:data":{"example-jukebox:extra":"c"}}')" 0 "HTTP/1.1 204 No Content" + +new "GET check" # XXX: "data" should probably be namespaced? +expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data?content=config -H 'Accept: application/yang-data+xml')" 0 'HTTP/1.1 200 OK' 'c' '' + if [ $RC -ne 0 ]; then new "Kill restconf daemon" stop_restconf