Skip to content

Commit 3910e63

Browse files
committed
reader: Fix return value of xmlTextReaderReadString again
Make sure to return NULL for node types except elements or text to match the old behavior. Note that CDATA sections are still treated like text nodes and will have their content returned. Fixes #838.
1 parent f35d528 commit 3910e63

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

testparser.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,76 @@ testReaderContent(void) {
361361
return err;
362362
}
363363

364+
static int
365+
testReaderNode(xmlTextReader *reader) {
366+
xmlChar *string;
367+
int type;
368+
int err = 0;
369+
370+
type = xmlTextReaderNodeType(reader);
371+
string = xmlTextReaderReadString(reader);
372+
373+
if (type == XML_READER_TYPE_ELEMENT) {
374+
xmlNodePtr node = xmlTextReaderCurrentNode(reader);
375+
376+
if ((node->children == NULL) != (string == NULL))
377+
err = 1;
378+
} else if (type == XML_READER_TYPE_TEXT ||
379+
type == XML_READER_TYPE_CDATA ||
380+
type == XML_READER_TYPE_WHITESPACE ||
381+
type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE) {
382+
if (string == NULL)
383+
err = 1;
384+
} else {
385+
if (string != NULL)
386+
err = 1;
387+
}
388+
389+
if (err)
390+
fprintf(stderr, "xmlTextReaderReadString failed for %d\n", type);
391+
392+
xmlFree(string);
393+
394+
return err;
395+
}
396+
397+
static int
398+
testReader(void) {
399+
xmlTextReader *reader;
400+
const xmlChar *xml = BAD_CAST
401+
"<d>\n"
402+
" x<e a='v'>y</e><f>z</f>\n"
403+
" <![CDATA[cdata]]>\n"
404+
" <!-- comment -->\n"
405+
" <?pi content?>\n"
406+
" <empty/>\n"
407+
"</d>";
408+
int err = 0;
409+
410+
reader = xmlReaderForDoc(xml, NULL, NULL, 0);
411+
412+
while (xmlTextReaderRead(reader) > 0) {
413+
if (testReaderNode(reader) > 0) {
414+
err = 1;
415+
break;
416+
}
417+
418+
if (xmlTextReaderMoveToFirstAttribute(reader) > 0) {
419+
do {
420+
if (testReaderNode(reader) > 0) {
421+
err = 1;
422+
break;
423+
}
424+
} while (xmlTextReaderMoveToNextAttribute(reader) > 0);
425+
426+
xmlTextReaderMoveToElement(reader);
427+
}
428+
}
429+
430+
xmlFreeTextReader(reader);
431+
return err;
432+
}
433+
364434
#ifdef LIBXML_XINCLUDE_ENABLED
365435
typedef struct {
366436
char *message;
@@ -638,6 +708,7 @@ main(void) {
638708
#ifdef LIBXML_READER_ENABLED
639709
err |= testReaderEncoding();
640710
err |= testReaderContent();
711+
err |= testReader();
641712
#ifdef LIBXML_XINCLUDE_ENABLED
642713
err |= testReaderXIncludeError();
643714
#endif

xmlreader.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,8 +1730,9 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader)
17301730
*
17311731
* Reads the contents of an element or a text node as a string.
17321732
*
1733-
* Returns a string containing the contents of the Element or Text node,
1734-
* or NULL if the reader is positioned on any other type of node.
1733+
* Returns a string containing the contents of the non-empty Element or
1734+
* Text node (including CDATA sections), or NULL if the reader
1735+
* is positioned on any other type of node.
17351736
* The string must be deallocated by the caller.
17361737
*/
17371738
xmlChar *
@@ -1754,11 +1755,8 @@ xmlTextReaderReadString(xmlTextReaderPtr reader)
17541755
(node->children == NULL))
17551756
return(NULL);
17561757
break;
1757-
case XML_ATTRIBUTE_NODE:
1758-
/* TODO */
1759-
break;
17601758
default:
1761-
break;
1759+
return(NULL);
17621760
}
17631761

17641762
buf = xmlBufCreateSize(30);

0 commit comments

Comments
 (0)