From 19f26e6838f455b074d8cb2a22c4d13574198250 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sat, 19 Jan 2019 21:39:19 +0100 Subject: [PATCH] * XML<>JSON conversion problems [https://github.com/clicon/clixon/issues/66] * CDATA sections stripped from XML when converted to JSON --- CHANGELOG.md | 2 ++ lib/src/clixon_json.c | 76 ++++++++++++++++++++++++++----------------- test/lib.sh | 59 +++++++++++++++++++++++++++++++-- test/test_xml.sh | 61 ++++++++++++++++++++++++---------- 4 files changed, 148 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b2b756a0..088d8a704 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -134,6 +134,8 @@ * JSON conversion problems [https://github.com/clicon/clixon/issues/66] + * CDATA sections stripped from XML when converted to JSON * Restconf returns error when RPC generates "ok" reply [https://github.com/clicon/clixon/issues/69] * xsd regular expression support for character classes [https://github.com/clicon/clixon/issues/68] * added support for \c, \d, \w, \W, \s, \S. diff --git a/lib/src/clixon_json.c b/lib/src/clixon_json.c index 731d90de8..4b412e208 100644 --- a/lib/src/clixon_json.c +++ b/lib/src/clixon_json.c @@ -216,42 +216,58 @@ array_eval(cxobj *xprev, return array; } -/*! Escape a json string +/*! Escape a json string as well as decode xml cdata + * And a */ -static char * -json_str_escape(char *str) +static int +json_str_escape_cdata(cbuf *cb, + char *str) { - int i, j; - char *snew; + int retval = -1; + char *snew = NULL; + int i; + int esc = 0; /* cdata escape */ - j = 0; for (i=0;i", strlen("]]>")) == 0){ + esc=0; + i += strlen("]]>")-1; + } + else + cprintf(cb, "%c", str[i]); break; - case '\"': - case '\\': - snew[j++]='\\'; default: /* fall thru */ - snew[j++]=str[i]; + cprintf(cb, "%c", str[i]); + break; } - snew[j++]='\0'; - return snew; + if ((snew = strdup(cbuf_get(cb))) ==NULL){ + clicon_err(OE_XML, errno, "strdup"); + goto done; + } + retval = 0; + done: + return retval; } /*! Do the actual work of translating XML to JSON @@ -309,10 +325,10 @@ xml2json1_cbuf(cbuf *cb, yang_stmt *ymod; /* yang module */ yang_spec *yspec = NULL; /* yang spec */ int bodystr0=1; - char *str; char *prefix=NULL; /* prefix / local namespace name */ char *namespace=NULL; /* namespace uri */ char *modname=NULL; /* Module name */ + int commas; /* If x is labelled with a default namespace, it should be translated * to a module name. @@ -337,10 +353,11 @@ xml2json1_cbuf(cbuf *cb, switch(arraytype){ case BODY_ARRAY:{ if (bodystr){ - if ((str = json_str_escape(xml_value(x))) == NULL) + /* XXX String if right type */ + cprintf(cb, "\""); + if (json_str_escape_cdata(cb, xml_value(x)) < 0) goto done; - cprintf(cb, "\"%s\"", str); - free(str); + cprintf(cb, "\""); } else cprintf(cb, "%s", xml_value(x)); @@ -434,8 +451,7 @@ xml2json1_cbuf(cbuf *cb, break; } - int na = xml_child_nr_notype(x, CX_ATTR); - int commas = na - 1; + commas = xml_child_nr_notype(x, CX_ATTR) - 1; for (i=0; i" "^$" new "xml parse to json" -expecteof "$PROG -j" 0 "" '^{"a": {"b": null}}$' +expecteof "$PROG -j" 0 "" '{"a": {"b": null}}' new "xml parse strange names" -expecteof "$PROG" 0 "<_->" "^<_->$" +expecteof "$PROG" 0 "<_->" "<_->" new "xml parse name errors" expecteof "$PROG" 255 "<-a/>" "" @@ -37,11 +35,16 @@ if [ "$ret" != "a${LF}b${LF}c${LF}d" ]; then err 'a$LFb$LFc' "$ret" fi +new "xml simple CDATA" +expecteofx "$PROG" 0 '' '' + +new "xml simple CDATA to json" +expecteofx "$PROG -j" 0 '' '{"a": "a text"}' + +new "xml complex CDATA" XML=$(cat <An example of escaped CENDs - - y" so I guess that means that z > x ]]> - + y" so I guess that means that z > x ]]> @@ -53,33 +56,55 @@ XML=$(cat <An example of escaped CENDs y\" so I guess that means that z > x ]]> ]]>]]>$" +JSON=$(cat < y\" so I guess that means that z > x ","data": "This text contains a CEND ]]>","alternative": "This text contains a CEND ]]>"}} +EOF +) +new "xml complex CDATA to json" +expecteofx "$PROG -j" 0 "$XML" "$JSON" + XML=$(cat <Less than: < , greater than: > ampersand: & EOF ) new "xml encode <>&" -expecteof "$PROG" 0 "$XML" "^$XML$" +expecteof "$PROG" 0 "$XML" "$XML" + +new "xml encode <>& to json" +expecteof "$PROG -j" 0 "$XML" '{"message": "Less than: < , greater than: > ampersand: & "}' XML=$(cat <To allow attribute values to contain both single and double quotes, the apostrophe or single-quote character ' may be represented as ' and the double-quote character as " +single-quote character ' represented as ' and double-quote character as " +EOF +) +new "xml single and double quote" +expecteof "$PROG" 0 "$XML" "single-quote character ' represented as ' and double-quote character as \"" + +JSON=$(cat <To allow attribute values to contain both single and double quotes, the apostrophe or single-quote character ' may be represented as ' and the double-quote character as \"$" +new "xml single and double quotes to json" +expecteofx "$PROG -j" 0 "$XML" "$JSON" + +new "xml backspace" +expecteofx "$PROG" 0 "a\b" "a\b" + +new "xml backspace to json" +expecteofx "$PROG -j" 0 "a\b" '{"a": "a\\b"}' new "Double quotes for attributes" -expecteof "$PROG" 0 '' '^$' +expecteof "$PROG" 0 '' '' new "Single quotes for attributes (returns double quotes but at least parses right)" -expecteof "$PROG" 0 "" '^$' +expecteof "$PROG" 0 "" '' new "Mixed quotes" -expecteof "$PROG" 0 "" '^$' +expecteof "$PROG" 0 "" '' new "XMLdecl version" expecteof "$PROG" 0 '' '' @@ -94,7 +119,7 @@ new "XMLdecl no version" expecteof "$PROG" 255 '' '' new "XMLdecl misspelled version" -expecteof "$PROG -l o" 255 '' 'yntax error: at or before: v' +expecteof "$PROG -l o" 255 '' '' new "XMLdecl version + encoding" expecteof "$PROG" 0 '' '' @@ -119,7 +144,7 @@ expecteof "$PROG" 0 '' #expecteof "$PROG" 255 '' '' new "namespace: DefaultAttName" -expecteof "$PROG" 0 'hello' '^hello$' +expecteof "$PROG" 0 'hello' 'hello' new "namespace: PrefixedAttName" expecteof "$PROG" 0 'hello' '^hello$'