diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-05-04 12:38:45 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-05-15 11:16:38 +0000 |
commit | 627905635fc59e37faa8c47099d7af58f77dedf1 (patch) | |
tree | f6d2bde6f95b6b20652372461699a3c6a5adf7d6 /chromium/third_party/libxml/src/tree.c | |
parent | 62a251e1e2ff02547dbc471799264e7d5bf086d9 (diff) | |
download | qtwebengine-chromium-627905635fc59e37faa8c47099d7af58f77dedf1.tar.gz |
[Backport] CVE-2023-29469 / Security bug 1433328
Manual roll of libxml to include cherry-picked security fix.
Originally reviewed on:
https://chromium-review.googlesource.com/c/chromium/src/+/4457227
Change-Id: I5dd9fbd29aaea404609b8a6b533fa79ae8d0f127
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/476752
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/libxml/src/tree.c')
-rw-r--r-- | chromium/third_party/libxml/src/tree.c | 139 |
1 files changed, 61 insertions, 78 deletions
diff --git a/chromium/third_party/libxml/src/tree.c b/chromium/third_party/libxml/src/tree.c index 6a42f1187d3..e0545c1e635 100644 --- a/chromium/third_party/libxml/src/tree.c +++ b/chromium/third_party/libxml/src/tree.c @@ -1411,14 +1411,21 @@ xmlStringLenGetNodeList(const xmlDoc *doc, const xmlChar *value, int len) { if (val != NULL) xmlFree(val); goto out; } - else if ((ent != NULL) && (ent->children == NULL)) { + else if ((ent != NULL) && + ((ent->flags & XML_ENT_PARSED) == 0) && + ((ent->flags & XML_ENT_EXPANDING) == 0)) { xmlNodePtr temp; - /* Set to non-NULL value to avoid recursion. */ - ent->children = (xmlNodePtr) -1; + /* + * The entity should have been checked already, + * but set the flag anyway to avoid recursion. + */ + ent->flags |= XML_ENT_EXPANDING; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; + ent->flags &= ~XML_ENT_EXPANDING; + ent->flags |= XML_ENT_PARSED; temp = ent->children; while (temp) { temp->parent = (xmlNodePtr)ent; @@ -1490,9 +1497,9 @@ out: */ xmlNodePtr xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { - xmlNodePtr ret = NULL, last = NULL; + xmlNodePtr ret = NULL, head = NULL, last = NULL; xmlNodePtr node; - xmlChar *val; + xmlChar *val = NULL; const xmlChar *cur = value; const xmlChar *q; xmlEntityPtr ent; @@ -1590,14 +1597,12 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { */ if (!xmlBufIsEmpty(buf)) { node = xmlNewDocText(doc, NULL); - if (node == NULL) { - if (val != NULL) xmlFree(val); - goto out; - } + if (node == NULL) + goto out; node->content = xmlBufDetach(buf); if (last == NULL) { - last = ret = node; + last = head = node; } else { last = xmlAddNextSibling(last, node); } @@ -1607,18 +1612,23 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { * Create a new REFERENCE_REF node */ node = xmlNewReference(doc, val); - if (node == NULL) { - if (val != NULL) xmlFree(val); + if (node == NULL) goto out; - } - else if ((ent != NULL) && (ent->children == NULL)) { + if ((ent != NULL) && + ((ent->flags & XML_ENT_PARSED) == 0) && + ((ent->flags & XML_ENT_EXPANDING) == 0)) { xmlNodePtr temp; - /* Set to non-NULL value to avoid recursion. */ - ent->children = (xmlNodePtr) -1; + /* + * The entity should have been checked already, + * but set the flag anyway to avoid recursion. + */ + ent->flags |= XML_ENT_EXPANDING; ent->children = xmlStringGetNodeList(doc, (const xmlChar*)node->content); ent->owner = 1; + ent->flags &= ~XML_ENT_EXPANDING; + ent->flags |= XML_ENT_PARSED; temp = ent->children; while (temp) { temp->parent = (xmlNodePtr)ent; @@ -1627,12 +1637,13 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { } } if (last == NULL) { - last = ret = node; + last = head = node; } else { last = xmlAddNextSibling(last, node); } } xmlFree(val); + val = NULL; } cur++; q = cur; @@ -1651,7 +1662,7 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { } else cur++; } - if ((cur != q) || (ret == NULL)) { + if ((cur != q) || (head == NULL)) { /* * Handle the last piece of text. */ @@ -1660,21 +1671,24 @@ xmlStringGetNodeList(const xmlDoc *doc, const xmlChar *value) { if (!xmlBufIsEmpty(buf)) { node = xmlNewDocText(doc, NULL); - if (node == NULL) { - xmlBufFree(buf); - return(NULL); - } + if (node == NULL) + goto out; node->content = xmlBufDetach(buf); if (last == NULL) { - ret = node; + head = node; } else { xmlAddNextSibling(last, node); } } + ret = head; + head = NULL; + out: xmlBufFree(buf); + if (val != NULL) xmlFree(val); + if (head != NULL) xmlFreeNodeList(head); return(ret); } @@ -1860,7 +1874,7 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns, if ((node != NULL) && (node->type != XML_ELEMENT_NODE)) { if ((eatname == 1) && - ((node->doc == NULL) || + ((node->doc == NULL) || (node->doc->dict == NULL) || (!(xmlDictOwns(node->doc->dict, name))))) xmlFree((xmlChar *) name); return (NULL); @@ -1873,6 +1887,7 @@ xmlNewPropInternal(xmlNodePtr node, xmlNsPtr ns, if (cur == NULL) { if ((eatname == 1) && ((node == NULL) || (node->doc == NULL) || + (node->doc->dict == NULL) || (!(xmlDictOwns(node->doc->dict, name))))) xmlFree((xmlChar *) name); xmlTreeErrMemory("building attribute"); @@ -2383,8 +2398,9 @@ xmlNewDocNodeEatName(xmlDocPtr doc, xmlNsPtr ns, } } else { /* if name don't come from the doc dictionary free it here */ - if ((name != NULL) && (doc != NULL) && - (!(xmlDictOwns(doc->dict, name)))) + if ((name != NULL) && + ((doc == NULL) || (doc->dict == NULL) || + (!(xmlDictOwns(doc->dict, name))))) xmlFree(name); } return(cur); @@ -4085,9 +4101,6 @@ xmlCopyNamespaceList(xmlNsPtr cur) { return(ret); } -static xmlNodePtr -xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent); - static xmlAttrPtr xmlCopyPropInternal(xmlDocPtr doc, xmlNodePtr target, xmlAttrPtr cur) { xmlAttrPtr ret; @@ -4218,8 +4231,10 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) { return(NULL); while (cur != NULL) { q = xmlCopyProp(target, cur); - if (q == NULL) + if (q == NULL) { + xmlFreePropList(ret); return(NULL); + } if (p == NULL) { ret = p = q; } else { @@ -4251,7 +4266,7 @@ xmlCopyPropList(xmlNodePtr target, xmlAttrPtr cur) { * namespace info, but don't recurse on children. */ -static xmlNodePtr +xmlNodePtr xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent, int extended) { xmlNodePtr ret; @@ -4450,7 +4465,7 @@ out: return(ret); } -static xmlNodePtr +xmlNodePtr xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) { xmlNodePtr ret = NULL; xmlNodePtr p = NULL,q; @@ -4464,7 +4479,7 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) { } if (doc->intSubset == NULL) { q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node ); - if (q == NULL) return(NULL); + if (q == NULL) goto error; q->doc = doc; q->parent = parent; doc->intSubset = (xmlDtdPtr) q; @@ -4476,7 +4491,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 (q == NULL) goto error; if (ret == NULL) { q->prev = NULL; ret = p = q; @@ -4489,6 +4504,9 @@ xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) { node = node->next; } return(ret); +error: + xmlFreeNodeList(ret); + return(NULL); } /** @@ -7205,8 +7223,6 @@ xmlBufferDetach(xmlBufferPtr buf) { if (buf == NULL) return(NULL); - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) - return(NULL); ret = buf->content; buf->content = NULL; @@ -7222,31 +7238,14 @@ xmlBufferDetach(xmlBufferPtr buf) { * @mem: the memory area * @size: the size in byte * - * routine to create an XML buffer from an immutable memory area. - * The area won't be modified nor copied, and is expected to be - * present until the end of the buffer lifetime. - * - * returns the new structure. + * Create an XML buffer initialized with bytes. */ xmlBufferPtr xmlBufferCreateStatic(void *mem, size_t size) { - xmlBufferPtr ret; - - if ((mem == NULL) || (size == 0)) - return(NULL); - if (size > UINT_MAX) - return(NULL); + xmlBufferPtr buf = xmlBufferCreateSize(size); - ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); - if (ret == NULL) { - xmlTreeErrMemory("creating buffer"); - return(NULL); - } - ret->use = size; - ret->size = size; - ret->alloc = XML_BUFFER_ALLOC_IMMUTABLE; - ret->content = (xmlChar *) mem; - return(ret); + xmlBufferAdd(buf, mem, size); + return(buf); } /** @@ -7266,12 +7265,10 @@ xmlBufferSetAllocationScheme(xmlBufferPtr buf, #endif return; } - if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) || - (buf->alloc == XML_BUFFER_ALLOC_IO)) return; + if (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)) + (scheme == XML_BUFFER_ALLOC_HYBRID)) buf->alloc = scheme; } @@ -7295,8 +7292,7 @@ xmlBufferFree(xmlBufferPtr buf) { if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { xmlFree(buf->contentIO); - } else if ((buf->content != NULL) && - (buf->alloc != XML_BUFFER_ALLOC_IMMUTABLE)) { + } else if (buf->content != NULL) { xmlFree(buf->content); } xmlFree(buf); @@ -7313,10 +7309,7 @@ xmlBufferEmpty(xmlBufferPtr buf) { if (buf == NULL) return; if (buf->content == NULL) return; buf->use = 0; - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) { - buf->content = BAD_CAST ""; - } else if ((buf->alloc == XML_BUFFER_ALLOC_IO) && - (buf->contentIO != NULL)) { + if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { size_t start_buf = buf->content - buf->contentIO; buf->size += start_buf; @@ -7343,8 +7336,7 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) { if (len > buf->use) return(-1); buf->use -= len; - if ((buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) || - ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL))) { + if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { /* * we just move the content pointer, but also make sure * the perceived buffer size has shrunk accordingly @@ -7388,7 +7380,6 @@ xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { if (buf == NULL) return(-1); - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); if (len < buf->size - buf->use) return(0); if (len >= UINT_MAX - buf->use) { @@ -7512,8 +7503,6 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) if (buf == NULL) return(0); - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); - /* Don't resize if we don't have to */ if (size < buf->size) return 1; @@ -7631,7 +7620,6 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) { if ((str == NULL) || (buf == NULL)) { return -1; } - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; if (len < -1) { #ifdef DEBUG_BUFFER xmlGenericError(xmlGenericErrorContext, @@ -7684,7 +7672,6 @@ xmlBufferAddHead(xmlBufferPtr buf, const xmlChar *str, int len) { if (buf == NULL) return(-1); - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; if (str == NULL) { #ifdef DEBUG_BUFFER xmlGenericError(xmlGenericErrorContext, @@ -7755,7 +7742,6 @@ int xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) { if (buf == NULL) return(-1); - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; if (str == NULL) return -1; return xmlBufferAdd(buf, str, -1); } @@ -7787,7 +7773,6 @@ void xmlBufferWriteCHAR(xmlBufferPtr buf, const xmlChar *string) { if (buf == NULL) return; - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return; xmlBufferCat(buf, string); } @@ -7803,7 +7788,6 @@ void xmlBufferWriteChar(xmlBufferPtr buf, const char *string) { if (buf == NULL) return; - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return; xmlBufferCCat(buf, string); } @@ -7822,7 +7806,6 @@ xmlBufferWriteQuotedString(xmlBufferPtr buf, const xmlChar *string) { const xmlChar *cur, *base; if (buf == NULL) return; - if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return; if (xmlStrchr(string, '\"')) { if (xmlStrchr(string, '\'')) { #ifdef DEBUG_BUFFER |