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); |
/* |