aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libxml/tree.c
diff options
context:
space:
mode:
authorsetser <setser@yandex-team.ru>2022-05-09 00:13:37 +0300
committersetser <setser@yandex-team.ru>2022-05-09 00:13:37 +0300
commite87e3fc8d0e04eb7ba3eee221bb91613b527ad85 (patch)
tree5279c128bdbdf902b9a08d9fae8e55b91910a553 /contrib/libs/libxml/tree.c
parentf4f3e4024a1f32bd0bc3fa20239025a1b179e42d (diff)
downloadydb-e87e3fc8d0e04eb7ba3eee221bb91613b527ad85.tar.gz
Update libxml to 2.9.13
ref:f572491d236694e847142c36f0f5546c649e05d7
Diffstat (limited to 'contrib/libs/libxml/tree.c')
-rw-r--r--contrib/libs/libxml/tree.c110
1 files changed, 77 insertions, 33 deletions
diff --git a/contrib/libs/libxml/tree.c b/contrib/libs/libxml/tree.c
index 08b1a5004d..9d94aa42ae 100644
--- a/contrib/libs/libxml/tree.c
+++ b/contrib/libs/libxml/tree.c
@@ -70,7 +70,7 @@ static xmlChar* xmlGetPropNodeValueInternal(const xmlAttr *prop);
************************************************************************/
/**
* xmlTreeErrMemory:
- * @extra: extra informations
+ * @extra: extra information
*
* Handle an out of memory condition
*/
@@ -83,7 +83,7 @@ xmlTreeErrMemory(const char *extra)
/**
* xmlTreeErr:
* @code: the error number
- * @extra: extra informations
+ * @extra: extra information
*
* Handle an out of memory condition
*/
@@ -1064,7 +1064,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
* @str: a string
*
* Copy a string using a "dict" dictionary in the current scope,
- * if availabe.
+ * if available.
*/
#define DICT_COPY(str, cpy) \
if (str) { \
@@ -1081,7 +1081,7 @@ xmlCreateIntSubset(xmlDocPtr doc, const xmlChar *name,
* @str: a string
*
* Copy a string using a "dict" dictionary in the current scope,
- * if availabe.
+ * if available.
*/
#define DICT_CONST_COPY(str, cpy) \
if (str) { \
@@ -1276,12 +1276,14 @@ 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 *cur, *end;
const xmlChar *q;
xmlEntityPtr ent;
xmlBufPtr buf;
if (value == NULL) return(NULL);
+ cur = value;
+ end = cur + len;
buf = xmlBufCreateSize(0);
if (buf == NULL) return(NULL);
@@ -1308,6 +1310,16 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
else
tmp = 0;
while (tmp != ';') { /* Non input consuming loop */
+ /*
+ * If you find an integer overflow here when fuzzing,
+ * the bug is probably elsewhere. This function should
+ * only receive entities that were already validated by
+ * the parser, typically by xmlParseAttValueComplex
+ * calling xmlStringDecodeEntities.
+ *
+ * So it's better *not* to check for overflow to
+ * potentially discover new bugs.
+ */
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 16 + (tmp - '0');
else if ((tmp >= 'a') && (tmp <= 'f'))
@@ -1336,6 +1348,7 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) {
else
tmp = 0;
while (tmp != ';') { /* Non input consuming loops */
+ /* Don't check for integer overflow, see above. */
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 10 + (tmp - '0');
else {
@@ -1515,6 +1528,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
cur += 3;
tmp = *cur;
while (tmp != ';') { /* Non input consuming loop */
+ /* Don't check for integer overflow, see above. */
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 16 + (tmp - '0');
else if ((tmp >= 'a') && (tmp <= 'f'))
@@ -1537,6 +1551,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
cur += 2;
tmp = *cur;
while (tmp != ';') { /* Non input consuming loops */
+ /* Don't check for integer overflow, see above. */
if ((tmp >= '0') && (tmp <= '9'))
charval = charval * 10 + (tmp - '0');
else {
@@ -1581,6 +1596,10 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
*/
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
+ if (node == NULL) {
+ if (val != NULL) xmlFree(val);
+ goto out;
+ }
node->content = xmlBufDetach(buf);
if (last == NULL) {
@@ -1647,6 +1666,10 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) {
if (!xmlBufIsEmpty(buf)) {
node = xmlNewDocText(doc, NULL);
+ if (node == NULL) {
+ xmlBufFree(buf);
+ return(NULL);
+ }
node->content = xmlBufDetach(buf);
if (last == NULL) {
@@ -1882,12 +1905,6 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns,
if (value != NULL) {
xmlNodePtr tmp;
- if(!xmlCheckUTF8(value)) {
- xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) doc,
- NULL);
- if (doc != NULL)
- doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
- }
cur->children = xmlNewDocText(doc, value);
cur->last = NULL;
tmp = cur->children;
@@ -2007,6 +2024,11 @@ xmlNewNsPropEatName(xmlNodePtr node, xmlNsPtr ns, xmlChar *name,
* @value: the value of the attribute
*
* Create a new property carried by a document.
+ * NOTE: @value is supposed to be a piece of XML CDATA, so it allows entity
+ * references, but XML special chars need to be escaped first by using
+ * xmlEncodeEntitiesReentrant(). Use xmlNewProp() if you don't need
+ * entities support.
+ *
* Returns a pointer to the attribute
*/
xmlAttrPtr
@@ -2834,8 +2856,15 @@ xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
prop = prop->next;
}
}
- if (tree->children != NULL)
+ if (tree->type == XML_ENTITY_REF_NODE) {
+ /*
+ * Clear 'children' which points to the entity declaration
+ * from the original document.
+ */
+ tree->children = NULL;
+ } else if (tree->children != NULL) {
xmlSetListDoc(tree->children, doc);
+ }
tree->doc = doc;
}
}
@@ -3673,17 +3702,14 @@ xmlFreeNodeList(xmlNodePtr cur) {
xmlFreeNsList((xmlNsPtr) cur);
return;
}
- if ((cur->type == XML_DOCUMENT_NODE) ||
-#ifdef LIBXML_DOCB_ENABLED
- (cur->type == XML_DOCB_DOCUMENT_NODE) ||
-#endif
- (cur->type == XML_HTML_DOCUMENT_NODE)) {
- xmlFreeDoc((xmlDocPtr) cur);
- return;
- }
if (cur->doc != NULL) dict = cur->doc->dict;
while (1) {
while ((cur->children != NULL) &&
+ (cur->type != XML_DOCUMENT_NODE) &&
+#ifdef LIBXML_DOCB_ENABLED
+ (cur->type != XML_DOCB_DOCUMENT_NODE) &&
+#endif
+ (cur->type != XML_HTML_DOCUMENT_NODE) &&
(cur->type != XML_DTD_NODE) &&
(cur->type != XML_ENTITY_REF_NODE)) {
cur = cur->children;
@@ -3692,7 +3718,13 @@ xmlFreeNodeList(xmlNodePtr cur) {
next = cur->next;
parent = cur->parent;
- if (cur->type != XML_DTD_NODE) {
+ if ((cur->type == XML_DOCUMENT_NODE) ||
+#ifdef LIBXML_DOCB_ENABLED
+ (cur->type == XML_DOCB_DOCUMENT_NODE) ||
+#endif
+ (cur->type == XML_HTML_DOCUMENT_NODE)) {
+ xmlFreeDoc((xmlDocPtr) cur);
+ } else if (cur->type != XML_DTD_NODE) {
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
xmlDeregisterNodeDefaultValue(cur);
@@ -4066,7 +4098,7 @@ xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) {
} else {
/*
* we have to find something appropriate here since
- * we cant be sure, that the namespace we found is identified
+ * we can't be sure, that the namespace we found is identified
* by the prefix
*/
if (xmlStrEqual(ns->href, cur->ns->href)) {
@@ -4547,6 +4579,7 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
if (doc == NULL) return(NULL);
ret = xmlNewDoc(doc->version);
if (ret == NULL) return(NULL);
+ ret->type = doc->type;
if (doc->name != NULL)
ret->name = xmlMemStrdup(doc->name);
if (doc->encoding != NULL)
@@ -4869,7 +4902,9 @@ xmlGetNodePath(const xmlNode *node)
}
next = ((xmlAttrPtr) cur)->parent;
} else {
- next = cur->parent;
+ xmlFree(buf);
+ xmlFree(buffer);
+ return (NULL);
}
/*
@@ -6564,6 +6599,16 @@ xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
attrDecl = xmlGetDtdQAttrDesc(doc->extSubset,
elemQName, name, NULL);
}
+ } else if (xmlStrEqual(nsName, XML_XML_NAMESPACE)) {
+ /*
+ * The XML namespace must be bound to prefix 'xml'.
+ */
+ attrDecl = xmlGetDtdQAttrDesc(doc->intSubset,
+ elemQName, name, BAD_CAST "xml");
+ if ((attrDecl == NULL) && (doc->extSubset != NULL)) {
+ attrDecl = xmlGetDtdQAttrDesc(doc->extSubset,
+ elemQName, name, BAD_CAST "xml");
+ }
} else {
xmlNsPtr *nsList, *cur;
@@ -6910,12 +6955,6 @@ xmlSetNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
if (value != NULL) {
xmlNodePtr tmp;
- if(!xmlCheckUTF8(value)) {
- xmlTreeErr(XML_TREE_NOT_UTF8, (xmlNodePtr) node->doc,
- NULL);
- if (node->doc != NULL)
- node->doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1");
- }
prop->children = xmlNewDocText(node->doc, value);
prop->last = NULL;
tmp = prop->children;
@@ -7243,7 +7282,7 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) {
/*
* we just move the content pointer, but also make sure
- * the perceived buffer size has shrinked accordingly
+ * the perceived buffer size has shrunk accordingly
*/
buf->content += len;
buf->size -= len;
@@ -7417,12 +7456,17 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
if (size < buf->size)
return 1;
+ if (size > UINT_MAX - 10) {
+ xmlTreeErrMemory("growing buffer");
+ return 0;
+ }
+
/* figure out new size */
switch (buf->alloc){
case XML_BUFFER_ALLOC_IO:
case XML_BUFFER_ALLOC_DOUBLEIT:
/*take care of empty case*/
- newSize = (buf->size ? buf->size*2 : size + 10);
+ newSize = (buf->size ? buf->size : size + 10);
while (size > newSize) {
if (newSize > UINT_MAX / 2) {
xmlTreeErrMemory("growing buffer");
@@ -7438,7 +7482,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
if (buf->use < BASE_BUFFER_SIZE)
newSize = size;
else {
- newSize = buf->size * 2;
+ newSize = buf->size;
while (size > newSize) {
if (newSize > UINT_MAX / 2) {
xmlTreeErrMemory("growing buffer");
@@ -7595,7 +7639,7 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) {
if (start_buf > (unsigned int) len) {
/*
- * We can add it in the space previously shrinked
+ * We can add it in the space previously shrunk
*/
buf->content -= len;
memmove(&buf->content[0], str, len);