!140 Upgrade to upstream v2.9.14 and Cleanup duplicate installation
From: @fly_fzc Reviewed-by: @xiezhipeng1 Signed-off-by: @xiezhipeng1
This commit is contained in:
commit
1929754748
@ -1,36 +0,0 @@
|
||||
From c3ae53279a37369d8b100b016126136dea05b44b Mon Sep 17 00:00:00 2001
|
||||
From: huangduirong <huangduirong@huawei.com>
|
||||
Date: Sat, 30 Oct 2021 15:21:01 +0800
|
||||
Subject: [PATCH] fix null-deref in xmlSchemaGetComponentTargetNs
|
||||
|
||||
---
|
||||
xmlschemas.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index 5387c8e..17aa6df 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -1329,6 +1329,9 @@ xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
|
||||
static const xmlChar *
|
||||
xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
|
||||
{
|
||||
+ if (item == NULL) {
|
||||
+ return (NULL);
|
||||
+ }
|
||||
switch (item->type) {
|
||||
case XML_SCHEMA_TYPE_ELEMENT:
|
||||
return (((xmlSchemaElementPtr) item)->name);
|
||||
@@ -1384,6 +1387,9 @@ xmlSchemaGetQNameRefTargetNs(void *ref)
|
||||
static const xmlChar *
|
||||
xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
|
||||
{
|
||||
+ if (item == NULL) {
|
||||
+ return (NULL);
|
||||
+ }
|
||||
switch (item->type) {
|
||||
case XML_SCHEMA_TYPE_ELEMENT:
|
||||
return (((xmlSchemaElementPtr) item)->targetNamespace);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 3e1aad4fe584747fd7d17cc7b2863a78e2d21a77 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 2 Jun 2021 17:31:49 +0200
|
||||
Subject: [PATCH] Fix XPath recursion limit
|
||||
|
||||
Fix accounting of recursion depth when parsing XPath expressions.
|
||||
|
||||
This silly bug introduced in commit 804c5297 could lead to spurious
|
||||
errors when parsing larger expressions or XSLT documents.
|
||||
|
||||
Should fix #264.
|
||||
---
|
||||
xpath.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xpath.c b/xpath.c
|
||||
index 7497ba0..1aa2f1a 100644
|
||||
--- a/xpath.c
|
||||
+++ b/xpath.c
|
||||
@@ -10983,7 +10983,7 @@ xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt, int sort) {
|
||||
}
|
||||
|
||||
if (xpctxt != NULL)
|
||||
- xpctxt->depth -= 1;
|
||||
+ xpctxt->depth -= 10;
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
From dea91c97debeac7c1aaf9c19f79029809e23a353 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 27 Jul 2021 16:12:54 +0200
|
||||
Subject: [PATCH] Fix buffering in xmlOutputBufferWrite
|
||||
|
||||
Fix a regression introduced with commit a697ed1e which caused
|
||||
xmlOutputBufferWrite to flush internal buffers too late.
|
||||
|
||||
Fixes #296.
|
||||
---
|
||||
xmlIO.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/xmlIO.c b/xmlIO.c
|
||||
index 57312b9..f20c0fa 100644
|
||||
--- a/xmlIO.c
|
||||
+++ b/xmlIO.c
|
||||
@@ -3401,12 +3401,18 @@ xmlOutputBufferWrite(xmlOutputBufferPtr out, int len, const char *buf) {
|
||||
out->error = XML_IO_ENCODER;
|
||||
return(-1);
|
||||
}
|
||||
- nbchars = ret >= 0 ? ret : 0;
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->conv);
|
||||
+ else
|
||||
+ nbchars = ret >= 0 ? ret : 0;
|
||||
} else {
|
||||
ret = xmlBufAdd(out->buffer, (const xmlChar *) buf, chunk);
|
||||
if (ret != 0)
|
||||
return(-1);
|
||||
- nbchars = chunk;
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->buffer);
|
||||
+ else
|
||||
+ nbchars = chunk;
|
||||
}
|
||||
buf += chunk;
|
||||
len -= chunk;
|
||||
@@ -3593,13 +3599,19 @@ xmlOutputBufferWriteEscape(xmlOutputBufferPtr out, const xmlChar *str,
|
||||
out->error = XML_IO_ENCODER;
|
||||
return(-1);
|
||||
}
|
||||
- nbchars = ret >= 0 ? ret : 0;
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->conv);
|
||||
+ else
|
||||
+ nbchars = ret >= 0 ? ret : 0;
|
||||
} else {
|
||||
ret = escaping(xmlBufEnd(out->buffer), &chunk, str, &cons);
|
||||
if ((ret < 0) || (chunk == 0)) /* chunk==0 => nothing done */
|
||||
return(-1);
|
||||
xmlBufAddLen(out->buffer, chunk);
|
||||
- nbchars = chunk;
|
||||
+ if (out->writecallback)
|
||||
+ nbchars = xmlBufUse(out->buffer);
|
||||
+ else
|
||||
+ nbchars = chunk;
|
||||
}
|
||||
str += cons;
|
||||
len -= cons;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From 13ad8736d294536da4cbcd70a96b0a2fbf47070c Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 25 May 2021 10:55:25 +0200
|
||||
Subject: [PATCH] Fix regression in xmlNodeDumpOutputInternal
|
||||
|
||||
Commit 85b1792e could cause additional whitespace if xmlNodeDump was
|
||||
called with a non-zero starting level.
|
||||
---
|
||||
xmlsave.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/xmlsave.c b/xmlsave.c
|
||||
index aedbd5e..489505f 100644
|
||||
--- a/xmlsave.c
|
||||
+++ b/xmlsave.c
|
||||
@@ -890,6 +890,13 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
break;
|
||||
|
||||
case XML_ELEMENT_NODE:
|
||||
+ if ((cur != root) && (ctxt->format == 1) &&
|
||||
+ (xmlIndentTreeOutput))
|
||||
+ xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
+ (ctxt->level > ctxt->indent_nr ?
|
||||
+ ctxt->indent_nr : ctxt->level),
|
||||
+ ctxt->indent);
|
||||
+
|
||||
/*
|
||||
* Some users like lxml are known to pass nodes with a corrupted
|
||||
* tree structure. Fall back to a recursive call to handle this
|
||||
@@ -900,13 +907,6 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((ctxt->level > 0) && (ctxt->format == 1) &&
|
||||
- (xmlIndentTreeOutput))
|
||||
- xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
- (ctxt->level > ctxt->indent_nr ?
|
||||
- ctxt->indent_nr : ctxt->level),
|
||||
- ctxt->indent);
|
||||
-
|
||||
xmlOutputBufferWrite(buf, 1, "<");
|
||||
if ((cur->ns != NULL) && (cur->ns->prefix != NULL)) {
|
||||
xmlOutputBufferWriteString(buf, (const char *)cur->ns->prefix);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From 92d9ab4c28842a09ca2b76d3ff2f933e01b6cd6f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Mon, 7 Jun 2021 15:09:53 +0200
|
||||
Subject: [PATCH] Fix whitespace when serializing empty HTML documents
|
||||
|
||||
The old, non-recursive HTML serialization code would always terminate
|
||||
the output with a newline. The new implementation omitted the newline
|
||||
if the document node had no children. Readd the newline when
|
||||
serializing empty documents.
|
||||
|
||||
Fixes #266.
|
||||
---
|
||||
HTMLtree.c | 14 +++++++++-----
|
||||
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/HTMLtree.c b/HTMLtree.c
|
||||
index bdd639c..7a2b855 100644
|
||||
--- a/HTMLtree.c
|
||||
+++ b/HTMLtree.c
|
||||
@@ -763,11 +763,15 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
if (((xmlDocPtr) cur)->intSubset != NULL) {
|
||||
htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
|
||||
}
|
||||
- /* Always validate cur->parent when descending. */
|
||||
- if ((cur->parent == parent) && (cur->children != NULL)) {
|
||||
- parent = cur;
|
||||
- cur = cur->children;
|
||||
- continue;
|
||||
+ if (cur->children != NULL) {
|
||||
+ /* Always validate cur->parent when descending. */
|
||||
+ if (cur->parent == parent) {
|
||||
+ parent = cur;
|
||||
+ cur = cur->children;
|
||||
+ continue;
|
||||
+ }
|
||||
+ } else {
|
||||
+ xmlOutputBufferWriteString(buf, "\n");
|
||||
}
|
||||
break;
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
From ec6e3efb06d7b15cf5a2328fabd3845acea4c815 Mon Sep 17 00:00:00 2001
|
||||
From: Arne Becker <arne_becker@genua.de>
|
||||
Date: Tue, 6 Jul 2021 21:56:04 +0200
|
||||
Subject: [PATCH] Patch to forbid epsilon-reduction of final states
|
||||
|
||||
When building the internal representation of a regexp, it is possible
|
||||
that a lot of empty transitions are created. Therefore there is a step
|
||||
to reduce them in the function xmlFAEliminateSimpleEpsilonTransitions.
|
||||
|
||||
There is an error there for this case:
|
||||
|
||||
* State 1 has a transition with an atom (in this case "a") to state 2.
|
||||
* State 2 is final and has an epsilon transition to state 1.
|
||||
|
||||
After reduction it looked like:
|
||||
* State 1 has a transition with an atom (in this case "a") to itself
|
||||
and is final.
|
||||
|
||||
In other words, the empty string is accepted when it shouldn't be.
|
||||
|
||||
The attached patch skips the reduction step for final states.
|
||||
An alternative would be to insert or increment counters when reducing a
|
||||
final state, but this seemed error prone and unnecessary, since there
|
||||
aren't that many final states.
|
||||
|
||||
Fixes #282
|
||||
---
|
||||
xmlregexp.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||
index 40dabb2..8d01c2b 100644
|
||||
--- a/xmlregexp.c
|
||||
+++ b/xmlregexp.c
|
||||
@@ -1892,6 +1892,12 @@ xmlFAReduceEpsilonTransitions(xmlRegParserCtxtPtr ctxt, int fromnr,
|
||||
* then X and Y are semantically equivalent and X can be eliminated
|
||||
* If X is the start state then make Y the start state, else replace the
|
||||
* target of all transitions to X by transitions to Y.
|
||||
+ *
|
||||
+ * If X is a final state, skip it.
|
||||
+ * Otherwise it would be necessary to manipulate counters for this case when
|
||||
+ * eliminating state 2:
|
||||
+ * State 1 has a transition with an atom to state 2.
|
||||
+ * State 2 is final and has an epsilon transition to state 1.
|
||||
*/
|
||||
static void
|
||||
xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
|
||||
@@ -1904,7 +1910,8 @@ xmlFAEliminateSimpleEpsilonTransitions(xmlRegParserCtxtPtr ctxt) {
|
||||
continue;
|
||||
if (state->nbTrans != 1)
|
||||
continue;
|
||||
- if (state->type == XML_REGEXP_UNREACH_STATE)
|
||||
+ if (state->type == XML_REGEXP_UNREACH_STATE ||
|
||||
+ state->type == XML_REGEXP_FINAL_STATE)
|
||||
continue;
|
||||
/* is the only transition out a basic transition */
|
||||
if ((state->trans[0].atom == NULL) &&
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,212 +0,0 @@
|
||||
From 85b1792e37b131e7a51af98a37f92472e8de5f3f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 18 May 2021 20:08:28 +0200
|
||||
Subject: [PATCH] Work around lxml API abuse
|
||||
|
||||
Make xmlNodeDumpOutput and htmlNodeDumpFormatOutput work with corrupted
|
||||
parent pointers. This used to work with the old recursive code but the
|
||||
non-recursive rewrite required parent pointers to be set correctly.
|
||||
|
||||
Unfortunately, lxml relies on the old behavior and passes subtrees with
|
||||
a corrupted structure. Fall back to a recursive function call if an
|
||||
invalid parent pointer is detected.
|
||||
|
||||
Fixes #255.
|
||||
---
|
||||
HTMLtree.c | 46 ++++++++++++++++++++++++++++------------------
|
||||
xmlsave.c | 31 +++++++++++++++++++++----------
|
||||
2 files changed, 49 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/HTMLtree.c b/HTMLtree.c
|
||||
index 24434d4..bdd639c 100644
|
||||
--- a/HTMLtree.c
|
||||
+++ b/HTMLtree.c
|
||||
@@ -744,7 +744,7 @@ void
|
||||
htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
xmlNodePtr cur, const char *encoding ATTRIBUTE_UNUSED,
|
||||
int format) {
|
||||
- xmlNodePtr root;
|
||||
+ xmlNodePtr root, parent;
|
||||
xmlAttrPtr attr;
|
||||
const htmlElemDesc * info;
|
||||
|
||||
@@ -755,6 +755,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
}
|
||||
|
||||
root = cur;
|
||||
+ parent = cur->parent;
|
||||
while (1) {
|
||||
switch (cur->type) {
|
||||
case XML_HTML_DOCUMENT_NODE:
|
||||
@@ -762,7 +763,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
if (((xmlDocPtr) cur)->intSubset != NULL) {
|
||||
htmlDtdDumpOutput(buf, (xmlDocPtr) cur, NULL);
|
||||
}
|
||||
- if (cur->children != NULL) {
|
||||
+ /* Always validate cur->parent when descending. */
|
||||
+ if ((cur->parent == parent) && (cur->children != NULL)) {
|
||||
+ parent = cur;
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
@@ -770,6 +773,16 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
|
||||
case XML_ELEMENT_NODE:
|
||||
/*
|
||||
+ * Some users like lxml are known to pass nodes with a corrupted
|
||||
+ * tree structure. Fall back to a recursive call to handle this
|
||||
+ * case.
|
||||
+ */
|
||||
+ if ((cur->parent != parent) && (cur->children != NULL)) {
|
||||
+ htmlNodeDumpFormatOutput(buf, doc, cur, encoding, format);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
* Get specific HTML info for that node.
|
||||
*/
|
||||
if (cur->ns == NULL)
|
||||
@@ -817,6 +830,7 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
(cur->name != NULL) &&
|
||||
(cur->name[0] != 'p')) /* p, pre, param */
|
||||
xmlOutputBufferWriteString(buf, "\n");
|
||||
+ parent = cur;
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
@@ -825,9 +839,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
(info != NULL) && (!info->isinline)) {
|
||||
if ((cur->next->type != HTML_TEXT_NODE) &&
|
||||
(cur->next->type != HTML_ENTITY_REF_NODE) &&
|
||||
- (cur->parent != NULL) &&
|
||||
- (cur->parent->name != NULL) &&
|
||||
- (cur->parent->name[0] != 'p')) /* p, pre, param */
|
||||
+ (parent != NULL) &&
|
||||
+ (parent->name != NULL) &&
|
||||
+ (parent->name[0] != 'p')) /* p, pre, param */
|
||||
xmlOutputBufferWriteString(buf, "\n");
|
||||
}
|
||||
|
||||
@@ -842,9 +856,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
break;
|
||||
if (((cur->name == (const xmlChar *)xmlStringText) ||
|
||||
(cur->name != (const xmlChar *)xmlStringTextNoenc)) &&
|
||||
- ((cur->parent == NULL) ||
|
||||
- ((xmlStrcasecmp(cur->parent->name, BAD_CAST "script")) &&
|
||||
- (xmlStrcasecmp(cur->parent->name, BAD_CAST "style"))))) {
|
||||
+ ((parent == NULL) ||
|
||||
+ ((xmlStrcasecmp(parent->name, BAD_CAST "script")) &&
|
||||
+ (xmlStrcasecmp(parent->name, BAD_CAST "style"))))) {
|
||||
xmlChar *buffer;
|
||||
|
||||
buffer = xmlEncodeEntitiesReentrant(doc, cur->content);
|
||||
@@ -902,13 +916,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
break;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * The parent should never be NULL here but we want to handle
|
||||
- * corrupted documents gracefully.
|
||||
- */
|
||||
- if (cur->parent == NULL)
|
||||
- return;
|
||||
- cur = cur->parent;
|
||||
+ cur = parent;
|
||||
+ /* cur->parent was validated when descending. */
|
||||
+ parent = cur->parent;
|
||||
|
||||
if ((cur->type == XML_HTML_DOCUMENT_NODE) ||
|
||||
(cur->type == XML_DOCUMENT_NODE)) {
|
||||
@@ -939,9 +949,9 @@ htmlNodeDumpFormatOutput(xmlOutputBufferPtr buf, xmlDocPtr doc,
|
||||
(cur->next != NULL)) {
|
||||
if ((cur->next->type != HTML_TEXT_NODE) &&
|
||||
(cur->next->type != HTML_ENTITY_REF_NODE) &&
|
||||
- (cur->parent != NULL) &&
|
||||
- (cur->parent->name != NULL) &&
|
||||
- (cur->parent->name[0] != 'p')) /* p, pre, param */
|
||||
+ (parent != NULL) &&
|
||||
+ (parent->name != NULL) &&
|
||||
+ (parent->name[0] != 'p')) /* p, pre, param */
|
||||
xmlOutputBufferWriteString(buf, "\n");
|
||||
}
|
||||
}
|
||||
diff --git a/xmlsave.c b/xmlsave.c
|
||||
index 61a4045..aedbd5e 100644
|
||||
--- a/xmlsave.c
|
||||
+++ b/xmlsave.c
|
||||
@@ -847,7 +847,7 @@ htmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
static void
|
||||
xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
int format = ctxt->format;
|
||||
- xmlNodePtr tmp, root, unformattedNode = NULL;
|
||||
+ xmlNodePtr tmp, root, unformattedNode = NULL, parent;
|
||||
xmlAttrPtr attr;
|
||||
xmlChar *start, *end;
|
||||
xmlOutputBufferPtr buf;
|
||||
@@ -856,6 +856,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
buf = ctxt->buf;
|
||||
|
||||
root = cur;
|
||||
+ parent = cur->parent;
|
||||
while (1) {
|
||||
switch (cur->type) {
|
||||
case XML_DOCUMENT_NODE:
|
||||
@@ -868,7 +869,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
break;
|
||||
|
||||
case XML_DOCUMENT_FRAG_NODE:
|
||||
- if (cur->children != NULL) {
|
||||
+ /* Always validate cur->parent when descending. */
|
||||
+ if ((cur->parent == parent) && (cur->children != NULL)) {
|
||||
+ parent = cur;
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
@@ -887,7 +890,18 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
break;
|
||||
|
||||
case XML_ELEMENT_NODE:
|
||||
- if ((cur != root) && (ctxt->format == 1) && (xmlIndentTreeOutput))
|
||||
+ /*
|
||||
+ * Some users like lxml are known to pass nodes with a corrupted
|
||||
+ * tree structure. Fall back to a recursive call to handle this
|
||||
+ * case.
|
||||
+ */
|
||||
+ if ((cur->parent != parent) && (cur->children != NULL)) {
|
||||
+ xmlNodeDumpOutputInternal(ctxt, cur);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ((ctxt->level > 0) && (ctxt->format == 1) &&
|
||||
+ (xmlIndentTreeOutput))
|
||||
xmlOutputBufferWrite(buf, ctxt->indent_size *
|
||||
(ctxt->level > ctxt->indent_nr ?
|
||||
ctxt->indent_nr : ctxt->level),
|
||||
@@ -942,6 +956,7 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
xmlOutputBufferWrite(buf, 1, ">");
|
||||
if (ctxt->format == 1) xmlOutputBufferWrite(buf, 1, "\n");
|
||||
if (ctxt->level >= 0) ctxt->level++;
|
||||
+ parent = cur;
|
||||
cur = cur->children;
|
||||
continue;
|
||||
}
|
||||
@@ -1058,13 +1073,9 @@ xmlNodeDumpOutputInternal(xmlSaveCtxtPtr ctxt, xmlNodePtr cur) {
|
||||
break;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * The parent should never be NULL here but we want to handle
|
||||
- * corrupted documents gracefully.
|
||||
- */
|
||||
- if (cur->parent == NULL)
|
||||
- return;
|
||||
- cur = cur->parent;
|
||||
+ cur = parent;
|
||||
+ /* cur->parent was validated when descending. */
|
||||
+ parent = cur->parent;
|
||||
|
||||
if (cur->type == XML_ELEMENT_NODE) {
|
||||
if (ctxt->level > 0) ctxt->level--;
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,210 +0,0 @@
|
||||
From 652dd12a858989b14eed4e84e453059cd3ba340e Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 8 Feb 2022 03:29:24 +0100
|
||||
Subject: [PATCH] [CVE-2022-23308] Use-after-free of ID and IDREF attributes
|
||||
|
||||
If a document is parsed with XML_PARSE_DTDVALID and without
|
||||
XML_PARSE_NOENT, the value of ID attributes has to be normalized after
|
||||
potentially expanding entities in xmlRemoveID. Otherwise, later calls
|
||||
to xmlGetID can return a pointer to previously freed memory.
|
||||
|
||||
ID attributes which are empty or contain only whitespace after
|
||||
entity expansion are affected in a similar way. This is fixed by
|
||||
not storing such attributes in the ID table.
|
||||
|
||||
The test to detect streaming mode when validating against a DTD was
|
||||
broken. In connection with the defects above, this could result in a
|
||||
use-after-free when using the xmlReader interface with validation.
|
||||
Fix detection of streaming mode to avoid similar issues. (This changes
|
||||
the expected result of a test case. But as far as I can tell, using the
|
||||
XML reader with XIncludes referencing the root document never worked
|
||||
properly, anyway.)
|
||||
|
||||
All of these issues can result in denial of service. Using xmlReader
|
||||
with validation could result in disclosure of memory via the error
|
||||
channel, typically stderr. The security impact of xmlGetID returning
|
||||
a pointer to freed memory depends on the application. The typical use
|
||||
case of calling xmlGetID on an unmodified document is not affected.
|
||||
---
|
||||
result/XInclude/ns1.xml.rdr | 2 +-
|
||||
valid.c | 88 ++++++++++++++++++++++++++++-----------------
|
||||
2 files changed, 56 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/result/XInclude/ns1.xml.rdr b/result/XInclude/ns1.xml.rdr
|
||||
index f23702f..9a3a5e7 100644
|
||||
--- a/result/XInclude/ns1.xml.rdr
|
||||
+++ b/result/XInclude/ns1.xml.rdr
|
||||
@@ -1,7 +1,7 @@
|
||||
0 1 doc 0 0
|
||||
1 14 #text 0 1
|
||||
|
||||
-1 1 ns:elem 1 0
|
||||
+1 1 xi:include 1 0
|
||||
1 14 #text 0 1
|
||||
|
||||
1 1 elem 0 0
|
||||
diff --git a/valid.c b/valid.c
|
||||
index 5ee391c..8e596f1 100644
|
||||
--- a/valid.c
|
||||
+++ b/valid.c
|
||||
@@ -479,6 +479,35 @@ nodeVPop(xmlValidCtxtPtr ctxt)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * xmlValidNormalizeString:
|
||||
+ * @str: a string
|
||||
+ *
|
||||
+ * Normalize a string in-place.
|
||||
+ */
|
||||
+static void
|
||||
+xmlValidNormalizeString(xmlChar *str) {
|
||||
+ xmlChar *dst;
|
||||
+ const xmlChar *src;
|
||||
+
|
||||
+ if (str == NULL)
|
||||
+ return;
|
||||
+ src = str;
|
||||
+ dst = str;
|
||||
+
|
||||
+ while (*src == 0x20) src++;
|
||||
+ while (*src != 0) {
|
||||
+ if (*src == 0x20) {
|
||||
+ while (*src == 0x20) src++;
|
||||
+ if (*src != 0)
|
||||
+ *dst++ = 0x20;
|
||||
+ } else {
|
||||
+ *dst++ = *src++;
|
||||
+ }
|
||||
+ }
|
||||
+ *dst = 0;
|
||||
+}
|
||||
+
|
||||
#ifdef DEBUG_VALID_ALGO
|
||||
static void
|
||||
xmlValidPrintNode(xmlNodePtr cur) {
|
||||
@@ -2607,6 +2636,24 @@ xmlDumpNotationTable(xmlBufferPtr buf, xmlNotationTablePtr table) {
|
||||
(xmlDictOwns(dict, (const xmlChar *)(str)) == 0))) \
|
||||
xmlFree((char *)(str));
|
||||
|
||||
+static int
|
||||
+xmlIsStreaming(xmlValidCtxtPtr ctxt) {
|
||||
+ xmlParserCtxtPtr pctxt;
|
||||
+
|
||||
+ if (ctxt == NULL)
|
||||
+ return(0);
|
||||
+ /*
|
||||
+ * These magic values are also abused to detect whether we're validating
|
||||
+ * while parsing a document. In this case, userData points to the parser
|
||||
+ * context.
|
||||
+ */
|
||||
+ if ((ctxt->finishDtd != XML_CTXT_FINISH_DTD_0) &&
|
||||
+ (ctxt->finishDtd != XML_CTXT_FINISH_DTD_1))
|
||||
+ return(0);
|
||||
+ pctxt = ctxt->userData;
|
||||
+ return(pctxt->parseMode == XML_PARSE_READER);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* xmlFreeID:
|
||||
* @not: A id
|
||||
@@ -2650,7 +2697,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
|
||||
if (doc == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
- if (value == NULL) {
|
||||
+ if ((value == NULL) || (value[0] == 0)) {
|
||||
return(NULL);
|
||||
}
|
||||
if (attr == NULL) {
|
||||
@@ -2681,7 +2728,7 @@ xmlAddID(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
|
||||
*/
|
||||
ret->value = xmlStrdup(value);
|
||||
ret->doc = doc;
|
||||
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
|
||||
+ if (xmlIsStreaming(ctxt)) {
|
||||
/*
|
||||
* Operating in streaming mode, attr is gonna disappear
|
||||
*/
|
||||
@@ -2820,6 +2867,7 @@ xmlRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
|
||||
ID = xmlNodeListGetString(doc, attr->children, 1);
|
||||
if (ID == NULL)
|
||||
return(-1);
|
||||
+ xmlValidNormalizeString(ID);
|
||||
|
||||
id = xmlHashLookup(table, ID);
|
||||
if (id == NULL || id->attr != attr) {
|
||||
@@ -3009,7 +3057,7 @@ xmlAddRef(xmlValidCtxtPtr ctxt, xmlDocPtr doc, const xmlChar *value,
|
||||
* fill the structure.
|
||||
*/
|
||||
ret->value = xmlStrdup(value);
|
||||
- if ((ctxt != NULL) && (ctxt->vstateNr != 0)) {
|
||||
+ if (xmlIsStreaming(ctxt)) {
|
||||
/*
|
||||
* Operating in streaming mode, attr is gonna disappear
|
||||
*/
|
||||
@@ -4028,8 +4076,7 @@ xmlValidateAttributeValue2(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
|
||||
xmlChar *
|
||||
xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
|
||||
xmlNodePtr elem, const xmlChar *name, const xmlChar *value) {
|
||||
- xmlChar *ret, *dst;
|
||||
- const xmlChar *src;
|
||||
+ xmlChar *ret;
|
||||
xmlAttributePtr attrDecl = NULL;
|
||||
int extsubset = 0;
|
||||
|
||||
@@ -4070,19 +4117,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
|
||||
ret = xmlStrdup(value);
|
||||
if (ret == NULL)
|
||||
return(NULL);
|
||||
- src = value;
|
||||
- dst = ret;
|
||||
- while (*src == 0x20) src++;
|
||||
- while (*src != 0) {
|
||||
- if (*src == 0x20) {
|
||||
- while (*src == 0x20) src++;
|
||||
- if (*src != 0)
|
||||
- *dst++ = 0x20;
|
||||
- } else {
|
||||
- *dst++ = *src++;
|
||||
- }
|
||||
- }
|
||||
- *dst = 0;
|
||||
+ xmlValidNormalizeString(ret);
|
||||
if ((doc->standalone) && (extsubset == 1) && (!xmlStrEqual(value, ret))) {
|
||||
xmlErrValidNode(ctxt, elem, XML_DTD_NOT_STANDALONE,
|
||||
"standalone: %s on %s value had to be normalized based on external subset declaration\n",
|
||||
@@ -4114,8 +4149,7 @@ xmlValidCtxtNormalizeAttributeValue(xmlValidCtxtPtr ctxt, xmlDocPtr doc,
|
||||
xmlChar *
|
||||
xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
|
||||
const xmlChar *name, const xmlChar *value) {
|
||||
- xmlChar *ret, *dst;
|
||||
- const xmlChar *src;
|
||||
+ xmlChar *ret;
|
||||
xmlAttributePtr attrDecl = NULL;
|
||||
|
||||
if (doc == NULL) return(NULL);
|
||||
@@ -4145,19 +4179,7 @@ xmlValidNormalizeAttributeValue(xmlDocPtr doc, xmlNodePtr elem,
|
||||
ret = xmlStrdup(value);
|
||||
if (ret == NULL)
|
||||
return(NULL);
|
||||
- src = value;
|
||||
- dst = ret;
|
||||
- while (*src == 0x20) src++;
|
||||
- while (*src != 0) {
|
||||
- if (*src == 0x20) {
|
||||
- while (*src == 0x20) src++;
|
||||
- if (*src != 0)
|
||||
- *dst++ = 0x20;
|
||||
- } else {
|
||||
- *dst++ = *src++;
|
||||
- }
|
||||
- }
|
||||
- *dst = 0;
|
||||
+ xmlValidNormalizeString(ret);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,341 +0,0 @@
|
||||
From 2554a2408e09f13652049e5ffb0d26196b02ebab Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 8 Mar 2022 20:10:02 +0100
|
||||
Subject: [PATCH] [CVE-2022-29824] Fix integer overflows in xmlBuf and
|
||||
xmlBuffer
|
||||
|
||||
In several places, the code handling string buffers didn't check for
|
||||
integer overflow or used wrong types for buffer sizes. This could
|
||||
result in out-of-bounds writes or other memory errors when working on
|
||||
large, multi-gigabyte buffers.
|
||||
|
||||
Thanks to Felix Wilhelm for the report.
|
||||
---
|
||||
buf.c | 86 +++++++++++++++++++++++-----------------------------------
|
||||
tree.c | 72 ++++++++++++++++++------------------------------
|
||||
2 files changed, 61 insertions(+), 97 deletions(-)
|
||||
|
||||
diff --git a/buf.c b/buf.c
|
||||
index 24368d37..40a5ee06 100644
|
||||
--- a/buf.c
|
||||
+++ b/buf.c
|
||||
@@ -30,6 +30,10 @@
|
||||
#include <libxml/parserInternals.h> /* for XML_MAX_TEXT_LENGTH */
|
||||
#include "buf.h"
|
||||
|
||||
+#ifndef SIZE_MAX
|
||||
+#define SIZE_MAX ((size_t) -1)
|
||||
+#endif
|
||||
+
|
||||
#define WITH_BUFFER_COMPAT
|
||||
|
||||
/**
|
||||
@@ -156,6 +160,8 @@ xmlBufPtr
|
||||
xmlBufCreateSize(size_t size) {
|
||||
xmlBufPtr ret;
|
||||
|
||||
+ if (size == SIZE_MAX)
|
||||
+ return(NULL);
|
||||
ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf));
|
||||
if (ret == NULL) {
|
||||
xmlBufMemoryError(NULL, "creating buffer");
|
||||
@@ -166,8 +172,8 @@ xmlBufCreateSize(size_t size) {
|
||||
ret->error = 0;
|
||||
ret->buffer = NULL;
|
||||
ret->alloc = xmlBufferAllocScheme;
|
||||
- ret->size = (size ? size+2 : 0); /* +1 for ending null */
|
||||
- ret->compat_size = (int) ret->size;
|
||||
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */
|
||||
+ ret->compat_size = (ret->size > INT_MAX ? INT_MAX : ret->size);
|
||||
if (ret->size){
|
||||
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
|
||||
if (ret->content == NULL) {
|
||||
@@ -442,23 +448,17 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) {
|
||||
CHECK_COMPAT(buf)
|
||||
|
||||
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
|
||||
- if (buf->use + len < buf->size)
|
||||
+ if (len < buf->size - buf->use)
|
||||
return(buf->size - buf->use);
|
||||
+ if (len > SIZE_MAX - buf->use)
|
||||
+ return(0);
|
||||
|
||||
- /*
|
||||
- * Windows has a BIG problem on realloc timing, so we try to double
|
||||
- * the buffer size (if that's enough) (bug 146697)
|
||||
- * Apparently BSD too, and it's probably best for linux too
|
||||
- * On an embedded system this may be something to change
|
||||
- */
|
||||
-#if 1
|
||||
- if (buf->size > (size_t) len)
|
||||
- size = buf->size * 2;
|
||||
- else
|
||||
- size = buf->use + len + 100;
|
||||
-#else
|
||||
- size = buf->use + len + 100;
|
||||
-#endif
|
||||
+ if (buf->size > (size_t) len) {
|
||||
+ size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2;
|
||||
+ } else {
|
||||
+ size = buf->use + len;
|
||||
+ size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100;
|
||||
+ }
|
||||
|
||||
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
||||
/*
|
||||
@@ -744,7 +744,7 @@ xmlBufIsEmpty(const xmlBufPtr buf)
|
||||
int
|
||||
xmlBufResize(xmlBufPtr buf, size_t size)
|
||||
{
|
||||
- unsigned int newSize;
|
||||
+ size_t newSize;
|
||||
xmlChar* rebuf = NULL;
|
||||
size_t start_buf;
|
||||
|
||||
@@ -772,9 +772,13 @@ xmlBufResize(xmlBufPtr buf, size_t size)
|
||||
case XML_BUFFER_ALLOC_IO:
|
||||
case XML_BUFFER_ALLOC_DOUBLEIT:
|
||||
/*take care of empty case*/
|
||||
- newSize = (buf->size ? buf->size*2 : size + 10);
|
||||
+ if (buf->size == 0) {
|
||||
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
|
||||
+ } else {
|
||||
+ newSize = buf->size;
|
||||
+ }
|
||||
while (size > newSize) {
|
||||
- if (newSize > UINT_MAX / 2) {
|
||||
+ if (newSize > SIZE_MAX / 2) {
|
||||
xmlBufMemoryError(buf, "growing buffer");
|
||||
return 0;
|
||||
}
|
||||
@@ -782,15 +786,15 @@ xmlBufResize(xmlBufPtr buf, size_t size)
|
||||
}
|
||||
break;
|
||||
case XML_BUFFER_ALLOC_EXACT:
|
||||
- newSize = size+10;
|
||||
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
|
||||
break;
|
||||
case XML_BUFFER_ALLOC_HYBRID:
|
||||
if (buf->use < BASE_BUFFER_SIZE)
|
||||
newSize = size;
|
||||
else {
|
||||
- newSize = buf->size * 2;
|
||||
+ newSize = buf->size;
|
||||
while (size > newSize) {
|
||||
- if (newSize > UINT_MAX / 2) {
|
||||
+ if (newSize > SIZE_MAX / 2) {
|
||||
xmlBufMemoryError(buf, "growing buffer");
|
||||
return 0;
|
||||
}
|
||||
@@ -800,7 +804,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
|
||||
break;
|
||||
|
||||
default:
|
||||
- newSize = size+10;
|
||||
+ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -866,7 +870,7 @@ xmlBufResize(xmlBufPtr buf, size_t size)
|
||||
*/
|
||||
int
|
||||
xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
|
||||
- unsigned int needSize;
|
||||
+ size_t needSize;
|
||||
|
||||
if ((str == NULL) || (buf == NULL) || (buf->error))
|
||||
return -1;
|
||||
@@ -888,8 +892,10 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) {
|
||||
if (len < 0) return -1;
|
||||
if (len == 0) return 0;
|
||||
|
||||
- needSize = buf->use + len + 2;
|
||||
- if (needSize > buf->size){
|
||||
+ if ((size_t) len >= buf->size - buf->use) {
|
||||
+ if ((size_t) len >= SIZE_MAX - buf->use)
|
||||
+ return(-1);
|
||||
+ needSize = buf->use + len + 1;
|
||||
if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) {
|
||||
/*
|
||||
* Used to provide parsing limits
|
||||
@@ -1025,31 +1031,7 @@ xmlBufCat(xmlBufPtr buf, const xmlChar *str) {
|
||||
*/
|
||||
int
|
||||
xmlBufCCat(xmlBufPtr buf, const char *str) {
|
||||
- const char *cur;
|
||||
-
|
||||
- if ((buf == NULL) || (buf->error))
|
||||
- return(-1);
|
||||
- CHECK_COMPAT(buf)
|
||||
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
||||
- if (str == NULL) {
|
||||
-#ifdef DEBUG_BUFFER
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "xmlBufCCat: str == NULL\n");
|
||||
-#endif
|
||||
- return -1;
|
||||
- }
|
||||
- for (cur = str;*cur != 0;cur++) {
|
||||
- if (buf->use + 10 >= buf->size) {
|
||||
- if (!xmlBufResize(buf, buf->use+10)){
|
||||
- xmlBufMemoryError(buf, "growing buffer");
|
||||
- return XML_ERR_NO_MEMORY;
|
||||
- }
|
||||
- }
|
||||
- buf->content[buf->use++] = *cur;
|
||||
- }
|
||||
- buf->content[buf->use] = 0;
|
||||
- UPDATE_COMPAT(buf)
|
||||
- return 0;
|
||||
+ return xmlBufCat(buf, (const xmlChar *) str);
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/tree.c b/tree.c
|
||||
index 9d94aa42..86afb7d6 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -7104,6 +7104,8 @@ xmlBufferPtr
|
||||
xmlBufferCreateSize(size_t size) {
|
||||
xmlBufferPtr ret;
|
||||
|
||||
+ if (size >= UINT_MAX)
|
||||
+ return(NULL);
|
||||
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
|
||||
if (ret == NULL) {
|
||||
xmlTreeErrMemory("creating buffer");
|
||||
@@ -7111,7 +7113,7 @@ xmlBufferCreateSize(size_t size) {
|
||||
}
|
||||
ret->use = 0;
|
||||
ret->alloc = xmlBufferAllocScheme;
|
||||
- ret->size = (size ? size+2 : 0); /* +1 for ending null */
|
||||
+ ret->size = (size ? size + 1 : 0); /* +1 for ending null */
|
||||
if (ret->size){
|
||||
ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar));
|
||||
if (ret->content == NULL) {
|
||||
@@ -7171,6 +7173,8 @@ xmlBufferCreateStatic(void *mem, size_t size) {
|
||||
|
||||
if ((mem == NULL) || (size == 0))
|
||||
return(NULL);
|
||||
+ if (size > UINT_MAX)
|
||||
+ return(NULL);
|
||||
|
||||
ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer));
|
||||
if (ret == NULL) {
|
||||
@@ -7318,28 +7322,23 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) {
|
||||
*/
|
||||
int
|
||||
xmlBufferGrow(xmlBufferPtr buf, unsigned int len) {
|
||||
- int size;
|
||||
+ unsigned int size;
|
||||
xmlChar *newbuf;
|
||||
|
||||
if (buf == NULL) return(-1);
|
||||
|
||||
if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0);
|
||||
- if (len + buf->use < buf->size) return(0);
|
||||
+ if (len < buf->size - buf->use)
|
||||
+ return(0);
|
||||
+ if (len > UINT_MAX - buf->use)
|
||||
+ return(-1);
|
||||
|
||||
- /*
|
||||
- * Windows has a BIG problem on realloc timing, so we try to double
|
||||
- * the buffer size (if that's enough) (bug 146697)
|
||||
- * Apparently BSD too, and it's probably best for linux too
|
||||
- * On an embedded system this may be something to change
|
||||
- */
|
||||
-#if 1
|
||||
- if (buf->size > len)
|
||||
- size = buf->size * 2;
|
||||
- else
|
||||
- size = buf->use + len + 100;
|
||||
-#else
|
||||
- size = buf->use + len + 100;
|
||||
-#endif
|
||||
+ if (buf->size > (size_t) len) {
|
||||
+ size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2;
|
||||
+ } else {
|
||||
+ size = buf->use + len;
|
||||
+ size = size > UINT_MAX - 100 ? UINT_MAX : size + 100;
|
||||
+ }
|
||||
|
||||
if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) {
|
||||
size_t start_buf = buf->content - buf->contentIO;
|
||||
@@ -7466,7 +7465,10 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
||||
case XML_BUFFER_ALLOC_IO:
|
||||
case XML_BUFFER_ALLOC_DOUBLEIT:
|
||||
/*take care of empty case*/
|
||||
- newSize = (buf->size ? buf->size : size + 10);
|
||||
+ if (buf->size == 0)
|
||||
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);
|
||||
+ else
|
||||
+ newSize = buf->size;
|
||||
while (size > newSize) {
|
||||
if (newSize > UINT_MAX / 2) {
|
||||
xmlTreeErrMemory("growing buffer");
|
||||
@@ -7476,7 +7478,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
||||
}
|
||||
break;
|
||||
case XML_BUFFER_ALLOC_EXACT:
|
||||
- newSize = size+10;
|
||||
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
|
||||
break;
|
||||
case XML_BUFFER_ALLOC_HYBRID:
|
||||
if (buf->use < BASE_BUFFER_SIZE)
|
||||
@@ -7494,7 +7496,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
||||
break;
|
||||
|
||||
default:
|
||||
- newSize = size+10;
|
||||
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7580,8 +7582,10 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) {
|
||||
if (len < 0) return -1;
|
||||
if (len == 0) return 0;
|
||||
|
||||
- needSize = buf->use + len + 2;
|
||||
- if (needSize > buf->size){
|
||||
+ if ((unsigned) len >= buf->size - buf->use) {
|
||||
+ if ((unsigned) len >= UINT_MAX - buf->use)
|
||||
+ return XML_ERR_NO_MEMORY;
|
||||
+ needSize = buf->use + len + 1;
|
||||
if (!xmlBufferResize(buf, needSize)){
|
||||
xmlTreeErrMemory("growing buffer");
|
||||
return XML_ERR_NO_MEMORY;
|
||||
@@ -7694,29 +7698,7 @@ xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) {
|
||||
*/
|
||||
int
|
||||
xmlBufferCCat(xmlBufferPtr buf, const char *str) {
|
||||
- const char *cur;
|
||||
-
|
||||
- if (buf == NULL)
|
||||
- return(-1);
|
||||
- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1;
|
||||
- if (str == NULL) {
|
||||
-#ifdef DEBUG_BUFFER
|
||||
- xmlGenericError(xmlGenericErrorContext,
|
||||
- "xmlBufferCCat: str == NULL\n");
|
||||
-#endif
|
||||
- return -1;
|
||||
- }
|
||||
- for (cur = str;*cur != 0;cur++) {
|
||||
- if (buf->use + 10 >= buf->size) {
|
||||
- if (!xmlBufferResize(buf, buf->use+10)){
|
||||
- xmlTreeErrMemory("growing buffer");
|
||||
- return XML_ERR_NO_MEMORY;
|
||||
- }
|
||||
- }
|
||||
- buf->content[buf->use++] = *cur;
|
||||
- }
|
||||
- buf->content[buf->use] = 0;
|
||||
- return 0;
|
||||
+ return xmlBufferCat(buf, (const xmlChar *) str);
|
||||
}
|
||||
|
||||
/**
|
||||
--
|
||||
GitLab
|
||||
|
||||
Binary file not shown.
BIN
libxml2-2.9.14.tar.xz
Normal file
BIN
libxml2-2.9.14.tar.xz
Normal file
Binary file not shown.
39
libxml2.spec
39
libxml2.spec
@ -1,25 +1,15 @@
|
||||
Summary: Library providing XML and HTML support
|
||||
Name: libxml2
|
||||
Version: 2.9.12
|
||||
Release: 8
|
||||
Version: 2.9.14
|
||||
Release: 1
|
||||
License: MIT
|
||||
Group: Development/Libraries
|
||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
||||
Source: https://download.gnome.org/sources/%{name}/2.9/%{name}-%{version}.tar.xz
|
||||
|
||||
Patch0: libxml2-multilib.patch
|
||||
Patch1: Fix-XPath-recursion-limit.patch
|
||||
Patch2: Fix-Null-deref-in-xmlSchemaGetComponentTargetNs.patch
|
||||
Patch3: Fix-memleaks-in-xmlXIncludeProcessFlags.patch
|
||||
Patch4: xmlAddChild-and-xmlAddNextSibling-may-not-attach-the.patch
|
||||
Patch5: Work-around-lxml-API-abuse.patch
|
||||
Patch6: Fix-regression-in-xmlNodeDumpOutputInternal.patch
|
||||
Patch7: Fix-whitespace-when-serializing-empty-HTML-documents.patch
|
||||
Patch8: Patch-to-forbid-epsilon-reduction-of-final-states.patch
|
||||
Patch9: Fix-buffering-in-xmlOutputBufferWrite.patch
|
||||
Patch10:backport-CVE-2022-23308-Use-after-free-of-ID-and-IDREF-attrib.patch
|
||||
Patch11:backport-CVE-2022-29824-Fix-integer-overflows-in-xmlBuf-and-xmlBuffer.patch
|
||||
Patch12:Fix-memory-leaks-for-xmlACatalogAdd.patch
|
||||
Patch13:Fix-memory-leaks-in-xmlACatalogAdd-when-xmlHashAddEntry-failed.patch
|
||||
Patch1: Fix-memleaks-in-xmlXIncludeProcessFlags.patch
|
||||
Patch2: Fix-memory-leaks-for-xmlACatalogAdd.patch
|
||||
Patch3: Fix-memory-leaks-in-xmlACatalogAdd-when-xmlHashAddEntry-failed.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: python3-devel
|
||||
@ -102,14 +92,9 @@ sed -i 's|#!/usr/bin/python |#!%{__python3} |' py3doc/*.py
|
||||
find doc -type f -exec chmod 0644 \{\} \;
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
make clean
|
||||
# for python3
|
||||
%configure --with-python=%{__python3}
|
||||
%make_install
|
||||
|
||||
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.a
|
||||
rm -f $RPM_BUILD_ROOT%{_libdir}/python*/site-packages/*.la
|
||||
@ -131,7 +116,7 @@ rm -fr %{buildroot}
|
||||
%files
|
||||
%defattr(-, root, root)
|
||||
|
||||
%doc AUTHORS NEWS README Copyright TODO
|
||||
%doc %{_datadir}/doc/libxml2
|
||||
|
||||
%{_libdir}/lib*.so.*
|
||||
%{_bindir}/xmllint
|
||||
@ -140,12 +125,12 @@ rm -fr %{buildroot}
|
||||
%files devel
|
||||
%defattr(-, root, root)
|
||||
|
||||
%doc AUTHORS NEWS README Copyright
|
||||
%doc NEWS README.md Copyright
|
||||
%doc doc/*.html doc/html doc/*.gif doc/*.png
|
||||
%doc doc/tutorial doc/libxml2-api.xml.gz
|
||||
%doc doc/examples
|
||||
%doc %dir %{_datadir}/gtk-doc/html/libxml2
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.devhelp
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.devhelp2
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.html
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.png
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.css
|
||||
@ -180,6 +165,12 @@ rm -fr %{buildroot}
|
||||
|
||||
|
||||
%changelog
|
||||
* Wed Jul 13 2022 fuanan <fuanan3@h-partners.com> - 2.9.14-1
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:Upgrade to upstream v2.9.14 and Cleanup duplicate installation
|
||||
|
||||
* Fri Jun 24 2022 fuanan <fuanan3@h-partners.com> - 2.9.12-8
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
From 8f5ccada05ddd4a1ff8e399ad39fc7cd4bd33325 Mon Sep 17 00:00:00 2001
|
||||
From: David Kilzer <ddkilzer@apple.com>
|
||||
Date: Wed, 7 Jul 2021 19:24:36 -0700
|
||||
Subject: [PATCH] xmlAddChild() and xmlAddNextSibling() may not attach their
|
||||
second argument
|
||||
|
||||
Use the return value of xmlAddChild() and xmlAddNextSibling()
|
||||
instead of the second argument directly.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
Fixes #316
|
||||
---
|
||||
xinclude.c | 14 ++++++--------
|
||||
xpointer.c | 13 ++++++-------
|
||||
2 files changed, 12 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/xinclude.c b/xinclude.c
|
||||
index b2e6ea1..2a0614d 100644
|
||||
--- a/xinclude.c
|
||||
+++ b/xinclude.c
|
||||
@@ -1014,15 +1014,15 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
|
||||
if (list == NULL) {
|
||||
list = tmp;
|
||||
listParent = cur->parent;
|
||||
+ last = tmp;
|
||||
} else {
|
||||
if (level == lastLevel)
|
||||
- xmlAddNextSibling(last, tmp);
|
||||
+ last = xmlAddNextSibling(last, tmp);
|
||||
else {
|
||||
- xmlAddChild(last, tmp);
|
||||
+ last = xmlAddChild(last, tmp);
|
||||
lastLevel = level;
|
||||
}
|
||||
}
|
||||
- last = tmp;
|
||||
|
||||
if (index2 > 1) {
|
||||
end = xmlXIncludeGetNthChild(cur, index2 - 1);
|
||||
@@ -1103,12 +1103,11 @@ xmlXIncludeCopyRange(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
|
||||
}
|
||||
if (tmp != NULL) {
|
||||
if (level == lastLevel)
|
||||
- xmlAddNextSibling(last, tmp);
|
||||
+ last = xmlAddNextSibling(last, tmp);
|
||||
else {
|
||||
- xmlAddChild(last, tmp);
|
||||
+ last = xmlAddChild(last, tmp);
|
||||
lastLevel = level;
|
||||
}
|
||||
- last = tmp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -1186,8 +1185,7 @@ xmlXIncludeCopyXPointer(xmlXIncludeCtxtPtr ctxt, xmlDocPtr target,
|
||||
if (last == NULL) {
|
||||
list = last = tmp;
|
||||
} else {
|
||||
- xmlAddNextSibling(last, tmp);
|
||||
- last = tmp;
|
||||
+ last = xmlAddNextSibling(last, tmp);
|
||||
}
|
||||
cur = cur->next;
|
||||
continue;
|
||||
diff --git a/xpointer.c b/xpointer.c
|
||||
index 27a6a8c..fe2fca5 100644
|
||||
--- a/xpointer.c
|
||||
+++ b/xpointer.c
|
||||
@@ -1483,16 +1483,16 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
|
||||
return(list);
|
||||
} else {
|
||||
tmp = xmlCopyNode(cur, 0);
|
||||
- if (list == NULL)
|
||||
+ if (list == NULL) {
|
||||
list = tmp;
|
||||
- else {
|
||||
+ parent = tmp;
|
||||
+ } else {
|
||||
if (last != NULL)
|
||||
- xmlAddNextSibling(last, tmp);
|
||||
+ parent = xmlAddNextSibling(last, tmp);
|
||||
else
|
||||
- xmlAddChild(parent, tmp);
|
||||
+ parent = xmlAddChild(parent, tmp);
|
||||
}
|
||||
last = NULL;
|
||||
- parent = tmp;
|
||||
|
||||
if (index2 > 1) {
|
||||
end = xmlXPtrGetNthChild(cur, index2 - 1);
|
||||
@@ -1574,8 +1574,7 @@ xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
|
||||
if (last != NULL)
|
||||
xmlAddNextSibling(last, tmp);
|
||||
else {
|
||||
- xmlAddChild(parent, tmp);
|
||||
- last = tmp;
|
||||
+ last = xmlAddChild(parent, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user