Fixed issue https://github.com/clicon/clixon/issues/17 special character in strings can break RPCs

This commit is contained in:
Olof hagsand 2018-04-21 16:32:46 +02:00
parent 7650803475
commit 67c0abead7
15 changed files with 405 additions and 136 deletions

View file

@ -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");

View file

@ -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:
* & -> "&amp; " must
* < -> "&lt; " must
* > -> "&gt; " must for backward compatibility
* ' -> "&apos; " may
* ' -> "&quot; " 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("&amp; ");
break;
case '<':
len += strlen("&lt; ");
break;
case '>':
len += strlen("&gt; ");
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, "&amp; ")) < 0){
clicon_err(OE_UNIX, errno, "snprintf");
goto done;
}
j += l;
break;
case '<':
if ((l=snprintf(&esc[j], 6, "&lt; ")) < 0){
clicon_err(OE_UNIX, errno, "snprintf");
goto done;
}
j += l;
break;
case '>':
if ((l=snprintf(&esc[j], 6, "&gt; ")) < 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");

View file

@ -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

View file

@ -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 */

View file

@ -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;

View file

@ -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; }
%%

View file

@ -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 */}
;