From be579a266e29f2f70db6957cd834ba88ad74b054 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Wed, 15 Jan 2025 12:52:53 +0100 Subject: [PATCH] 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. --- testparser.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ xmlreader.c | 10 +++----- 2 files changed, 75 insertions(+), 6 deletions(-) diff --git a/testparser.c b/testparser.c index d3a3e387..c28e8bbf 100644 --- a/testparser.c +++ b/testparser.c @@ -467,6 +467,76 @@ testReaderContent(void) { return err; } +static int +testReaderNode(xmlTextReader *reader) { + xmlChar *string; + int type; + int err = 0; + + type = xmlTextReaderNodeType(reader); + string = xmlTextReaderReadString(reader); + + if (type == XML_READER_TYPE_ELEMENT) { + xmlNodePtr node = xmlTextReaderCurrentNode(reader); + + if ((node->children == NULL) != (string == NULL)) + err = 1; + } else if (type == XML_READER_TYPE_TEXT || + type == XML_READER_TYPE_CDATA || + type == XML_READER_TYPE_WHITESPACE || + type == XML_READER_TYPE_SIGNIFICANT_WHITESPACE) { + if (string == NULL) + err = 1; + } else { + if (string != NULL) + err = 1; + } + + if (err) + fprintf(stderr, "xmlTextReaderReadString failed for %d\n", type); + + xmlFree(string); + + return err; +} + +static int +testReader(void) { + xmlTextReader *reader; + const xmlChar *xml = BAD_CAST + "\n" + " xyz\n" + " \n" + " \n" + " \n" + " \n" + ""; + int err = 0; + + reader = xmlReaderForDoc(xml, NULL, NULL, 0); + + while (xmlTextReaderRead(reader) > 0) { + if (testReaderNode(reader) > 0) { + err = 1; + break; + } + + if (xmlTextReaderMoveToFirstAttribute(reader) > 0) { + do { + if (testReaderNode(reader) > 0) { + err = 1; + break; + } + } while (xmlTextReaderMoveToNextAttribute(reader) > 0); + + xmlTextReaderMoveToElement(reader); + } + } + + xmlFreeTextReader(reader); + return err; +} + #ifdef LIBXML_XINCLUDE_ENABLED typedef struct { char *message; @@ -834,6 +904,7 @@ main(void) { #ifdef LIBXML_READER_ENABLED err |= testReaderEncoding(); err |= testReaderContent(); + err |= testReader(); #ifdef LIBXML_XINCLUDE_ENABLED err |= testReaderXIncludeError(); #endif diff --git a/xmlreader.c b/xmlreader.c index 403a4e4e..6d815a94 100644 --- a/xmlreader.c +++ b/xmlreader.c @@ -1742,8 +1742,9 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader) * * Reads the contents of an element or a text node as a string. * - * Returns a string containing the contents of the Element or Text node, - * or NULL if the reader is positioned on any other type of node. + * Returns a string containing the contents of the non-empty Element or + * Text node (including CDATA sections), or NULL if the reader + * is positioned on any other type of node. * The string must be deallocated by the caller. */ xmlChar * @@ -1766,11 +1767,8 @@ xmlTextReaderReadString(xmlTextReaderPtr reader) (node->children == NULL)) return(NULL); break; - case XML_ATTRIBUTE_NODE: - /* TODO */ - break; default: - break; + return(NULL); } buf = xmlBufCreate(50);