1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2024-12-25 23:21:26 +03:00

reader: Make xmlTextReaderReadString non-recursive

Also report malloc failures.

Fixes #607.
This commit is contained in:
Nick Wellnhofer 2024-04-18 12:57:15 +02:00
parent f69647811c
commit 7cbf609ae8

View File

@ -1179,54 +1179,6 @@ xmlTextReaderDoExpand(xmlTextReaderPtr reader) {
return(1);
}
/**
* xmlTextReaderCollectSiblings:
* @node: the first child
*
* Traverse depth-first through all sibling nodes and their children
* nodes and concatenate their content. This is an auxiliary function
* to xmlTextReaderReadString.
*
* Returns a string containing the content, or NULL in case of error.
*/
static xmlChar *
xmlTextReaderCollectSiblings(xmlNodePtr node)
{
xmlBufferPtr buffer;
xmlChar *ret;
if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
return(NULL);
buffer = xmlBufferCreate();
if (buffer == NULL)
return NULL;
xmlBufferSetAllocationScheme(buffer, XML_BUFFER_ALLOC_DOUBLEIT);
for ( ; node != NULL; node = node->next) {
switch (node->type) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
xmlBufferCat(buffer, node->content);
break;
case XML_ELEMENT_NODE: {
xmlChar *tmp;
tmp = xmlTextReaderCollectSiblings(node->children);
xmlBufferCat(buffer, tmp);
xmlFree(tmp);
break;
}
default:
break;
}
}
ret = buffer->content;
buffer->content = NULL;
xmlBufferFree(buffer);
return(ret);
}
/**
* xmlTextReaderRead:
* @reader: the xmlTextReaderPtr used
@ -1781,29 +1733,70 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader)
xmlChar *
xmlTextReaderReadString(xmlTextReaderPtr reader)
{
xmlNodePtr node;
xmlNodePtr node, cur;
xmlBufPtr buf;
xmlChar *ret;
if ((reader == NULL) || (reader->node == NULL))
return(NULL);
node = (reader->curnode != NULL) ? reader->curnode : reader->node;
switch (node->type) {
case XML_TEXT_NODE:
if (node->content != NULL)
return(readerStrdup(reader, node->content));
break;
case XML_ELEMENT_NODE:
if (xmlTextReaderDoExpand(reader) != -1) {
return xmlTextReaderCollectSiblings(node->children);
}
break;
case XML_ATTRIBUTE_NODE:
/* TODO */
break;
default:
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ELEMENT_NODE:
break;
case XML_ATTRIBUTE_NODE:
/* TODO */
break;
default:
break;
}
return(NULL);
buf = xmlBufCreateSize(30);
if (buf == NULL) {
xmlTextReaderErrMemory(reader);
return(NULL);
}
xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_DOUBLEIT);
cur = node;
while (cur != NULL) {
switch (cur->type) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
xmlBufCat(buf, cur->content);
break;
case XML_ELEMENT_NODE:
if (cur->children != NULL) {
cur = cur->children;
continue;
}
break;
default:
break;
}
if (cur == node)
goto done;
while (cur->next == NULL) {
cur = cur->parent;
if (cur == node)
goto done;
}
cur = cur->next;
}
done:
ret = xmlBufDetach(buf);
if (ret == NULL)
xmlTextReaderErrMemory(reader);
xmlBufFree(buf);
return(ret);
}
#if 0