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:
parent
f69647811c
commit
7cbf609ae8
103
xmlreader.c
103
xmlreader.c
@ -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,7 +1733,9 @@ xmlTextReaderReadOuterXml(xmlTextReaderPtr reader)
|
||||
xmlChar *
|
||||
xmlTextReaderReadString(xmlTextReaderPtr reader)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
xmlNodePtr node, cur;
|
||||
xmlBufPtr buf;
|
||||
xmlChar *ret;
|
||||
|
||||
if ((reader == NULL) || (reader->node == NULL))
|
||||
return(NULL);
|
||||
@ -1789,13 +1743,8 @@ xmlTextReaderReadString(xmlTextReaderPtr reader)
|
||||
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_CDATA_SECTION_NODE:
|
||||
case XML_ELEMENT_NODE:
|
||||
if (xmlTextReaderDoExpand(reader) != -1) {
|
||||
return xmlTextReaderCollectSiblings(node->children);
|
||||
}
|
||||
break;
|
||||
case XML_ATTRIBUTE_NODE:
|
||||
/* TODO */
|
||||
@ -1803,7 +1752,51 @@ xmlTextReaderReadString(xmlTextReaderPtr reader)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user