From d0d2f090dcb4774998716988255753f965912d73 Mon Sep 17 00:00:00 2001 From: Daniel Veillard Date: Fri, 7 Mar 2008 16:50:21 +0000 Subject: fix handling of empty CDATA nodes as reported and discussed around #514181 * xmlsave.c parser.c: fix handling of empty CDATA nodes as reported and discussed around #514181 and associated patches * test/emptycdata.xml result/emptycdata.xml* result/noent/emptycdata.xml: added a specific test in the regression suite. Daniel svn path=/trunk/; revision=3701 --- ChangeLog | 8 ++++++++ parser.c | 15 ++++++++++++++- result/emptycdata.xml | 4 ++++ result/emptycdata.xml.rde | 7 +++++++ result/emptycdata.xml.rdr | 7 +++++++ result/emptycdata.xml.sax | 10 ++++++++++ result/emptycdata.xml.sax2 | 10 ++++++++++ result/noent/emptycdata.xml | 4 ++++ test/emptycdata.xml | 4 ++++ xmlsave.c | 32 ++++++++++++++++++-------------- 10 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 result/emptycdata.xml create mode 100644 result/emptycdata.xml.rde create mode 100644 result/emptycdata.xml.rdr create mode 100644 result/emptycdata.xml.sax create mode 100644 result/emptycdata.xml.sax2 create mode 100644 result/noent/emptycdata.xml create mode 100644 test/emptycdata.xml diff --git a/ChangeLog b/ChangeLog index fd7ddbf0..0d7570cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Fri Mar 7 17:45:27 CET 2008 Daniel Veillard + + * xmlsave.c parser.c: fix handling of empty CDATA nodes as + reported and discussed around #514181 and associated patches + * test/emptycdata.xml result/emptycdata.xml* + result/noent/emptycdata.xml: added a specific test in the + regression suite. + Thu Mar 6 15:23:10 CET 2008 Daniel Veillard * encoding.c: poblem with encoding detection for UTF-16 reported by diff --git a/parser.c b/parser.c index 0d27e87e..5dc6d01d 100644 --- a/parser.c +++ b/parser.c @@ -10165,7 +10165,20 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) { ctxt->input->cur += tmp; goto encoding_error; } - if ((ctxt->sax != NULL) && (base > 0) && + if ((ctxt->sax != NULL) && (base == 0) && + (ctxt->sax->cdataBlock != NULL) && + (!ctxt->disableSAX)) { + /* + * Special case to provide identical behaviour + * between pull and push parsers on enpty CDATA + * sections + */ + if ((ctxt->input->cur - ctxt->input->base >= 9) && + (!strncmp((const char *)&ctxt->input->cur[-9], + "sax->cdataBlock(ctxt->userData, + BAD_CAST "", 0); + } else if ((ctxt->sax != NULL) && (base > 0) && (!ctxt->disableSAX)) { if (ctxt->sax->cdataBlock != NULL) ctxt->sax->cdataBlock(ctxt->userData, diff --git a/result/emptycdata.xml b/result/emptycdata.xml new file mode 100644 index 00000000..bc98388a --- /dev/null +++ b/result/emptycdata.xml @@ -0,0 +1,4 @@ + + + + diff --git a/result/emptycdata.xml.rde b/result/emptycdata.xml.rde new file mode 100644 index 00000000..1c8b74ff --- /dev/null +++ b/result/emptycdata.xml.rde @@ -0,0 +1,7 @@ +0 1 html 0 0 +1 14 #text 0 1 + +1 4 #cdata-section 0 1 +1 14 #text 0 1 + +0 15 html 0 0 diff --git a/result/emptycdata.xml.rdr b/result/emptycdata.xml.rdr new file mode 100644 index 00000000..1c8b74ff --- /dev/null +++ b/result/emptycdata.xml.rdr @@ -0,0 +1,7 @@ +0 1 html 0 0 +1 14 #text 0 1 + +1 4 #cdata-section 0 1 +1 14 #text 0 1 + +0 15 html 0 0 diff --git a/result/emptycdata.xml.sax b/result/emptycdata.xml.sax new file mode 100644 index 00000000..39587c63 --- /dev/null +++ b/result/emptycdata.xml.sax @@ -0,0 +1,10 @@ +SAX.setDocumentLocator() +SAX.startDocument() +SAX.startElement(html, xmlns='http://www.w3.org/1999/xhtml') +SAX.characters( +, 1) +SAX.pcdata(, 0) +SAX.characters( +, 1) +SAX.endElement(html) +SAX.endDocument() diff --git a/result/emptycdata.xml.sax2 b/result/emptycdata.xml.sax2 new file mode 100644 index 00000000..7f80296e --- /dev/null +++ b/result/emptycdata.xml.sax2 @@ -0,0 +1,10 @@ +SAX.setDocumentLocator() +SAX.startDocument() +SAX.startElementNs(html, NULL, 'http://www.w3.org/1999/xhtml', 1, xmlns='http://www.w3.org/1999/xhtml', 0, 0) +SAX.characters( +, 1) +SAX.pcdata(, 0) +SAX.characters( +, 1) +SAX.endElementNs(html, NULL, 'http://www.w3.org/1999/xhtml') +SAX.endDocument() diff --git a/result/noent/emptycdata.xml b/result/noent/emptycdata.xml new file mode 100644 index 00000000..bc98388a --- /dev/null +++ b/result/noent/emptycdata.xml @@ -0,0 +1,4 @@ + + + + diff --git a/test/emptycdata.xml b/test/emptycdata.xml new file mode 100644 index 00000000..bc98388a --- /dev/null +++ b/test/emptycdata.xml @@ -0,0 +1,4 @@ + + + + diff --git a/xmlsave.c b/xmlsave.c index cbabd786..2a61577f 100644 --- a/xmlsave.c +++ b/xmlsave.c @@ -727,8 +727,8 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { return; } if (cur->type == XML_CDATA_SECTION_NODE) { - if (cur->content == NULL) { - xmlOutputBufferWrite(buf, 12, ""); + if (cur->content == NULL || *cur->content == '\0') { + xmlOutputBufferWrite(buf, 12, ""); } else { start = end = cur->content; while (*end != '\0') { @@ -1236,21 +1236,25 @@ xhtmlNodeDumpOutput(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) { return; } if (cur->type == XML_CDATA_SECTION_NODE) { - start = end = cur->content; - while (*end != '\0') { - if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') { - end = end + 2; + if (cur->content == NULL || *cur->content == '\0') { + xmlOutputBufferWrite(buf, 12, ""); + } else { + start = end = cur->content; + while (*end != '\0') { + if (*end == ']' && *(end + 1) == ']' && *(end + 2) == '>') { + end = end + 2; + xmlOutputBufferWrite(buf, 9, ""); + start = end; + } + end++; + } + if (start != end) { xmlOutputBufferWrite(buf, 9, ""); - start = end; } - end++; - } - if (start != end) { - xmlOutputBufferWrite(buf, 9, ""); } return; } -- cgit v1.2.3