CDATA Encode and decode (parsing) support

This commit is contained in:
Olof hagsand 2018-06-13 22:55:46 +02:00
parent 8b31d83806
commit 9eff879458
6 changed files with 61 additions and 16 deletions

View file

@ -10,6 +10,7 @@
### Minor changes: ### Minor changes:
* CDATA xml support (patch by David Cornejo, Netgate) * CDATA xml support (patch by David Cornejo, Netgate)
* Encode and decode (parsing) support
* Validation of yang bits type space-separated list value * Validation of yang bits type space-separated list value
* Added -U <user> command line to clixon_cli and clixon_netconf for NACM pseudo-user tests * Added -U <user> command line to clixon_cli and clixon_netconf for NACM pseudo-user tests
* Added a generated CLI show command that works on the generated parse tree with auto completion. * Added a generated CLI show command that works on the generated parse tree with auto completion.

View file

@ -243,6 +243,8 @@ yang2cli_var_sub(clicon_handle h,
if ((id=strchr(name, ':')) != NULL) if ((id=strchr(name, ':')) != NULL)
*id = '\0'; *id = '\0';
cprintf(cb, "%s:%s", name, id+1); cprintf(cb, "%s:%s", name, id+1);
if (name)
free(name);
} }
} }
} }

View file

@ -297,14 +297,27 @@ xml_chardata_encode(char *str,
int l; int l;
int len; int len;
int i, j; int i, j;
int cdata; /* when set, skip encoding */
len = 0; /* First compute length (do nothing) */
len = 0; cdata = 0;
for (i=0; i<strlen(str); i++){ for (i=0; i<strlen(str); i++){
if (cdata){
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0)
cdata = 0;
len++;
}
else
switch (str[i]){ switch (str[i]){
case '&': case '&':
len += strlen("&amp; "); len += strlen("&amp; ");
break; break;
case '<': case '<':
if (strncmp(&str[i], "<![CDATA[", strlen("<![CDATA[")) == 0){
len++;
cdata++;
}
else
len += strlen("&lt; "); len += strlen("&lt; ");
break; break;
case '>': case '>':
@ -315,13 +328,25 @@ xml_chardata_encode(char *str,
} }
} }
len++; /* trailing \0 */ len++; /* trailing \0 */
/* We know length, allocate encoding buffer */
if ((esc = malloc(len)) == NULL){ if ((esc = malloc(len)) == NULL){
clicon_err(OE_UNIX, errno, "malloc"); clicon_err(OE_UNIX, errno, "malloc");
goto done; goto done;
} }
memset(esc, 0, len); memset(esc, 0, len);
j = 0;
/* Same code again, but now actually encode into output buffer */
j = 0; cdata = 0;
for (i=0; i<strlen(str); i++){ for (i=0; i<strlen(str); i++){
if (cdata){
if (strncmp(&str[i], "]]>", strlen("]]>")) == 0){
cdata = 0;
esc[j++] = str[i++];
esc[j++] = str[i++];
}
esc[j++] = str[i];
}
else
switch (str[i]){ switch (str[i]){
case '&': case '&':
if ((l=snprintf(&esc[j], 7, "&amp; ")) < 0){ if ((l=snprintf(&esc[j], 7, "&amp; ")) < 0){
@ -331,6 +356,11 @@ xml_chardata_encode(char *str,
j += l; j += l;
break; break;
case '<': case '<':
if (strncmp(&str[i], "<![CDATA[", strlen("<![CDATA[")) == 0){
esc[j++] = str[i];
cdata++;
break;
}
if ((l=snprintf(&esc[j], 6, "&lt; ")) < 0){ if ((l=snprintf(&esc[j], 6, "&lt; ")) < 0){
clicon_err(OE_UNIX, errno, "snprintf"); clicon_err(OE_UNIX, errno, "snprintf");
goto done; goto done;

View file

@ -104,10 +104,11 @@ int clixon_xml_parsewrap(void)
<STATEA>"</" { BEGIN(START); return BSLASH; } <STATEA>"</" { BEGIN(START); return BSLASH; }
<STATEA>"<!--" { BEGIN(CMNT); return BCOMMENT; } <STATEA>"<!--" { BEGIN(CMNT); return BCOMMENT; }
<STATEA>"<![CDATA[" { BEGIN(CDATA); _YA->ya_lex_state = STATEA; clixon_xml_parselval.string = yytext; return CHARDATA;}
<STATEA>\< { BEGIN(START); return *clixon_xml_parsetext; } <STATEA>\< { BEGIN(START); return *clixon_xml_parsetext; }
<STATEA>& { _YA->ya_lex_state =STATEA;BEGIN(AMPERSAND);} <STATEA>& { _YA->ya_lex_state =STATEA;BEGIN(AMPERSAND);}
<STATEA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHARDATA);} <STATEA>\n { clixon_xml_parselval.string = yytext;_YA->ya_linenum++; return (CHARDATA);}
<STATEA>"<![CDATA[" { BEGIN(CDATA); _YA->ya_lex_state = STATEA; clixon_xml_parselval.string = yytext; return CHARDATA;}
<STATEA>. { clixon_xml_parselval.string = yytext; return CHARDATA; /*XXX:optimize*/} <STATEA>. { clixon_xml_parselval.string = yytext; return CHARDATA; /*XXX:optimize*/}
/* @see xml_chardata_encode */ /* @see xml_chardata_encode */

View file

@ -1261,7 +1261,11 @@ ys_populate_identity(yang_stmt *ys,
} }
/* add prefix */ /* add prefix */
cv_name_set(cv, idref); cv_name_set(cv, idref);
cvec_append_var(ybaseid->ys_cvec, cv); cvec_append_var(ybaseid->ys_cvec, cv); /* cv copied */
if (cv){
cv_free(cv);
cv = NULL;
}
/* Transitive to the root */ /* Transitive to the root */
if (ys_populate_identity(ybaseid, idref) < 0) if (ys_populate_identity(ybaseid, idref) < 0)
goto done; goto done;

View file

@ -153,6 +153,13 @@ new "cli show configuration eth& - encoding tests"
expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" 0 "interfaces interface eth& type t<> expectfn "$clixon_cli -1 -f $cfg -y $fyang show conf cli" 0 "interfaces interface eth& type t<>
interfaces interface eth& enabled true" interfaces interface eth& enabled true"
new "netconf edit CDATA"
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config><interfaces><interface><name>eth/0/0</name><type>ex:eth</type><description><![CDATA[myeth&]]></description></interface></interfaces></config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
#new "netconf get CDATA"
#expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/interfaces/interface[name=eth/0/0]/description\" /></get-config></rpc>]]>]]>" "<rpc-reply><data><interfaces><interface><name>eth/0/0</name><description><![CDATA[myeth&]]></description><enabled>true</enabled></interface></interfaces></data></rpc-reply>]]>]]>"
new "netconf discard-changes" new "netconf discard-changes"
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><discard-changes/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"