| Index: third_party/libxml/src/tree.c
|
| diff --git a/third_party/libxml/src/tree.c b/third_party/libxml/src/tree.c
|
| index 1e1a23a10e7726ca0b2f271caf1eeb5171a96fd4..307782cf4722ecc6c55fa9a0b73dbd6f07b99ce7 100644
|
| --- a/third_party/libxml/src/tree.c
|
| +++ b/third_party/libxml/src/tree.c
|
| @@ -41,6 +41,9 @@
|
| #include <libxml/debugXML.h>
|
| #endif
|
|
|
| +#include "buf.h"
|
| +#include "save.h"
|
| +
|
| int __xmlRegisterCallbacks = 0;
|
|
|
| /************************************************************************
|
| @@ -52,7 +55,7 @@ int __xmlRegisterCallbacks = 0;
|
| static xmlNsPtr
|
| xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns);
|
|
|
| -static xmlChar* xmlGetPropNodeValueInternal(xmlAttrPtr prop);
|
| +static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
|
|
|
| /************************************************************************
|
| * *
|
| @@ -157,7 +160,7 @@ static int xmlCheckDTD = 1;
|
| * Returns A pointer to the entity structure or NULL if not found.
|
| */
|
| static xmlEntityPtr
|
| -xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
|
| +xmlGetEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
|
| xmlEntitiesTablePtr table;
|
|
|
| if((dtd != NULL) && (dtd->entities != NULL)) {
|
| @@ -178,7 +181,7 @@ xmlGetEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
|
| * Returns A pointer to the entity structure or NULL if not found.
|
| */
|
| static xmlEntityPtr
|
| -xmlGetParameterEntityFromDtd(xmlDtdPtr dtd, const xmlChar *name) {
|
| +xmlGetParameterEntityFromDtd(const xmlDtd *dtd, const xmlChar *name) {
|
| xmlEntitiesTablePtr table;
|
|
|
| if ((dtd != NULL) && (dtd->pentities != NULL)) {
|
| @@ -311,7 +314,7 @@ xmlSplitQName2(const xmlChar *name, xmlChar **prefix) {
|
| * parse an XML qualified name string,i
|
| *
|
| * returns NULL if it is not a Qualified Name, otherwise, update len
|
| - * with the lenght in byte of the prefix and return a pointer
|
| + * with the length in byte of the prefix and return a pointer
|
| * to the start of the name without the prefix
|
| */
|
|
|
| @@ -349,7 +352,7 @@ xmlSplitQName3(const xmlChar *name, int *len) {
|
|
|
| #define CUR_SCHAR(s, l) xmlStringCurrentChar(NULL, s, &l)
|
|
|
| -#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
|
| +#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
| /**
|
| * xmlValidateNCName:
|
| * @value: the value to check
|
| @@ -682,7 +685,8 @@ try_complex:
|
| void
|
| xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
|
| if ((scheme == XML_BUFFER_ALLOC_EXACT) ||
|
| - (scheme == XML_BUFFER_ALLOC_DOUBLEIT))
|
| + (scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
|
| + (scheme == XML_BUFFER_ALLOC_HYBRID))
|
| xmlBufferAllocScheme = scheme;
|
| }
|
|
|
| @@ -693,6 +697,9 @@ xmlSetBufferAllocationScheme(xmlBufferAllocationScheme scheme) {
|
| * XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
|
| * XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
|
| * improves performance
|
| + * XML_BUFFER_ALLOC_HYBRID - use exact sizes on small strings to keep memory usage tight
|
| + * in normal usage, and doubleit on large strings to avoid
|
| + * pathological performance.
|
| *
|
| * Returns the current allocation scheme
|
| */
|
| @@ -710,8 +717,11 @@ xmlGetBufferAllocationScheme(void) {
|
| * Creation of a new Namespace. This function will refuse to create
|
| * a namespace with a similar prefix than an existing one present on this
|
| * node.
|
| + * Note that for a default namespace, @prefix should be NULL.
|
| + *
|
| * We use href==NULL in the case of an element creation where the namespace
|
| * was not defined.
|
| + *
|
| * Returns a new namespace pointer or NULL
|
| */
|
| xmlNsPtr
|
| @@ -721,8 +731,19 @@ xmlNewNs(xmlNodePtr node, const xmlChar *href, const xmlChar *prefix) {
|
| if ((node != NULL) && (node->type != XML_ELEMENT_NODE))
|
| return(NULL);
|
|
|
| - if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml")))
|
| - return(NULL);
|
| + if ((prefix != NULL) && (xmlStrEqual(prefix, BAD_CAST "xml"))) {
|
| + /* xml namespace is predefined, no need to add it */
|
| + if (xmlStrEqual(href, XML_XML_NAMESPACE))
|
| + return(NULL);
|
| +
|
| + /*
|
| + * Problem, this is an attempt to bind xml prefix to a wrong
|
| + * namespace, which breaks
|
| + * Namespace constraint: Reserved Prefixes and Namespace Names
|
| + * from XML namespace. But documents authors may not care in
|
| + * their context so let's proceed.
|
| + */
|
| + }
|
|
|
| /*
|
| * Allocate a new Namespace and fill the fields.
|
| @@ -785,7 +806,9 @@ xmlSetNs(xmlNodePtr node, xmlNsPtr ns) {
|
| #endif
|
| return;
|
| }
|
| - node->ns = ns;
|
| + if ((node->type == XML_ELEMENT_NODE) ||
|
| + (node->type == XML_ATTRIBUTE_NODE))
|
| + node->ns = ns;
|
| }
|
|
|
| /**
|
| @@ -893,7 +916,7 @@ xmlNewDtd(xmlDocPtr doc, const xmlChar *name,
|
| */
|
|
|
| xmlDtdPtr
|
| -xmlGetIntSubset(xmlDocPtr doc) {
|
| +xmlGetIntSubset(const xmlDoc *doc) {
|
| xmlNodePtr cur;
|
|
|
| if (doc == NULL)
|
| @@ -1243,16 +1266,21 @@ xmlFreeDoc(xmlDocPtr cur) {
|
| * Returns a pointer to the first child
|
| */
|
| xmlNodePtr
|
| -xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| +xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
|
| xmlNodePtr ret = NULL, last = NULL;
|
| xmlNodePtr node;
|
| xmlChar *val;
|
| const xmlChar *cur = value, *end = cur + len;
|
| const xmlChar *q;
|
| xmlEntityPtr ent;
|
| + xmlBufPtr buf;
|
|
|
| if (value == NULL) return(NULL);
|
|
|
| + buf = xmlBufCreateSize(0);
|
| + if (buf == NULL) return(NULL);
|
| + xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_HYBRID);
|
| +
|
| q = cur;
|
| while ((cur < end) && (*cur != 0)) {
|
| if (cur[0] == '&') {
|
| @@ -1263,19 +1291,8 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| * Save the current text.
|
| */
|
| if (cur != q) {
|
| - if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
|
| - xmlNodeAddContentLen(last, q, cur - q);
|
| - } else {
|
| - node = xmlNewDocTextLen(doc, q, cur - q);
|
| - if (node == NULL) return(ret);
|
| - if (last == NULL)
|
| - last = ret = node;
|
| - else {
|
| - last->next = node;
|
| - node->prev = last;
|
| - last = node;
|
| - }
|
| - }
|
| + if (xmlBufAdd(buf, q, cur - q))
|
| + goto out;
|
| }
|
| q = cur;
|
| if ((cur + 2 < end) && (cur[1] == '#') && (cur[2] == 'x')) {
|
| @@ -1340,7 +1357,7 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| if ((cur >= end) || (*cur == 0)) {
|
| xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY, (xmlNodePtr) doc,
|
| (const char *) q);
|
| - return(ret);
|
| + goto out;
|
| }
|
| if (cur != q) {
|
| /*
|
| @@ -1350,23 +1367,36 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| ent = xmlGetDocEntity(doc, val);
|
| if ((ent != NULL) &&
|
| (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
|
| - if (last == NULL) {
|
| - node = xmlNewDocText(doc, ent->content);
|
| - last = ret = node;
|
| - } else if (last->type != XML_TEXT_NODE) {
|
| - node = xmlNewDocText(doc, ent->content);
|
| - last = xmlAddNextSibling(last, node);
|
| - } else
|
| - xmlNodeAddContent(last, ent->content);
|
| +
|
| + if (xmlBufCat(buf, ent->content))
|
| + goto out;
|
|
|
| } else {
|
| /*
|
| + * Flush buffer so far
|
| + */
|
| + if (!xmlBufIsEmpty(buf)) {
|
| + node = xmlNewDocText(doc, NULL);
|
| + if (node == NULL) {
|
| + if (val != NULL) xmlFree(val);
|
| + goto out;
|
| + }
|
| + node->content = xmlBufDetach(buf);
|
| +
|
| + if (last == NULL) {
|
| + last = ret = node;
|
| + } else {
|
| + last = xmlAddNextSibling(last, node);
|
| + }
|
| + }
|
| +
|
| + /*
|
| * Create a new REFERENCE_REF node
|
| */
|
| node = xmlNewReference(doc, val);
|
| if (node == NULL) {
|
| if (val != NULL) xmlFree(val);
|
| - return(ret);
|
| + goto out;
|
| }
|
| else if ((ent != NULL) && (ent->children == NULL)) {
|
| xmlNodePtr temp;
|
| @@ -1393,40 +1423,44 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| q = cur;
|
| }
|
| if (charval != 0) {
|
| - xmlChar buf[10];
|
| + xmlChar buffer[10];
|
| int l;
|
|
|
| - l = xmlCopyCharMultiByte(buf, charval);
|
| - buf[l] = 0;
|
| - node = xmlNewDocText(doc, buf);
|
| - if (node != NULL) {
|
| - if (last == NULL) {
|
| - last = ret = node;
|
| - } else {
|
| - last = xmlAddNextSibling(last, node);
|
| - }
|
| - }
|
| + l = xmlCopyCharMultiByte(buffer, charval);
|
| + buffer[l] = 0;
|
| +
|
| + if (xmlBufCat(buf, buffer))
|
| + goto out;
|
| charval = 0;
|
| }
|
| } else
|
| cur++;
|
| }
|
| - if ((cur != q) || (ret == NULL)) {
|
| +
|
| + if (cur != q) {
|
| /*
|
| * Handle the last piece of text.
|
| */
|
| - if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
|
| - xmlNodeAddContentLen(last, q, cur - q);
|
| + if (xmlBufAdd(buf, q, cur - q))
|
| + goto out;
|
| + }
|
| +
|
| + if (!xmlBufIsEmpty(buf)) {
|
| + node = xmlNewDocText(doc, NULL);
|
| + if (node == NULL) goto out;
|
| + node->content = xmlBufDetach(buf);
|
| +
|
| + if (last == NULL) {
|
| + last = ret = node;
|
| } else {
|
| - node = xmlNewDocTextLen(doc, q, cur - q);
|
| - if (node == NULL) return(ret);
|
| - if (last == NULL) {
|
| - ret = node;
|
| - } else {
|
| - xmlAddNextSibling(last, node);
|
| - }
|
| + last = xmlAddNextSibling(last, node);
|
| }
|
| + } else if (ret == NULL) {
|
| + ret = xmlNewDocText(doc, BAD_CAST "");
|
| }
|
| +
|
| +out:
|
| + xmlBufFree(buf);
|
| return(ret);
|
| }
|
|
|
| @@ -1440,16 +1474,21 @@ xmlStringLenGetNodeList(xmlDocPtr doc, const xmlChar *value, int len) {
|
| * Returns a pointer to the first child
|
| */
|
| xmlNodePtr
|
| -xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| +xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
|
| xmlNodePtr ret = NULL, last = NULL;
|
| xmlNodePtr node;
|
| xmlChar *val;
|
| const xmlChar *cur = value;
|
| const xmlChar *q;
|
| xmlEntityPtr ent;
|
| + xmlBufPtr buf;
|
|
|
| if (value == NULL) return(NULL);
|
|
|
| + buf = xmlBufCreateSize(0);
|
| + if (buf == NULL) return(NULL);
|
| + xmlBufSetAllocationScheme(buf, XML_BUFFER_ALLOC_HYBRID);
|
| +
|
| q = cur;
|
| while (*cur != 0) {
|
| if (cur[0] == '&') {
|
| @@ -1460,19 +1499,8 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| * Save the current text.
|
| */
|
| if (cur != q) {
|
| - if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
|
| - xmlNodeAddContentLen(last, q, cur - q);
|
| - } else {
|
| - node = xmlNewDocTextLen(doc, q, cur - q);
|
| - if (node == NULL) return(ret);
|
| - if (last == NULL)
|
| - last = ret = node;
|
| - else {
|
| - last->next = node;
|
| - node->prev = last;
|
| - last = node;
|
| - }
|
| - }
|
| + if (xmlBufAdd(buf, q, cur - q))
|
| + goto out;
|
| }
|
| q = cur;
|
| if ((cur[1] == '#') && (cur[2] == 'x')) {
|
| @@ -1525,7 +1553,7 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| if (*cur == 0) {
|
| xmlTreeErr(XML_TREE_UNTERMINATED_ENTITY,
|
| (xmlNodePtr) doc, (const char *) q);
|
| - return(ret);
|
| + goto out;
|
| }
|
| if (cur != q) {
|
| /*
|
| @@ -1535,23 +1563,32 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| ent = xmlGetDocEntity(doc, val);
|
| if ((ent != NULL) &&
|
| (ent->etype == XML_INTERNAL_PREDEFINED_ENTITY)) {
|
| - if (last == NULL) {
|
| - node = xmlNewDocText(doc, ent->content);
|
| - last = ret = node;
|
| - } else if (last->type != XML_TEXT_NODE) {
|
| - node = xmlNewDocText(doc, ent->content);
|
| - last = xmlAddNextSibling(last, node);
|
| - } else
|
| - xmlNodeAddContent(last, ent->content);
|
| +
|
| + if (xmlBufCat(buf, ent->content))
|
| + goto out;
|
|
|
| } else {
|
| /*
|
| + * Flush buffer so far
|
| + */
|
| + if (!xmlBufIsEmpty(buf)) {
|
| + node = xmlNewDocText(doc, NULL);
|
| + node->content = xmlBufDetach(buf);
|
| +
|
| + if (last == NULL) {
|
| + last = ret = node;
|
| + } else {
|
| + last = xmlAddNextSibling(last, node);
|
| + }
|
| + }
|
| +
|
| + /*
|
| * Create a new REFERENCE_REF node
|
| */
|
| node = xmlNewReference(doc, val);
|
| if (node == NULL) {
|
| if (val != NULL) xmlFree(val);
|
| - return(ret);
|
| + goto out;
|
| }
|
| else if ((ent != NULL) && (ent->children == NULL)) {
|
| xmlNodePtr temp;
|
| @@ -1577,19 +1614,15 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| q = cur;
|
| }
|
| if (charval != 0) {
|
| - xmlChar buf[10];
|
| + xmlChar buffer[10];
|
| int len;
|
|
|
| - len = xmlCopyCharMultiByte(buf, charval);
|
| - buf[len] = 0;
|
| - node = xmlNewDocText(doc, buf);
|
| - if (node != NULL) {
|
| - if (last == NULL) {
|
| - last = ret = node;
|
| - } else {
|
| - last = xmlAddNextSibling(last, node);
|
| - }
|
| - }
|
| + len = xmlCopyCharMultiByte(buffer, charval);
|
| + buffer[len] = 0;
|
| +
|
| + if (xmlBufCat(buf, buffer))
|
| + goto out;
|
| + charval = 0;
|
| }
|
| } else
|
| cur++;
|
| @@ -1598,18 +1631,22 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| /*
|
| * Handle the last piece of text.
|
| */
|
| - if ((last != NULL) && (last->type == XML_TEXT_NODE)) {
|
| - xmlNodeAddContentLen(last, q, cur - q);
|
| + xmlBufAdd(buf, q, cur - q);
|
| + }
|
| +
|
| + if (!xmlBufIsEmpty(buf)) {
|
| + node = xmlNewDocText(doc, NULL);
|
| + node->content = xmlBufDetach(buf);
|
| +
|
| + if (last == NULL) {
|
| + last = ret = node;
|
| } else {
|
| - node = xmlNewDocTextLen(doc, q, cur - q);
|
| - if (node == NULL) return(ret);
|
| - if (last == NULL) {
|
| - last = ret = node;
|
| - } else {
|
| - last = xmlAddNextSibling(last, node);
|
| - }
|
| + last = xmlAddNextSibling(last, node);
|
| }
|
| }
|
| +
|
| +out:
|
| + xmlBufFree(buf);
|
| return(ret);
|
| }
|
|
|
| @@ -1625,14 +1662,19 @@ xmlStringGetNodeList(xmlDocPtr doc, const xmlChar *value) {
|
| * Returns a pointer to the string copy, the caller must free it with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
|
| +xmlNodeListGetString(xmlDocPtr doc, const xmlNode *list, int inLine)
|
| {
|
| - xmlNodePtr node = list;
|
| + const xmlNode *node = list;
|
| xmlChar *ret = NULL;
|
| xmlEntityPtr ent;
|
| + int attr;
|
|
|
| if (list == NULL)
|
| return (NULL);
|
| + if ((list->parent != NULL) && (list->parent->type == XML_ATTRIBUTE_NODE))
|
| + attr = 1;
|
| + else
|
| + attr = 0;
|
|
|
| while (node != NULL) {
|
| if ((node->type == XML_TEXT_NODE) ||
|
| @@ -1642,7 +1684,10 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
|
| } else {
|
| xmlChar *buffer;
|
|
|
| - buffer = xmlEncodeEntitiesReentrant(doc, node->content);
|
| + if (attr)
|
| + buffer = xmlEncodeAttributeEntities(doc, node->content);
|
| + else
|
| + buffer = xmlEncodeEntitiesReentrant(doc, node->content);
|
| if (buffer != NULL) {
|
| ret = xmlStrcat(ret, buffer);
|
| xmlFree(buffer);
|
| @@ -1707,9 +1752,9 @@ xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, int inLine)
|
| * Returns a pointer to the string copy, the caller must free it with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlNodeListGetRawString(xmlDocPtr doc, xmlNodePtr list, int inLine)
|
| +xmlNodeListGetRawString(const xmlDoc *doc, const xmlNode *list, int inLine)
|
| {
|
| - xmlNodePtr node = list;
|
| + const xmlNode *node = list;
|
| xmlChar *ret = NULL;
|
| xmlEntityPtr ent;
|
|
|
| @@ -2538,7 +2583,7 @@ xmlNewCharRef(xmlDocPtr doc, const xmlChar *name) {
|
| * Returns a pointer to the new node object.
|
| */
|
| xmlNodePtr
|
| -xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
|
| +xmlNewReference(const xmlDoc *doc, const xmlChar *name) {
|
| xmlNodePtr cur;
|
| xmlEntityPtr ent;
|
|
|
| @@ -2556,7 +2601,7 @@ xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
|
| memset(cur, 0, sizeof(xmlNode));
|
| cur->type = XML_ENTITY_REF_NODE;
|
|
|
| - cur->doc = doc;
|
| + cur->doc = (xmlDoc *)doc;
|
| if (name[0] == '&') {
|
| int len;
|
| name++;
|
| @@ -2594,11 +2639,11 @@ xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
|
| * Returns a pointer to the new node object.
|
| */
|
| xmlNodePtr
|
| -xmlNewDocText(xmlDocPtr doc, const xmlChar *content) {
|
| +xmlNewDocText(const xmlDoc *doc, const xmlChar *content) {
|
| xmlNodePtr cur;
|
|
|
| cur = xmlNewText(content);
|
| - if (cur != NULL) cur->doc = doc;
|
| + if (cur != NULL) cur->doc = (xmlDoc *)doc;
|
| return(cur);
|
| }
|
|
|
| @@ -2748,7 +2793,7 @@ void
|
| xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
|
| xmlAttrPtr prop;
|
|
|
| - if (tree == NULL)
|
| + if ((tree == NULL) || (tree->type == XML_NAMESPACE_DECL))
|
| return;
|
| if (tree->doc != doc) {
|
| if(tree->type == XML_ELEMENT_NODE) {
|
| @@ -2776,7 +2821,7 @@ void
|
| xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
|
| xmlNodePtr cur;
|
|
|
| - if (list == NULL)
|
| + if ((list == NULL) || (list->type == XML_NAMESPACE_DECL))
|
| return;
|
| cur = list;
|
| while (cur != NULL) {
|
| @@ -2883,7 +2928,9 @@ static xmlNodePtr
|
| xmlAddPropSibling(xmlNodePtr prev, xmlNodePtr cur, xmlNodePtr prop) {
|
| xmlAttrPtr attr;
|
|
|
| - if (cur->type != XML_ATTRIBUTE_NODE)
|
| + if ((cur == NULL) || (cur->type != XML_ATTRIBUTE_NODE) ||
|
| + (prop == NULL) || (prop->type != XML_ATTRIBUTE_NODE) ||
|
| + ((prev != NULL) && (prev->type != XML_ATTRIBUTE_NODE)))
|
| return(NULL);
|
|
|
| /* check if an attribute with the same name exists */
|
| @@ -2931,14 +2978,14 @@ xmlAddPropSibling(xmlNodePtr prev, xmlNodePtr cur, xmlNodePtr prop) {
|
| */
|
| xmlNodePtr
|
| xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddNextSibling : cur == NULL\n");
|
| #endif
|
| return(NULL);
|
| }
|
| - if (elem == NULL) {
|
| + if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddNextSibling : elem == NULL\n");
|
| @@ -2992,7 +3039,7 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| }
|
|
|
| #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
|
| - defined(LIBXML_SCHEMAS_ENABLED)
|
| + defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
|
| /**
|
| * xmlAddPrevSibling:
|
| * @cur: the child node
|
| @@ -3009,14 +3056,14 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| */
|
| xmlNodePtr
|
| xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddPrevSibling : cur == NULL\n");
|
| #endif
|
| return(NULL);
|
| }
|
| - if (elem == NULL) {
|
| + if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddPrevSibling : elem == NULL\n");
|
| @@ -3087,7 +3134,7 @@ xmlNodePtr
|
| xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| xmlNodePtr parent;
|
|
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddSibling : cur == NULL\n");
|
| @@ -3095,7 +3142,7 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
| return(NULL);
|
| }
|
|
|
| - if (elem == NULL) {
|
| + if ((elem == NULL) || (elem->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddSibling : elem == NULL\n");
|
| @@ -3163,7 +3210,7 @@ xmlNodePtr
|
| xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
|
| xmlNodePtr prev;
|
|
|
| - if (parent == NULL) {
|
| + if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddChildList : parent == NULL\n");
|
| @@ -3171,7 +3218,7 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
|
| return(NULL);
|
| }
|
|
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddChildList : child == NULL\n");
|
| @@ -3249,7 +3296,7 @@ xmlNodePtr
|
| xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
| xmlNodePtr prev;
|
|
|
| - if (parent == NULL) {
|
| + if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddChild : parent == NULL\n");
|
| @@ -3257,7 +3304,7 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
| return(NULL);
|
| }
|
|
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlAddChild : child == NULL\n");
|
| @@ -3370,8 +3417,8 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
| * Returns the last child or NULL if none.
|
| */
|
| xmlNodePtr
|
| -xmlGetLastChild(xmlNodePtr parent) {
|
| - if (parent == NULL) {
|
| +xmlGetLastChild(const xmlNode *parent) {
|
| + if ((parent == NULL) || (parent->type == XML_NAMESPACE_DECL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlGetLastChild : parent == NULL\n");
|
| @@ -3409,6 +3456,7 @@ xmlChildElementCount(xmlNodePtr parent) {
|
| case XML_ELEMENT_NODE:
|
| case XML_ENTITY_NODE:
|
| case XML_DOCUMENT_NODE:
|
| + case XML_DOCUMENT_FRAG_NODE:
|
| case XML_HTML_DOCUMENT_NODE:
|
| cur = parent->children;
|
| break;
|
| @@ -3444,6 +3492,7 @@ xmlFirstElementChild(xmlNodePtr parent) {
|
| case XML_ELEMENT_NODE:
|
| case XML_ENTITY_NODE:
|
| case XML_DOCUMENT_NODE:
|
| + case XML_DOCUMENT_FRAG_NODE:
|
| case XML_HTML_DOCUMENT_NODE:
|
| cur = parent->children;
|
| break;
|
| @@ -3479,6 +3528,7 @@ xmlLastElementChild(xmlNodePtr parent) {
|
| case XML_ELEMENT_NODE:
|
| case XML_ENTITY_NODE:
|
| case XML_DOCUMENT_NODE:
|
| + case XML_DOCUMENT_FRAG_NODE:
|
| case XML_HTML_DOCUMENT_NODE:
|
| cur = parent->last;
|
| break;
|
| @@ -3721,6 +3771,10 @@ xmlFreeNode(xmlNodePtr cur) {
|
| * @cur: the node
|
| *
|
| * Unlink a node from it's current context, the node is not freed
|
| + * If one need to free the node, use xmlFreeNode() routine after the
|
| + * unlink to discard it.
|
| + * Note that namespace nodes can't be unlinked as they do not have
|
| + * pointer to their parent.
|
| */
|
| void
|
| xmlUnlinkNode(xmlNodePtr cur) {
|
| @@ -3731,6 +3785,8 @@ xmlUnlinkNode(xmlNodePtr cur) {
|
| #endif
|
| return;
|
| }
|
| + if (cur->type == XML_NAMESPACE_DECL)
|
| + return;
|
| if (cur->type == XML_DTD_NODE) {
|
| xmlDocPtr doc;
|
| doc = cur->doc;
|
| @@ -3799,14 +3855,15 @@ xmlUnlinkNode(xmlNodePtr cur) {
|
| xmlNodePtr
|
| xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
|
| if (old == cur) return(NULL);
|
| - if ((old == NULL) || (old->parent == NULL)) {
|
| + if ((old == NULL) || (old->type == XML_NAMESPACE_DECL) ||
|
| + (old->parent == NULL)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlReplaceNode : old == NULL or without parent\n");
|
| #endif
|
| return(NULL);
|
| }
|
| - if (cur == NULL) {
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL)) {
|
| xmlUnlinkNode(old);
|
| return(old);
|
| }
|
| @@ -3920,6 +3977,8 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
|
| xmlAttrPtr ret;
|
|
|
| if (cur == NULL) return(NULL);
|
| + if ((target != NULL) && (target->type != XML_ELEMENT_NODE))
|
| + return(NULL);
|
| if (target != NULL)
|
| ret = xmlNewDocProp(target->doc, cur->name, NULL);
|
| else if (doc != NULL)
|
| @@ -4039,6 +4098,8 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
|
| xmlAttrPtr ret = NULL;
|
| xmlAttrPtr p = NULL,q;
|
|
|
| + if ((target != NULL) && (target->type != XML_ELEMENT_NODE))
|
| + return(NULL);
|
| while (cur != NULL) {
|
| q = xmlCopyProp(target, cur);
|
| if (q == NULL)
|
| @@ -4075,7 +4136,7 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) {
|
| */
|
|
|
| static xmlNodePtr
|
| -xmlStaticCopyNode(const xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
|
| +xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
|
| int extended) {
|
| xmlNodePtr ret;
|
|
|
| @@ -4241,6 +4302,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
| }
|
| if (doc->intSubset == NULL) {
|
| q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
|
| + if (q == NULL) return(NULL);
|
| q->doc = doc;
|
| q->parent = parent;
|
| doc->intSubset = (xmlDtdPtr) q;
|
| @@ -4252,6 +4314,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
| } else
|
| #endif /* LIBXML_TREE_ENABLED */
|
| q = xmlStaticCopyNode(node, doc, parent, 1);
|
| + if (q == NULL) return(NULL);
|
| if (ret == NULL) {
|
| q->prev = NULL;
|
| ret = p = q;
|
| @@ -4278,7 +4341,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
|
| * Returns: a new #xmlNodePtr, or NULL in case of error.
|
| */
|
| xmlNodePtr
|
| -xmlCopyNode(const xmlNodePtr node, int extended) {
|
| +xmlCopyNode(xmlNodePtr node, int extended) {
|
| xmlNodePtr ret;
|
|
|
| ret = xmlStaticCopyNode(node, NULL, NULL, extended);
|
| @@ -4298,7 +4361,7 @@ xmlCopyNode(const xmlNodePtr node, int extended) {
|
| * Returns: a new #xmlNodePtr, or NULL in case of error.
|
| */
|
| xmlNodePtr
|
| -xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
|
| +xmlDocCopyNode(xmlNodePtr node, xmlDocPtr doc, int extended) {
|
| xmlNodePtr ret;
|
|
|
| ret = xmlStaticCopyNode(node, doc, NULL, extended);
|
| @@ -4314,7 +4377,7 @@ xmlDocCopyNode(const xmlNodePtr node, xmlDocPtr doc, int extended) {
|
| *
|
| * Returns: a new #xmlNodePtr, or NULL in case of error.
|
| */
|
| -xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, const xmlNodePtr node) {
|
| +xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, xmlNodePtr node) {
|
| xmlNodePtr ret = xmlStaticCopyNodeList(node, doc, NULL);
|
| return(ret);
|
| }
|
| @@ -4328,7 +4391,7 @@ xmlNodePtr xmlDocCopyNodeList(xmlDocPtr doc, const xmlNodePtr node) {
|
| *
|
| * Returns: a new #xmlNodePtr, or NULL in case of error.
|
| */
|
| -xmlNodePtr xmlCopyNodeList(const xmlNodePtr node) {
|
| +xmlNodePtr xmlCopyNodeList(xmlNodePtr node) {
|
| xmlNodePtr ret = xmlStaticCopyNodeList(node, NULL, NULL);
|
| return(ret);
|
| }
|
| @@ -4454,6 +4517,10 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
|
| #ifdef LIBXML_TREE_ENABLED
|
| if (doc->intSubset != NULL) {
|
| ret->intSubset = xmlCopyDtd(doc->intSubset);
|
| + if (ret->intSubset == NULL) {
|
| + xmlFreeDoc(ret);
|
| + return(NULL);
|
| + }
|
| xmlSetTreeDoc((xmlNodePtr)ret->intSubset, ret);
|
| ret->intSubset->parent = ret;
|
| }
|
| @@ -4484,39 +4551,71 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
|
| ************************************************************************/
|
|
|
| /**
|
| - * xmlGetLineNo:
|
| + * xmlGetLineNoInternal:
|
| * @node: valid node
|
| + * @depth: used to limit any risk of recursion
|
| *
|
| - * Get line number of @node. This requires activation of this option
|
| - * before invoking the parser by calling xmlLineNumbersDefault(1)
|
| + * Get line number of @node.
|
| + * Try to override the limitation of lines being store in 16 bits ints
|
| *
|
| * Returns the line number if successful, -1 otherwise
|
| */
|
| -long
|
| -xmlGetLineNo(xmlNodePtr node)
|
| +static long
|
| +xmlGetLineNoInternal(const xmlNode *node, int depth)
|
| {
|
| long result = -1;
|
|
|
| + if (depth >= 5)
|
| + return(-1);
|
| +
|
| if (!node)
|
| return result;
|
| if ((node->type == XML_ELEMENT_NODE) ||
|
| (node->type == XML_TEXT_NODE) ||
|
| (node->type == XML_COMMENT_NODE) ||
|
| - (node->type == XML_PI_NODE))
|
| - result = (long) node->line;
|
| - else if ((node->prev != NULL) &&
|
| + (node->type == XML_PI_NODE)) {
|
| + if (node->line == 65535) {
|
| + if ((node->type == XML_TEXT_NODE) && (node->psvi != NULL))
|
| + result = (long) node->psvi;
|
| + else if ((node->type == XML_ELEMENT_NODE) &&
|
| + (node->children != NULL))
|
| + result = xmlGetLineNoInternal(node->children, depth + 1);
|
| + else if (node->next != NULL)
|
| + result = xmlGetLineNoInternal(node->next, depth + 1);
|
| + else if (node->prev != NULL)
|
| + result = xmlGetLineNoInternal(node->prev, depth + 1);
|
| + }
|
| + if ((result == -1) || (result == 65535))
|
| + result = (long) node->line;
|
| + } else if ((node->prev != NULL) &&
|
| ((node->prev->type == XML_ELEMENT_NODE) ||
|
| (node->prev->type == XML_TEXT_NODE) ||
|
| (node->prev->type == XML_COMMENT_NODE) ||
|
| (node->prev->type == XML_PI_NODE)))
|
| - result = xmlGetLineNo(node->prev);
|
| + result = xmlGetLineNoInternal(node->prev, depth + 1);
|
| else if ((node->parent != NULL) &&
|
| (node->parent->type == XML_ELEMENT_NODE))
|
| - result = xmlGetLineNo(node->parent);
|
| + result = xmlGetLineNoInternal(node->parent, depth + 1);
|
|
|
| return result;
|
| }
|
|
|
| +/**
|
| + * xmlGetLineNo:
|
| + * @node: valid node
|
| + *
|
| + * Get line number of @node.
|
| + * Try to override the limitation of lines being store in 16 bits ints
|
| + * if XML_PARSE_BIG_LINES parser option was used
|
| + *
|
| + * Returns the line number if successful, -1 otherwise
|
| + */
|
| +long
|
| +xmlGetLineNo(const xmlNode *node)
|
| +{
|
| + return(xmlGetLineNoInternal(node, 0));
|
| +}
|
| +
|
| #if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
|
| /**
|
| * xmlGetNodePath:
|
| @@ -4528,9 +4627,9 @@ xmlGetLineNo(xmlNodePtr node)
|
| * the returned string
|
| */
|
| xmlChar *
|
| -xmlGetNodePath(xmlNodePtr node)
|
| +xmlGetNodePath(const xmlNode *node)
|
| {
|
| - xmlNodePtr cur, tmp, next;
|
| + const xmlNode *cur, *tmp, *next;
|
| xmlChar *buffer = NULL, *temp;
|
| size_t buf_len;
|
| xmlChar *buf;
|
| @@ -4539,7 +4638,7 @@ xmlGetNodePath(xmlNodePtr node)
|
| char nametemp[100];
|
| int occur = 0, generic;
|
|
|
| - if (node == NULL)
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| return (NULL);
|
|
|
| buf_len = 500;
|
| @@ -4774,7 +4873,7 @@ xmlGetNodePath(xmlNodePtr node)
|
| * Returns the #xmlNodePtr for the root or NULL
|
| */
|
| xmlNodePtr
|
| -xmlDocGetRootElement(xmlDocPtr doc) {
|
| +xmlDocGetRootElement(const xmlDoc *doc) {
|
| xmlNodePtr ret;
|
|
|
| if (doc == NULL) return(NULL);
|
| @@ -4804,7 +4903,7 @@ xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
|
| xmlNodePtr old = NULL;
|
|
|
| if (doc == NULL) return(NULL);
|
| - if (root == NULL)
|
| + if ((root == NULL) || (root->type == XML_NAMESPACE_DECL))
|
| return(NULL);
|
| xmlUnlinkNode(root);
|
| xmlSetTreeDoc(root, doc);
|
| @@ -4888,9 +4987,11 @@ xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlNodeGetLang(xmlNodePtr cur) {
|
| +xmlNodeGetLang(const xmlNode *cur) {
|
| xmlChar *lang;
|
|
|
| + if ((cur == NULL) || (cur->type == XML_NAMESPACE_DECL))
|
| + return(NULL);
|
| while (cur != NULL) {
|
| lang = xmlGetNsProp(cur, BAD_CAST "lang", XML_XML_NAMESPACE);
|
| if (lang != NULL)
|
| @@ -4967,9 +5068,11 @@ xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
|
| * Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
|
| */
|
| int
|
| -xmlNodeGetSpacePreserve(xmlNodePtr cur) {
|
| +xmlNodeGetSpacePreserve(const xmlNode *cur) {
|
| xmlChar *space;
|
|
|
| + if ((cur == NULL) || (cur->type != XML_ELEMENT_NODE))
|
| + return(-1);
|
| while (cur != NULL) {
|
| space = xmlGetNsProp(cur, BAD_CAST "space", XML_XML_NAMESPACE);
|
| if (space != NULL) {
|
| @@ -5000,6 +5103,7 @@ void
|
| xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
|
| xmlDocPtr doc;
|
| xmlDictPtr dict;
|
| + const xmlChar *freeme = NULL;
|
|
|
| if (cur == NULL) return;
|
| if (name == NULL) return;
|
| @@ -5037,12 +5141,16 @@ xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
|
| dict = NULL;
|
| if (dict != NULL) {
|
| if ((cur->name != NULL) && (!xmlDictOwns(dict, cur->name)))
|
| - xmlFree((xmlChar *) cur->name);
|
| + freeme = cur->name;
|
| cur->name = xmlDictLookup(dict, name, -1);
|
| } else {
|
| - if (cur->name != NULL) xmlFree((xmlChar *) cur->name);
|
| + if (cur->name != NULL)
|
| + freeme = cur->name;
|
| cur->name = xmlStrdup(name);
|
| }
|
| +
|
| + if (freeme)
|
| + xmlFree((xmlChar *) freeme);
|
| }
|
| #endif
|
|
|
| @@ -5130,12 +5238,14 @@ xmlNodeSetBase(xmlNodePtr cur, const xmlChar* uri) {
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
|
| +xmlNodeGetBase(const xmlDoc *doc, const xmlNode *cur) {
|
| xmlChar *oldbase = NULL;
|
| xmlChar *base, *newbase;
|
|
|
| if ((cur == NULL) && (doc == NULL))
|
| return(NULL);
|
| + if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
|
| + return(NULL);
|
| if (doc == NULL) doc = cur->doc;
|
| if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
|
| cur = doc->children;
|
| @@ -5213,27 +5323,55 @@ xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
|
| * Returns 0 in case of success and -1 in case of error.
|
| */
|
| int
|
| -xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
| +xmlNodeBufGetContent(xmlBufferPtr buffer, const xmlNode *cur)
|
| {
|
| + xmlBufPtr buf;
|
| + int ret;
|
| +
|
| if ((cur == NULL) || (buffer == NULL)) return(-1);
|
| + buf = xmlBufFromBuffer(buffer);
|
| + ret = xmlBufGetNodeContent(buf, cur);
|
| + buffer = xmlBufBackToBuffer(buf);
|
| + if ((ret < 0) || (buffer == NULL))
|
| + return(-1);
|
| + return(0);
|
| +}
|
| +
|
| +/**
|
| + * xmlBufGetNodeContent:
|
| + * @buf: a buffer xmlBufPtr
|
| + * @cur: the node being read
|
| + *
|
| + * Read the value of a node @cur, this can be either the text carried
|
| + * directly by this node if it's a TEXT node or the aggregate string
|
| + * of the values carried by this node child's (TEXT and ENTITY_REF).
|
| + * Entity references are substituted.
|
| + * Fills up the buffer @buf with this value
|
| + *
|
| + * Returns 0 in case of success and -1 in case of error.
|
| + */
|
| +int
|
| +xmlBufGetNodeContent(xmlBufPtr buf, const xmlNode *cur)
|
| +{
|
| + if ((cur == NULL) || (buf == NULL)) return(-1);
|
| switch (cur->type) {
|
| case XML_CDATA_SECTION_NODE:
|
| case XML_TEXT_NODE:
|
| - xmlBufferCat(buffer, cur->content);
|
| + xmlBufCat(buf, cur->content);
|
| break;
|
| case XML_DOCUMENT_FRAG_NODE:
|
| case XML_ELEMENT_NODE:{
|
| - xmlNodePtr tmp = cur;
|
| + const xmlNode *tmp = cur;
|
|
|
| while (tmp != NULL) {
|
| switch (tmp->type) {
|
| case XML_CDATA_SECTION_NODE:
|
| case XML_TEXT_NODE:
|
| if (tmp->content != NULL)
|
| - xmlBufferCat(buffer, tmp->content);
|
| + xmlBufCat(buf, tmp->content);
|
| break;
|
| case XML_ENTITY_REF_NODE:
|
| - xmlNodeBufGetContent(buffer, tmp);
|
| + xmlBufGetNodeContent(buf, tmp);
|
| break;
|
| default:
|
| break;
|
| @@ -5277,16 +5415,16 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
|
|
| while (tmp != NULL) {
|
| if (tmp->type == XML_TEXT_NODE)
|
| - xmlBufferCat(buffer, tmp->content);
|
| + xmlBufCat(buf, tmp->content);
|
| else
|
| - xmlNodeBufGetContent(buffer, tmp);
|
| + xmlBufGetNodeContent(buf, tmp);
|
| tmp = tmp->next;
|
| }
|
| break;
|
| }
|
| case XML_COMMENT_NODE:
|
| case XML_PI_NODE:
|
| - xmlBufferCat(buffer, cur->content);
|
| + xmlBufCat(buf, cur->content);
|
| break;
|
| case XML_ENTITY_REF_NODE:{
|
| xmlEntityPtr ent;
|
| @@ -5304,7 +5442,7 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
| * xmlNodeGetContent() which handles all possible node types */
|
| tmp = ent->children;
|
| while (tmp) {
|
| - xmlNodeBufGetContent(buffer, tmp);
|
| + xmlBufGetNodeContent(buf, tmp);
|
| tmp = tmp->next;
|
| }
|
| break;
|
| @@ -5326,13 +5464,13 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
| if ((cur->type == XML_ELEMENT_NODE) ||
|
| (cur->type == XML_TEXT_NODE) ||
|
| (cur->type == XML_CDATA_SECTION_NODE)) {
|
| - xmlNodeBufGetContent(buffer, cur);
|
| + xmlBufGetNodeContent(buf, cur);
|
| }
|
| cur = cur->next;
|
| }
|
| break;
|
| case XML_NAMESPACE_DECL:
|
| - xmlBufferCat(buffer, ((xmlNsPtr) cur)->href);
|
| + xmlBufCat(buf, ((xmlNsPtr) cur)->href);
|
| break;
|
| case XML_ELEMENT_DECL:
|
| case XML_ATTRIBUTE_DECL:
|
| @@ -5341,6 +5479,7 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
| }
|
| return(0);
|
| }
|
| +
|
| /**
|
| * xmlNodeGetContent:
|
| * @cur: the node being read
|
| @@ -5353,23 +5492,22 @@ xmlNodeBufGetContent(xmlBufferPtr buffer, xmlNodePtr cur)
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlNodeGetContent(xmlNodePtr cur)
|
| +xmlNodeGetContent(const xmlNode *cur)
|
| {
|
| if (cur == NULL)
|
| return (NULL);
|
| switch (cur->type) {
|
| case XML_DOCUMENT_FRAG_NODE:
|
| case XML_ELEMENT_NODE:{
|
| - xmlBufferPtr buffer;
|
| + xmlBufPtr buf;
|
| xmlChar *ret;
|
|
|
| - buffer = xmlBufferCreateSize(64);
|
| - if (buffer == NULL)
|
| + buf = xmlBufCreateSize(64);
|
| + if (buf == NULL)
|
| return (NULL);
|
| - xmlNodeBufGetContent(buffer, cur);
|
| - ret = buffer->content;
|
| - buffer->content = NULL;
|
| - xmlBufferFree(buffer);
|
| + xmlBufGetNodeContent(buf, cur);
|
| + ret = xmlBufDetach(buf);
|
| + xmlBufFree(buf);
|
| return (ret);
|
| }
|
| case XML_ATTRIBUTE_NODE:
|
| @@ -5381,7 +5519,7 @@ xmlNodeGetContent(xmlNodePtr cur)
|
| return (NULL);
|
| case XML_ENTITY_REF_NODE:{
|
| xmlEntityPtr ent;
|
| - xmlBufferPtr buffer;
|
| + xmlBufPtr buf;
|
| xmlChar *ret;
|
|
|
| /* lookup entity declaration */
|
| @@ -5389,15 +5527,14 @@ xmlNodeGetContent(xmlNodePtr cur)
|
| if (ent == NULL)
|
| return (NULL);
|
|
|
| - buffer = xmlBufferCreate();
|
| - if (buffer == NULL)
|
| + buf = xmlBufCreate();
|
| + if (buf == NULL)
|
| return (NULL);
|
|
|
| - xmlNodeBufGetContent(buffer, cur);
|
| + xmlBufGetNodeContent(buf, cur);
|
|
|
| - ret = buffer->content;
|
| - buffer->content = NULL;
|
| - xmlBufferFree(buffer);
|
| + ret = xmlBufDetach(buf);
|
| + xmlBufFree(buf);
|
| return (ret);
|
| }
|
| case XML_ENTITY_NODE:
|
| @@ -5412,18 +5549,17 @@ xmlNodeGetContent(xmlNodePtr cur)
|
| case XML_DOCB_DOCUMENT_NODE:
|
| #endif
|
| case XML_HTML_DOCUMENT_NODE: {
|
| - xmlBufferPtr buffer;
|
| + xmlBufPtr buf;
|
| xmlChar *ret;
|
|
|
| - buffer = xmlBufferCreate();
|
| - if (buffer == NULL)
|
| + buf = xmlBufCreate();
|
| + if (buf == NULL)
|
| return (NULL);
|
|
|
| - xmlNodeBufGetContent(buffer, (xmlNodePtr) cur);
|
| + xmlBufGetNodeContent(buf, (xmlNodePtr) cur);
|
|
|
| - ret = buffer->content;
|
| - buffer->content = NULL;
|
| - xmlBufferFree(buffer);
|
| + ret = xmlBufDetach(buf);
|
| + xmlBufFree(buf);
|
| return (ret);
|
| }
|
| case XML_NAMESPACE_DECL: {
|
| @@ -5736,7 +5872,7 @@ xmlTextMerge(xmlNodePtr first, xmlNodePtr second) {
|
| * namespace if defined
|
| */
|
| xmlNsPtr *
|
| -xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
|
| +xmlGetNsList(const xmlDoc *doc ATTRIBUTE_UNUSED, const xmlNode *node)
|
| {
|
| xmlNsPtr cur;
|
| xmlNsPtr *ret = NULL;
|
| @@ -5744,6 +5880,9 @@ xmlGetNsList(xmlDocPtr doc ATTRIBUTE_UNUSED, xmlNodePtr node)
|
| int maxns = 10;
|
| int i;
|
|
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| + return(NULL);
|
| +
|
| while (node != NULL) {
|
| if (node->type == XML_ELEMENT_NODE) {
|
| cur = node->nsDef;
|
| @@ -5840,9 +5979,9 @@ xmlNsPtr
|
| xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace) {
|
|
|
| xmlNsPtr cur;
|
| - xmlNodePtr orig = node;
|
| + const xmlNode *orig = node;
|
|
|
| - if (node == NULL) return(NULL);
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL)) return(NULL);
|
| if ((nameSpace != NULL) &&
|
| (xmlStrEqual(nameSpace, (const xmlChar *)"xml"))) {
|
| if ((doc == NULL) && (node->type == XML_ELEMENT_NODE)) {
|
| @@ -5972,7 +6111,7 @@ xmlSearchNsByHref(xmlDocPtr doc, xmlNodePtr node, const xmlChar * href)
|
| xmlNodePtr orig = node;
|
| int is_attr;
|
|
|
| - if ((node == NULL) || (href == NULL))
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) || (href == NULL))
|
| return (NULL);
|
| if (xmlStrEqual(href, XML_XML_NAMESPACE)) {
|
| /*
|
| @@ -6063,7 +6202,7 @@ xmlNewReconciliedNs(xmlDocPtr doc, xmlNodePtr tree, xmlNsPtr ns) {
|
| xmlChar prefix[50];
|
| int counter = 1;
|
|
|
| - if (tree == NULL) {
|
| + if ((tree == NULL) || (tree->type != XML_ELEMENT_NODE)) {
|
| #ifdef DEBUG_TREE
|
| xmlGenericError(xmlGenericErrorContext,
|
| "xmlNewReconciliedNs : tree == NULL\n");
|
| @@ -6309,7 +6448,7 @@ xmlReconciliateNs(xmlDocPtr doc, xmlNodePtr tree) {
|
| #endif /* LIBXML_TREE_ENABLED */
|
|
|
| static xmlAttrPtr
|
| -xmlGetPropNodeInternal(xmlNodePtr node, const xmlChar *name,
|
| +xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
|
| const xmlChar *nsName, int useDTD)
|
| {
|
| xmlAttrPtr prop;
|
| @@ -6423,7 +6562,7 @@ xmlGetPropNodeInternal(xmlNodePtr node, const xmlChar *name,
|
| }
|
|
|
| static xmlChar*
|
| -xmlGetPropNodeValueInternal(xmlAttrPtr prop)
|
| +xmlGetPropNodeValueInternal(const xmlAttr *prop)
|
| {
|
| if (prop == NULL)
|
| return(NULL);
|
| @@ -6469,7 +6608,7 @@ xmlGetPropNodeValueInternal(xmlAttrPtr prop)
|
| * neither was found.
|
| */
|
| xmlAttrPtr
|
| -xmlHasProp(xmlNodePtr node, const xmlChar *name) {
|
| +xmlHasProp(const xmlNode *node, const xmlChar *name) {
|
| xmlAttrPtr prop;
|
| xmlDocPtr doc;
|
|
|
| @@ -6524,7 +6663,7 @@ xmlHasProp(xmlNodePtr node, const xmlChar *name) {
|
| * if neither was found.
|
| */
|
| xmlAttrPtr
|
| -xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
|
| +xmlHasNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
|
|
|
| return(xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD));
|
| }
|
| @@ -6546,7 +6685,7 @@ xmlHasNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlGetProp(xmlNodePtr node, const xmlChar *name) {
|
| +xmlGetProp(const xmlNode *node, const xmlChar *name) {
|
| xmlAttrPtr prop;
|
|
|
| prop = xmlHasProp(node, name);
|
| @@ -6571,7 +6710,7 @@ xmlGetProp(xmlNodePtr node, const xmlChar *name) {
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name) {
|
| +xmlGetNoNsProp(const xmlNode *node, const xmlChar *name) {
|
| xmlAttrPtr prop;
|
|
|
| prop = xmlGetPropNodeInternal(node, name, NULL, xmlCheckDTD);
|
| @@ -6596,7 +6735,7 @@ xmlGetNoNsProp(xmlNodePtr node, const xmlChar *name) {
|
| * It's up to the caller to free the memory with xmlFree().
|
| */
|
| xmlChar *
|
| -xmlGetNsProp(xmlNodePtr node, const xmlChar *name, const xmlChar *nameSpace) {
|
| +xmlGetNsProp(const xmlNode *node, const xmlChar *name, const xmlChar *nameSpace) {
|
| xmlAttrPtr prop;
|
|
|
| prop = xmlGetPropNodeInternal(node, name, nameSpace, xmlCheckDTD);
|
| @@ -6761,7 +6900,7 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
|
| * Returns 1 yes, 0 no
|
| */
|
| int
|
| -xmlNodeIsText(xmlNodePtr node) {
|
| +xmlNodeIsText(const xmlNode *node) {
|
| if (node == NULL) return(0);
|
|
|
| if (node->type == XML_TEXT_NODE) return(1);
|
| @@ -6778,7 +6917,7 @@ xmlNodeIsText(xmlNodePtr node) {
|
| * Returns 1 yes, 0 no
|
| */
|
| int
|
| -xmlIsBlankNode(xmlNodePtr node) {
|
| +xmlIsBlankNode(const xmlNode *node) {
|
| const xmlChar *cur;
|
| if (node == NULL) return(0);
|
|
|
| @@ -6903,6 +7042,34 @@ xmlBufferCreateSize(size_t size) {
|
| }
|
|
|
| /**
|
| + * xmlBufferDetach:
|
| + * @buf: the buffer
|
| + *
|
| + * Remove the string contained in a buffer and gie it back to the
|
| + * caller. The buffer is reset to an empty content.
|
| + * This doesn't work with immutable buffers as they can't be reset.
|
| + *
|
| + * Returns the previous string contained by the buffer.
|
| + */
|
| +xmlChar *
|
| +xmlBufferDetach(xmlBufferPtr buf) {
|
| + xmlChar *ret;
|
| +
|
| + if (buf == NULL)
|
| + return(NULL);
|
| + if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE)
|
| + return(NULL);
|
| +
|
| + ret = buf->content;
|
| + buf->content = NULL;
|
| + buf->size = 0;
|
| + buf->use = 0;
|
| +
|
| + return ret;
|
| +}
|
| +
|
| +
|
| +/**
|
| * xmlBufferCreateStatic:
|
| * @mem: the memory area
|
| * @size: the size in byte
|
| @@ -6953,6 +7120,7 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf,
|
| (buf->alloc == XML_BUFFER_ALLOC_IO)) return;
|
| if ((scheme == XML_BUFFER_ALLOC_DOUBLEIT) ||
|
| (scheme == XML_BUFFER_ALLOC_EXACT) ||
|
| + (scheme == XML_BUFFER_ALLOC_HYBRID) ||
|
| (scheme == XML_BUFFER_ALLOC_IMMUTABLE))
|
| buf->alloc = scheme;
|
| }
|
| @@ -7152,7 +7320,7 @@ xmlBufferDump(FILE *file, xmlBufferPtr buf) {
|
| */
|
|
|
| const xmlChar *
|
| -xmlBufferContent(const xmlBufferPtr buf)
|
| +xmlBufferContent(const xmlBuffer *buf)
|
| {
|
| if(!buf)
|
| return NULL;
|
| @@ -7170,7 +7338,7 @@ xmlBufferContent(const xmlBufferPtr buf)
|
| */
|
|
|
| int
|
| -xmlBufferLength(const xmlBufferPtr buf)
|
| +xmlBufferLength(const xmlBuffer *buf)
|
| {
|
| if(!buf)
|
| return 0;
|
| @@ -7220,6 +7388,21 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
| case XML_BUFFER_ALLOC_EXACT:
|
| newSize = size+10;
|
| break;
|
| + case XML_BUFFER_ALLOC_HYBRID:
|
| + if (buf->use < BASE_BUFFER_SIZE)
|
| + newSize = size;
|
| + else {
|
| + newSize = buf->size * 2;
|
| + while (size > newSize) {
|
| + if (newSize > UINT_MAX / 2) {
|
| + xmlTreeErrMemory("growing buffer");
|
| + return 0;
|
| + }
|
| + newSize *= 2;
|
| + }
|
| + }
|
| + break;
|
| +
|
| default:
|
| newSize = size+10;
|
| break;
|
| @@ -7539,7 +7722,7 @@ xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) {
|
| * Returns 0 (uncompressed) to 9 (max compression)
|
| */
|
| int
|
| -xmlGetDocCompressMode (xmlDocPtr doc) {
|
| +xmlGetDocCompressMode (const xmlDoc *doc) {
|
| if (doc == NULL) return(-1);
|
| return(doc->compression);
|
| }
|
| @@ -7730,8 +7913,7 @@ xmlDOMWrapNsMapAddItem(xmlNsMapPtr *nsmap, int position,
|
| map->first->prev = ret;
|
| ret->next = map->first;
|
| map->first = ret;
|
| - } else
|
| - return(NULL);
|
| + }
|
|
|
| ret->oldNs = oldNs;
|
| ret->newNs = newNs;
|
| @@ -7791,7 +7973,7 @@ xmlDOMWrapStoreNs(xmlDocPtr doc,
|
| *
|
| * Allocates and initializes a new DOM-wrapper context.
|
| *
|
| -* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal errror.
|
| +* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal error.
|
| */
|
| xmlDOMWrapCtxtPtr
|
| xmlDOMWrapNewCtxt(void)
|
| @@ -7876,6 +8058,8 @@ xmlDOMWrapNSNormGatherInScopeNs(xmlNsMapPtr *map,
|
|
|
| if ((map == NULL) || (*map != NULL))
|
| return (-1);
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| + return (-1);
|
| /*
|
| * Get in-scope ns-decls of @parent.
|
| */
|
| @@ -8143,6 +8327,8 @@ xmlSearchNsByNamespaceStrict(xmlDocPtr doc, xmlNodePtr node,
|
|
|
| if ((doc == NULL) || (nsName == NULL) || (retNs == NULL))
|
| return (-1);
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| + return(-1);
|
|
|
| *retNs = NULL;
|
| if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
|
| @@ -8241,8 +8427,8 @@ xmlSearchNsByPrefixStrict(xmlDocPtr doc, xmlNodePtr node,
|
| xmlNodePtr cur;
|
| xmlNsPtr ns;
|
|
|
| - if ((doc == NULL) || (node == NULL))
|
| - return (-1);
|
| + if ((doc == NULL) || (node == NULL) || (node->type == XML_NAMESPACE_DECL))
|
| + return(-1);
|
|
|
| if (retNs)
|
| *retNs = NULL;
|
| @@ -8310,6 +8496,9 @@ xmlDOMWrapNSNormDeclareNsForced(xmlDocPtr doc,
|
| char buf[50];
|
| const xmlChar *pref;
|
| int counter = 0;
|
| +
|
| + if ((doc == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
|
| + return(NULL);
|
| /*
|
| * Create a ns-decl on @anchor.
|
| */
|
| @@ -8826,6 +9015,9 @@ xmlDOMWrapAdoptBranch(xmlDOMWrapCtxtPtr ctxt,
|
| parnsdone = 0;
|
|
|
| cur = node;
|
| + if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
|
| + goto internal_error;
|
| +
|
| while (cur != NULL) {
|
| /*
|
| * Paranoid source-doc sanity check.
|
| @@ -9205,6 +9397,9 @@ xmlDOMWrapCloneNode(xmlDOMWrapCtxtPtr ctxt,
|
| *resNode = NULL;
|
|
|
| cur = node;
|
| + if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
|
| + return(-1);
|
| +
|
| while (cur != NULL) {
|
| if (cur->doc != sourceDoc) {
|
| /*
|
| @@ -9603,7 +9798,8 @@ leave_node:
|
| if (clone->parent != NULL)
|
| clone->parent->last = clone;
|
| clone = clone->parent;
|
| - parentClone = clone->parent;
|
| + if (clone != NULL)
|
| + parentClone = clone->parent;
|
| /*
|
| * Process parent --> next;
|
| */
|
| @@ -9722,6 +9918,8 @@ xmlDOMWrapAdoptAttr(xmlDOMWrapCtxtPtr ctxt,
|
| if (attr->children == NULL)
|
| return (0);
|
| cur = attr->children;
|
| + if ((cur != NULL) && (cur->type == XML_NAMESPACE_DECL))
|
| + goto internal_error;
|
| while (cur != NULL) {
|
| cur->doc = destDoc;
|
| switch (cur->type) {
|
| @@ -9783,7 +9981,7 @@ internal_error:
|
| * References of out-of scope ns-decls are remapped to point to @destDoc:
|
| * 1) If @destParent is given, then nsDef entries on element-nodes are used
|
| * 2) If *no* @destParent is given, then @destDoc->oldNs entries are used
|
| -* This is the case when you have an unliked node and just want to move it
|
| +* This is the case when you have an unlinked node and just want to move it
|
| * to the context of
|
| *
|
| * If @destParent is given, it ensures that the tree is namespace
|
| @@ -9806,7 +10004,8 @@ xmlDOMWrapAdoptNode(xmlDOMWrapCtxtPtr ctxt,
|
| xmlNodePtr destParent,
|
| int options)
|
| {
|
| - if ((node == NULL) || (destDoc == NULL) ||
|
| + if ((node == NULL) || (node->type == XML_NAMESPACE_DECL) ||
|
| + (destDoc == NULL) ||
|
| ((destParent != NULL) && (destParent->doc != destDoc)))
|
| return(-1);
|
| /*
|
|
|