update version to 2.11.4
This commit is contained in:
parent
bf69a87436
commit
9789a518b5
@ -1,41 +0,0 @@
|
||||
From b01853fb42257136461d1b45e45ecaa3f3ecd570 Mon Sep 17 00:00:00 2001
|
||||
From: panxiaohe <panxiaohe@huawei.com>
|
||||
Date: Tue, 9 Nov 2021 14:27:24 +0800
|
||||
Subject: [PATCH] Fix memleaks in xmlXIncludeProcessFlags
|
||||
|
||||
---
|
||||
tree.c | 18 +++++++++++++-----
|
||||
1 file changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tree.c b/tree.c
|
||||
index 17e59d7..64799fb 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -3720,11 +3720,19 @@ xmlFreeNodeList(xmlNodePtr cur) {
|
||||
* Otherwise the node name might come from the document's
|
||||
* dictionary
|
||||
*/
|
||||
- if ((cur->name != NULL) &&
|
||||
- (cur->type != XML_TEXT_NODE) &&
|
||||
- (cur->type != XML_COMMENT_NODE))
|
||||
- DICT_FREE(cur->name)
|
||||
- xmlFree(cur);
|
||||
+ 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->name != NULL) &&
|
||||
+ (cur->type != XML_TEXT_NODE) &&
|
||||
+ (cur->type != XML_COMMENT_NODE))
|
||||
+ DICT_FREE(cur->name)
|
||||
+ xmlFree(cur);
|
||||
+ }
|
||||
}
|
||||
|
||||
if (next != NULL) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,28 +0,0 @@
|
||||
From 9736e895d02e889b25c7e8a73afe3f7bf61dca27 Mon Sep 17 00:00:00 2001
|
||||
From: xiezhipeng <xiezhipeng1@huawei.com>
|
||||
Date: Thu, 16 Jun 2022 19:13:10 +0800
|
||||
Subject: [PATCH] Fix memory leaks for xmlACatalogAdd
|
||||
|
||||
---
|
||||
xmlcatalog.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/xmlcatalog.c b/xmlcatalog.c
|
||||
index 3f0e1b9..6fdbff9 100644
|
||||
--- a/xmlcatalog.c
|
||||
+++ b/xmlcatalog.c
|
||||
@@ -527,6 +527,11 @@ int main(int argc, char **argv) {
|
||||
xmlACatalogDump(catal, stdout);
|
||||
}
|
||||
i += 2;
|
||||
+ /* Check for memory leaks */
|
||||
+ if (catal != NULL)
|
||||
+ xmlFreeCatalog(catal);
|
||||
+ if (super != NULL)
|
||||
+ xmlFreeCatalog(super);
|
||||
} else {
|
||||
if ((!strcmp(argv[i], "-add")) ||
|
||||
(!strcmp(argv[i], "--add"))) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
From 43555b3ff9c28a44aa27f447475b9f9cfccbe702 Mon Sep 17 00:00:00 2001
|
||||
From: xiezhipeng <xiezhipeng1@huawei.com>
|
||||
Date: Fri, 24 Jun 2022 09:39:54 +0800
|
||||
Subject: [PATCH] fix memory leaks in xmlACatalogAdd
|
||||
|
||||
---
|
||||
catalog.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/catalog.c b/catalog.c
|
||||
index effbb2e..866e753 100644
|
||||
--- a/catalog.c
|
||||
+++ b/catalog.c
|
||||
@@ -2981,6 +2981,8 @@ xmlACatalogAdd(xmlCatalogPtr catal, const xmlChar * type,
|
||||
if (catal->sgml == NULL)
|
||||
catal->sgml = xmlHashCreate(10);
|
||||
res = xmlHashAddEntry(catal->sgml, orig, entry);
|
||||
+ if (res)
|
||||
+ xmlFreeCatalogEntry(entry, NULL);
|
||||
}
|
||||
}
|
||||
return (res);
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,65 +0,0 @@
|
||||
From a2fe74c08a9bd03cf5515b9e44d2005538b9f619 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 20 Feb 2022 18:19:27 +0100
|
||||
Subject: [PATCH 3/3] Add XML_DEPRECATED macro
|
||||
|
||||
__attribute__((deprecated)) is available since at least GCC 3.1, so an
|
||||
exact version check is probably unnecessary.
|
||||
---
|
||||
include/libxml/xmlversion.h.in | 18 ++++++++++++++++++
|
||||
testapi.c | 3 +++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
diff --git a/include/libxml/xmlversion.h.in b/include/libxml/xmlversion.h.in
|
||||
index f9f79a2f..b1d2a208 100644
|
||||
--- a/include/libxml/xmlversion.h.in
|
||||
+++ b/include/libxml/xmlversion.h.in
|
||||
@@ -456,6 +456,15 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
|
||||
# define LIBXML_ATTR_FORMAT(fmt,args)
|
||||
#endif
|
||||
|
||||
+#ifndef XML_DEPRECATED
|
||||
+# ifdef IN_LIBXML
|
||||
+# define XML_DEPRECATED
|
||||
+# else
|
||||
+/* Available since at least GCC 3.1 */
|
||||
+# define XML_DEPRECATED __attribute__((deprecated))
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
#else /* ! __GNUC__ */
|
||||
/**
|
||||
* ATTRIBUTE_UNUSED:
|
||||
@@ -475,6 +484,15 @@ XMLPUBFUN void XMLCALL xmlCheckVersion(int version);
|
||||
* Macro used to indicate to GCC the parameter are printf like
|
||||
*/
|
||||
#define LIBXML_ATTR_FORMAT(fmt,args)
|
||||
+/**
|
||||
+ * XML_DEPRECATED:
|
||||
+ *
|
||||
+ * Macro used to indicate that a function, variable, type or struct member
|
||||
+ * is deprecated.
|
||||
+ */
|
||||
+#ifndef XML_DEPRECATED
|
||||
+#define XML_DEPRECATED
|
||||
+#endif
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff --git a/testapi.c b/testapi.c
|
||||
index 4b091f0c..3a4dc2fe 100644
|
||||
--- a/testapi.c
|
||||
+++ b/testapi.c
|
||||
@@ -8,6 +8,9 @@
|
||||
* daniel@veillard.com
|
||||
*/
|
||||
|
||||
+/* Disable deprecation warnings */
|
||||
+#define XML_DEPRECATED
|
||||
+
|
||||
#include "libxml.h"
|
||||
#include <stdio.h>
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,618 +0,0 @@
|
||||
From c846986356fc149915a74972bf198abc266bc2c0 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 25 Aug 2022 17:43:08 +0200
|
||||
Subject: [PATCH] [CVE-2022-40303] Fix integer overflows with XML_PARSE_HUGE
|
||||
|
||||
Also impose size limits when XML_PARSE_HUGE is set. Limit size of names
|
||||
to XML_MAX_TEXT_LENGTH (10 million bytes) and other content to
|
||||
XML_MAX_HUGE_LENGTH (1 billion bytes).
|
||||
|
||||
Move some the length checks to the end of the respective loop to make
|
||||
them strict.
|
||||
|
||||
xmlParseEntityValue didn't have a length limitation at all. But without
|
||||
XML_PARSE_HUGE, this should eventually trigger an error in xmlGROW.
|
||||
|
||||
Thanks to Maddie Stone working with Google Project Zero for the report!
|
||||
---
|
||||
parser.c | 233 +++++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 121 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 93f031be..79479979 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -102,6 +102,8 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
|
||||
* *
|
||||
************************************************************************/
|
||||
|
||||
+#define XML_MAX_HUGE_LENGTH 1000000000
|
||||
+
|
||||
#define XML_PARSER_BIG_ENTITY 1000
|
||||
#define XML_PARSER_LOT_ENTITY 5000
|
||||
|
||||
@@ -552,7 +554,7 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
|
||||
errmsg = "Malformed declaration expecting version";
|
||||
break;
|
||||
case XML_ERR_NAME_TOO_LONG:
|
||||
- errmsg = "Name too long use XML_PARSE_HUGE option";
|
||||
+ errmsg = "Name too long";
|
||||
break;
|
||||
#if 0
|
||||
case:
|
||||
@@ -3202,6 +3204,9 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNameComplex++;
|
||||
@@ -3267,7 +3272,8 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
@@ -3293,13 +3299,13 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3338,7 +3344,10 @@ const xmlChar *
|
||||
xmlParseName(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *in;
|
||||
const xmlChar *ret;
|
||||
- int count = 0;
|
||||
+ size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
GROW;
|
||||
|
||||
@@ -3362,8 +3371,7 @@ xmlParseName(xmlParserCtxtPtr ctxt) {
|
||||
in++;
|
||||
if ((*in > 0) && (*in < 0x80)) {
|
||||
count = in - ctxt->input->cur;
|
||||
- if ((count > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (count > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3384,6 +3392,9 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
size_t startPosition = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -3404,17 +3415,13 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
|
||||
(xmlIsNameChar(ctxt, c) && (c != ':'))) {
|
||||
if (count++ > XML_PARSER_CHUNK_SIZE) {
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
- return(NULL);
|
||||
- }
|
||||
count = 0;
|
||||
GROW;
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
return(NULL);
|
||||
}
|
||||
- len += l;
|
||||
+ if (len <= INT_MAX - l)
|
||||
+ len += l;
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
if (c == 0) {
|
||||
@@ -3432,8 +3439,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) {
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3459,7 +3465,10 @@ static const xmlChar *
|
||||
xmlParseNCName(xmlParserCtxtPtr ctxt) {
|
||||
const xmlChar *in, *e;
|
||||
const xmlChar *ret;
|
||||
- int count = 0;
|
||||
+ size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNCName++;
|
||||
@@ -3484,8 +3493,7 @@ xmlParseNCName(xmlParserCtxtPtr ctxt) {
|
||||
goto complex;
|
||||
if ((*in > 0) && (*in < 0x80)) {
|
||||
count = in - ctxt->input->cur;
|
||||
- if ((count > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (count > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3567,6 +3575,9 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
const xmlChar *cur = *str;
|
||||
int len = 0, l;
|
||||
int c;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseStringName++;
|
||||
@@ -3602,12 +3613,6 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
if (len + 10 > max) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
- xmlFree(buffer);
|
||||
- return(NULL);
|
||||
- }
|
||||
max *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buffer,
|
||||
max * sizeof(xmlChar));
|
||||
@@ -3621,14 +3626,18 @@ xmlParseStringName(xmlParserCtxtPtr ctxt, const xmlChar** str) {
|
||||
COPY_BUF(l,buffer,len,c);
|
||||
cur += l;
|
||||
c = CUR_SCHAR(cur, l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
+ xmlFree(buffer);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buffer[len] = 0;
|
||||
*str = cur;
|
||||
return(buffer);
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3655,6 +3664,9 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0, l;
|
||||
int c;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
|
||||
#ifdef DEBUG
|
||||
nbParseNmToken++;
|
||||
@@ -3706,12 +3718,6 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 10 > max) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((max > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
- xmlFree(buffer);
|
||||
- return(NULL);
|
||||
- }
|
||||
max *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buffer,
|
||||
max * sizeof(xmlChar));
|
||||
@@ -3725,6 +3731,11 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
COPY_BUF(l,buffer,len,c);
|
||||
NEXTL(l);
|
||||
c = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
+ xmlFree(buffer);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buffer[len] = 0;
|
||||
return(buffer);
|
||||
@@ -3732,8 +3743,7 @@ xmlParseNmtoken(xmlParserCtxtPtr ctxt) {
|
||||
}
|
||||
if (len == 0)
|
||||
return(NULL);
|
||||
- if ((len > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NmToken");
|
||||
return(NULL);
|
||||
}
|
||||
@@ -3759,6 +3769,9 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
int c, l;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
xmlChar stop;
|
||||
xmlChar *ret = NULL;
|
||||
const xmlChar *cur = NULL;
|
||||
@@ -3818,6 +3831,12 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) {
|
||||
GROW;
|
||||
c = CUR_CHAR(l);
|
||||
}
|
||||
+
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
|
||||
+ "entity value too long\n");
|
||||
+ goto error;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
@@ -3905,6 +3924,9 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
xmlChar *rep = NULL;
|
||||
size_t len = 0;
|
||||
size_t buf_size = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int c, l, in_space = 0;
|
||||
xmlChar *current = NULL;
|
||||
xmlEntityPtr ent;
|
||||
@@ -3936,16 +3958,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
while (((NXT(0) != limit) && /* checked */
|
||||
(IS_CHAR(c)) && (c != '<')) &&
|
||||
(ctxt->instate != XML_PARSER_EOF)) {
|
||||
- /*
|
||||
- * Impose a reasonable limit on attribute size, unless XML_PARSE_HUGE
|
||||
- * special option is given
|
||||
- */
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
- "AttValue length too long\n");
|
||||
- goto mem_error;
|
||||
- }
|
||||
if (c == '&') {
|
||||
in_space = 0;
|
||||
if (NXT(1) == '#') {
|
||||
@@ -4093,6 +4105,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
}
|
||||
GROW;
|
||||
c = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
+ "AttValue length too long\n");
|
||||
+ goto mem_error;
|
||||
+ }
|
||||
}
|
||||
if (ctxt->instate == XML_PARSER_EOF)
|
||||
goto error;
|
||||
@@ -4114,16 +4131,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
} else
|
||||
NEXT;
|
||||
|
||||
- /*
|
||||
- * There we potentially risk an overflow, don't allow attribute value of
|
||||
- * length more than INT_MAX it is a very reasonable assumption !
|
||||
- */
|
||||
- if (len >= INT_MAX) {
|
||||
- xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
- "AttValue length too long\n");
|
||||
- goto mem_error;
|
||||
- }
|
||||
-
|
||||
if (attlen != NULL) *attlen = (int) len;
|
||||
return(buf);
|
||||
|
||||
@@ -4194,6 +4201,9 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
int cur, l;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
xmlChar stop;
|
||||
int state = ctxt->instate;
|
||||
int count = 0;
|
||||
@@ -4221,13 +4231,6 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = (xmlParserInputState) state;
|
||||
- return(NULL);
|
||||
- }
|
||||
size *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
@@ -4256,6 +4259,12 @@ xmlParseSystemLiteral(xmlParserCtxtPtr ctxt) {
|
||||
SHRINK;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "SystemLiteral");
|
||||
+ xmlFree(buf);
|
||||
+ ctxt->instate = (xmlParserInputState) state;
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
ctxt->instate = (xmlParserInputState) state;
|
||||
@@ -4283,6 +4292,9 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
int len = 0;
|
||||
int size = XML_PARSER_BUFFER_SIZE;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_TEXT_LENGTH :
|
||||
+ XML_MAX_NAME_LENGTH;
|
||||
xmlChar cur;
|
||||
xmlChar stop;
|
||||
int count = 0;
|
||||
@@ -4310,12 +4322,6 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 1 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_NAME_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
|
||||
- xmlFree(buf);
|
||||
- return(NULL);
|
||||
- }
|
||||
size *= 2;
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
@@ -4343,6 +4349,11 @@ xmlParsePubidLiteral(xmlParserCtxtPtr ctxt) {
|
||||
SHRINK;
|
||||
cur = CUR;
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Public ID");
|
||||
+ xmlFree(buf);
|
||||
+ return(NULL);
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (cur != stop) {
|
||||
@@ -4742,6 +4753,9 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
int r, rl;
|
||||
int cur, l;
|
||||
size_t count = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int inputid;
|
||||
|
||||
inputid = ctxt->input->id;
|
||||
@@ -4787,13 +4801,6 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
if ((r == '-') && (q == '-')) {
|
||||
xmlFatalErr(ctxt, XML_ERR_HYPHEN_IN_COMMENT, NULL);
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
- "Comment too big found", NULL);
|
||||
- xmlFree (buf);
|
||||
- return;
|
||||
- }
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *new_buf;
|
||||
size_t new_size;
|
||||
@@ -4831,6 +4838,13 @@ xmlParseCommentComplex(xmlParserCtxtPtr ctxt, xmlChar *buf,
|
||||
GROW;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
+ "Comment too big found", NULL);
|
||||
+ xmlFree (buf);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
if (cur == 0) {
|
||||
@@ -4875,6 +4889,9 @@ xmlParseComment(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
size_t size = XML_PARSER_BUFFER_SIZE;
|
||||
size_t len = 0;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
xmlParserInputState state;
|
||||
const xmlChar *in;
|
||||
size_t nbchar = 0;
|
||||
@@ -4958,8 +4975,7 @@ get_more:
|
||||
buf[len] = 0;
|
||||
}
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if (len > maxLength) {
|
||||
xmlFatalErrMsgStr(ctxt, XML_ERR_COMMENT_NOT_FINISHED,
|
||||
"Comment too big found", NULL);
|
||||
xmlFree (buf);
|
||||
@@ -5159,6 +5175,9 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
xmlChar *buf = NULL;
|
||||
size_t len = 0;
|
||||
size_t size = XML_PARSER_BUFFER_SIZE;
|
||||
+ size_t maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
int cur, l;
|
||||
const xmlChar *target;
|
||||
xmlParserInputState state;
|
||||
@@ -5234,14 +5253,6 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
return;
|
||||
}
|
||||
count = 0;
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
- "PI %s too big found", target);
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = state;
|
||||
- return;
|
||||
- }
|
||||
}
|
||||
COPY_BUF(l,buf,len,cur);
|
||||
NEXTL(l);
|
||||
@@ -5251,15 +5262,14 @@ xmlParsePI(xmlParserCtxtPtr ctxt) {
|
||||
GROW;
|
||||
cur = CUR_CHAR(l);
|
||||
}
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
+ "PI %s too big found", target);
|
||||
+ xmlFree(buf);
|
||||
+ ctxt->instate = state;
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
- if ((len > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
- "PI %s too big found", target);
|
||||
- xmlFree(buf);
|
||||
- ctxt->instate = state;
|
||||
- return;
|
||||
- }
|
||||
buf[len] = 0;
|
||||
if (cur != '?') {
|
||||
xmlFatalErrMsgStr(ctxt, XML_ERR_PI_NOT_FINISHED,
|
||||
@@ -8954,6 +8964,9 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
const xmlChar *in = NULL, *start, *end, *last;
|
||||
xmlChar *ret = NULL;
|
||||
int line, col;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
|
||||
GROW;
|
||||
in = (xmlChar *) CUR_PTR;
|
||||
@@ -8993,8 +9006,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
start = in;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9007,8 +9019,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
if ((*in++ == 0x20) && (*in == 0x20)) break;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9041,16 +9052,14 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
last = last + delta;
|
||||
}
|
||||
end = ctxt->input->end;
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9063,8 +9072,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
col++;
|
||||
if (in >= end) {
|
||||
GROW_PARSE_ATT_VALUE_INTERNAL(ctxt, in, start, end)
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9072,8 +9080,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
}
|
||||
}
|
||||
last = in;
|
||||
- if (((in - start) > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
+ if ((in - start) > maxLength) {
|
||||
xmlFatalErrMsg(ctxt, XML_ERR_ATTRIBUTE_NOT_FINISHED,
|
||||
"AttValue length too long\n");
|
||||
return(NULL);
|
||||
@@ -9763,6 +9770,9 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
int s, sl;
|
||||
int cur, l;
|
||||
int count = 0;
|
||||
+ int maxLength = (ctxt->options & XML_PARSE_HUGE) ?
|
||||
+ XML_MAX_HUGE_LENGTH :
|
||||
+ XML_MAX_TEXT_LENGTH;
|
||||
|
||||
/* Check 2.6.0 was NXT(0) not RAW */
|
||||
if (CMP9(CUR_PTR, '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[')) {
|
||||
@@ -9796,13 +9806,6 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
if (len + 5 >= size) {
|
||||
xmlChar *tmp;
|
||||
|
||||
- if ((size > XML_MAX_TEXT_LENGTH) &&
|
||||
- ((ctxt->options & XML_PARSE_HUGE) == 0)) {
|
||||
- xmlFatalErrMsgStr(ctxt, XML_ERR_CDATA_NOT_FINISHED,
|
||||
- "CData section too big found", NULL);
|
||||
- xmlFree (buf);
|
||||
- return;
|
||||
- }
|
||||
tmp = (xmlChar *) xmlRealloc(buf, size * 2 * sizeof(xmlChar));
|
||||
if (tmp == NULL) {
|
||||
xmlFree(buf);
|
||||
@@ -9829,6 +9832,12 @@ xmlParseCDSect(xmlParserCtxtPtr ctxt) {
|
||||
}
|
||||
NEXTL(l);
|
||||
cur = CUR_CHAR(l);
|
||||
+ if (len > maxLength) {
|
||||
+ xmlFatalErrMsg(ctxt, XML_ERR_CDATA_NOT_FINISHED,
|
||||
+ "CData section too big found\n");
|
||||
+ xmlFree(buf);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
buf[len] = 0;
|
||||
ctxt->instate = XML_PARSER_CONTENT;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,101 +0,0 @@
|
||||
From 1b41ec4e9433b05bb0376be4725804c54ef1d80b Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 31 Aug 2022 22:11:25 +0200
|
||||
Subject: [PATCH] [CVE-2022-40304] Fix dict corruption caused by entity
|
||||
reference cycles
|
||||
|
||||
When an entity reference cycle is detected, the entity content is
|
||||
cleared by setting its first byte to zero. But the entity content might
|
||||
be allocated from a dict. In this case, the dict entry becomes corrupted
|
||||
leading to all kinds of logic errors, including memory errors like
|
||||
double-frees.
|
||||
|
||||
Stop storing entity content, orig, ExternalID and SystemID in a dict.
|
||||
These values are unlikely to occur multiple times in a document, so they
|
||||
shouldn't have been stored in a dict in the first place.
|
||||
|
||||
Thanks to Ned Williamson and Nathan Wachholz working with Google Project
|
||||
Zero for the report!
|
||||
---
|
||||
entities.c | 55 ++++++++++++++++--------------------------------------
|
||||
1 file changed, 16 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/entities.c b/entities.c
|
||||
index 84435515..d4e5412e 100644
|
||||
--- a/entities.c
|
||||
+++ b/entities.c
|
||||
@@ -128,36 +128,19 @@ xmlFreeEntity(xmlEntityPtr entity)
|
||||
if ((entity->children) && (entity->owner == 1) &&
|
||||
(entity == (xmlEntityPtr) entity->children->parent))
|
||||
xmlFreeNodeList(entity->children);
|
||||
- if (dict != NULL) {
|
||||
- if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name)))
|
||||
- xmlFree((char *) entity->name);
|
||||
- if ((entity->ExternalID != NULL) &&
|
||||
- (!xmlDictOwns(dict, entity->ExternalID)))
|
||||
- xmlFree((char *) entity->ExternalID);
|
||||
- if ((entity->SystemID != NULL) &&
|
||||
- (!xmlDictOwns(dict, entity->SystemID)))
|
||||
- xmlFree((char *) entity->SystemID);
|
||||
- if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI)))
|
||||
- xmlFree((char *) entity->URI);
|
||||
- if ((entity->content != NULL)
|
||||
- && (!xmlDictOwns(dict, entity->content)))
|
||||
- xmlFree((char *) entity->content);
|
||||
- if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig)))
|
||||
- xmlFree((char *) entity->orig);
|
||||
- } else {
|
||||
- if (entity->name != NULL)
|
||||
- xmlFree((char *) entity->name);
|
||||
- if (entity->ExternalID != NULL)
|
||||
- xmlFree((char *) entity->ExternalID);
|
||||
- if (entity->SystemID != NULL)
|
||||
- xmlFree((char *) entity->SystemID);
|
||||
- if (entity->URI != NULL)
|
||||
- xmlFree((char *) entity->URI);
|
||||
- if (entity->content != NULL)
|
||||
- xmlFree((char *) entity->content);
|
||||
- if (entity->orig != NULL)
|
||||
- xmlFree((char *) entity->orig);
|
||||
- }
|
||||
+ if ((entity->name != NULL) &&
|
||||
+ ((dict == NULL) || (!xmlDictOwns(dict, entity->name))))
|
||||
+ xmlFree((char *) entity->name);
|
||||
+ if (entity->ExternalID != NULL)
|
||||
+ xmlFree((char *) entity->ExternalID);
|
||||
+ if (entity->SystemID != NULL)
|
||||
+ xmlFree((char *) entity->SystemID);
|
||||
+ if (entity->URI != NULL)
|
||||
+ xmlFree((char *) entity->URI);
|
||||
+ if (entity->content != NULL)
|
||||
+ xmlFree((char *) entity->content);
|
||||
+ if (entity->orig != NULL)
|
||||
+ xmlFree((char *) entity->orig);
|
||||
xmlFree(entity);
|
||||
}
|
||||
|
||||
@@ -193,18 +176,12 @@ xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type,
|
||||
ret->SystemID = xmlStrdup(SystemID);
|
||||
} else {
|
||||
ret->name = xmlDictLookup(dict, name, -1);
|
||||
- if (ExternalID != NULL)
|
||||
- ret->ExternalID = xmlDictLookup(dict, ExternalID, -1);
|
||||
- if (SystemID != NULL)
|
||||
- ret->SystemID = xmlDictLookup(dict, SystemID, -1);
|
||||
+ ret->ExternalID = xmlStrdup(ExternalID);
|
||||
+ ret->SystemID = xmlStrdup(SystemID);
|
||||
}
|
||||
if (content != NULL) {
|
||||
ret->length = xmlStrlen(content);
|
||||
- if ((dict != NULL) && (ret->length < 5))
|
||||
- ret->content = (xmlChar *)
|
||||
- xmlDictLookup(dict, content, ret->length);
|
||||
- else
|
||||
- ret->content = xmlStrndup(content, ret->length);
|
||||
+ ret->content = xmlStrndup(content, ret->length);
|
||||
} else {
|
||||
ret->length = 0;
|
||||
ret->content = NULL;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
From 647e072ea0a2f12687fa05c172f4c4713fdb0c4f Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Fri, 7 Apr 2023 11:46:35 +0200
|
||||
Subject: [PATCH] [CVE-2023-28484] Fix null deref in xmlSchemaFixupComplexType
|
||||
|
||||
Fix a null pointer dereference when parsing (invalid) XML schemas.
|
||||
|
||||
Thanks to Robby Simpson for the report!
|
||||
|
||||
Fixes #491.
|
||||
---
|
||||
result/schemas/issue491_0_0.err | 1 +
|
||||
test/schemas/issue491_0.xml | 1 +
|
||||
test/schemas/issue491_0.xsd | 18 ++++++++++++++++++
|
||||
xmlschemas.c | 2 +-
|
||||
4 files changed, 21 insertions(+), 1 deletion(-)
|
||||
create mode 100644 result/schemas/issue491_0_0.err
|
||||
create mode 100644 test/schemas/issue491_0.xml
|
||||
create mode 100644 test/schemas/issue491_0.xsd
|
||||
|
||||
diff --git a/result/schemas/issue491_0_0.err b/result/schemas/issue491_0_0.err
|
||||
new file mode 100644
|
||||
index 00000000..9b2bb969
|
||||
--- /dev/null
|
||||
+++ b/result/schemas/issue491_0_0.err
|
||||
@@ -0,0 +1 @@
|
||||
+./test/schemas/issue491_0.xsd:8: element complexType: Schemas parser error : complex type 'ChildType': The content type of both, the type and its base type, must either 'mixed' or 'element-only'.
|
||||
diff --git a/test/schemas/issue491_0.xml b/test/schemas/issue491_0.xml
|
||||
new file mode 100644
|
||||
index 00000000..e2b2fc2e
|
||||
--- /dev/null
|
||||
+++ b/test/schemas/issue491_0.xml
|
||||
@@ -0,0 +1 @@
|
||||
+<Child xmlns="http://www.test.com">5</Child>
|
||||
diff --git a/test/schemas/issue491_0.xsd b/test/schemas/issue491_0.xsd
|
||||
new file mode 100644
|
||||
index 00000000..81702649
|
||||
--- /dev/null
|
||||
+++ b/test/schemas/issue491_0.xsd
|
||||
@@ -0,0 +1,18 @@
|
||||
+<?xml version='1.0' encoding='UTF-8'?>
|
||||
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.test.com" targetNamespace="http://www.test.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
|
||||
+ <xs:complexType name="BaseType">
|
||||
+ <xs:simpleContent>
|
||||
+ <xs:extension base="xs:int" />
|
||||
+ </xs:simpleContent>
|
||||
+ </xs:complexType>
|
||||
+ <xs:complexType name="ChildType">
|
||||
+ <xs:complexContent>
|
||||
+ <xs:extension base="BaseType">
|
||||
+ <xs:sequence>
|
||||
+ <xs:element name="bad" type="xs:int" minOccurs="0" maxOccurs="1"/>
|
||||
+ </xs:sequence>
|
||||
+ </xs:extension>
|
||||
+ </xs:complexContent>
|
||||
+ </xs:complexType>
|
||||
+ <xs:element name="Child" type="ChildType" />
|
||||
+</xs:schema>
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index 17aa6dfa..36cd6730 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -18563,7 +18563,7 @@ xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
|
||||
"allowed to appear inside other model groups",
|
||||
NULL, NULL);
|
||||
|
||||
- } else if (! dummySequence) {
|
||||
+ } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
|
||||
xmlSchemaTreeItemPtr effectiveContent =
|
||||
(xmlSchemaTreeItemPtr) type->subtypes;
|
||||
/*
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From 09a2dd453007f9c7205274623acdd73747c22d64 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Fri, 7 Apr 2023 11:49:27 +0200
|
||||
Subject: [PATCH] [CVE-2023-29469] Hashing of empty dict strings isn't
|
||||
deterministic
|
||||
|
||||
When hashing empty strings which aren't null-terminated,
|
||||
xmlDictComputeFastKey could produce inconsistent results. This could
|
||||
lead to various logic or memory errors, including double frees.
|
||||
|
||||
For consistency the seed is also taken into account, but this shouldn't
|
||||
have an impact on security.
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
Fixes #510.
|
||||
---
|
||||
dict.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dict.c b/dict.c
|
||||
index 26ce516d..57b76fae 100644
|
||||
--- a/dict.c
|
||||
+++ b/dict.c
|
||||
@@ -451,7 +451,8 @@ static unsigned long
|
||||
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
|
||||
unsigned long value = seed;
|
||||
|
||||
- if (name == NULL) return(0);
|
||||
+ if ((name == NULL) || (namelen <= 0))
|
||||
+ return(value);
|
||||
value += *name;
|
||||
value <<= 5;
|
||||
if (namelen > 10) {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,104 +0,0 @@
|
||||
From e03590c9adfed2856866b5b1edaaf339b4523913 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 8 Feb 2022 02:42:30 +0100
|
||||
Subject: [PATCH 3/3] Don't add IDs containing unexpanded entity references
|
||||
|
||||
When parsing without entity substitution, IDs or IDREFs containing
|
||||
unexpanded entity reference like "abc&x;def" could be created. We could
|
||||
try to expand these entities like in validation mode, but it seems
|
||||
safer to honor the request not to expand entities. We silently ignore
|
||||
such IDs for now.
|
||||
---
|
||||
SAX2.c | 41 ++++++++++++++++++++++-------------------
|
||||
1 file changed, 22 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/SAX2.c b/SAX2.c
|
||||
index edfb06f3..ae6181c4 100644
|
||||
--- a/SAX2.c
|
||||
+++ b/SAX2.c
|
||||
@@ -1368,7 +1368,12 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
||||
#endif /* LIBXML_VALID_ENABLED */
|
||||
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
|
||||
(((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
|
||||
- ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
|
||||
+ ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
|
||||
+ /* Don't create IDs containing entity references */
|
||||
+ (ret->children != NULL) &&
|
||||
+ (ret->children->type == XML_TEXT_NODE) &&
|
||||
+ (ret->children->next == NULL)) {
|
||||
+ xmlChar *content = ret->children->content;
|
||||
/*
|
||||
* when validating, the ID registration is done at the attribute
|
||||
* validation level. Otherwise we have to do specific handling here.
|
||||
@@ -1379,16 +1384,16 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
||||
*
|
||||
* Open issue: normalization of the value.
|
||||
*/
|
||||
- if (xmlValidateNCName(value, 1) != 0) {
|
||||
+ if (xmlValidateNCName(content, 1) != 0) {
|
||||
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
|
||||
"xml:id : attribute value %s is not an NCName\n",
|
||||
- (const char *) value, NULL);
|
||||
+ (const char *) content, NULL);
|
||||
}
|
||||
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
||||
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret))
|
||||
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
||||
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret))
|
||||
- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, value, ret);
|
||||
+ xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
}
|
||||
|
||||
error:
|
||||
@@ -2121,7 +2126,12 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
||||
#endif /* LIBXML_VALID_ENABLED */
|
||||
if (((ctxt->loadsubset & XML_SKIP_IDS) == 0) &&
|
||||
(((ctxt->replaceEntities == 0) && (ctxt->external != 2)) ||
|
||||
- ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0)))) {
|
||||
+ ((ctxt->replaceEntities != 0) && (ctxt->inSubset == 0))) &&
|
||||
+ /* Don't create IDs containing entity references */
|
||||
+ (ret->children != NULL) &&
|
||||
+ (ret->children->type == XML_TEXT_NODE) &&
|
||||
+ (ret->children->next == NULL)) {
|
||||
+ xmlChar *content = ret->children->content;
|
||||
/*
|
||||
* when validating, the ID registration is done at the attribute
|
||||
* validation level. Otherwise we have to do specific handling here.
|
||||
@@ -2134,27 +2144,20 @@ xmlSAX2AttributeNs(xmlParserCtxtPtr ctxt,
|
||||
*
|
||||
* Open issue: normalization of the value.
|
||||
*/
|
||||
- if (dup == NULL)
|
||||
- dup = xmlStrndup(value, valueend - value);
|
||||
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
||||
#ifdef LIBXML_VALID_ENABLED
|
||||
- if (xmlValidateNCName(dup, 1) != 0) {
|
||||
+ if (xmlValidateNCName(content, 1) != 0) {
|
||||
xmlErrValid(ctxt, XML_DTD_XMLID_VALUE,
|
||||
"xml:id : attribute value %s is not an NCName\n",
|
||||
- (const char *) dup, NULL);
|
||||
+ (const char *) content, NULL);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
||||
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
} else if (xmlIsID(ctxt->myDoc, ctxt->node, ret)) {
|
||||
- /* might be worth duplicate entry points and not copy */
|
||||
- if (dup == NULL)
|
||||
- dup = xmlStrndup(value, valueend - value);
|
||||
- xmlAddID(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
||||
+ xmlAddID(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
} else if (xmlIsRef(ctxt->myDoc, ctxt->node, ret)) {
|
||||
- if (dup == NULL)
|
||||
- dup = xmlStrndup(value, valueend - value);
|
||||
- xmlAddRef(&ctxt->vctxt, ctxt->myDoc, dup, ret);
|
||||
+ xmlAddRef(&ctxt->vctxt, ctxt->myDoc, content, ret);
|
||||
}
|
||||
}
|
||||
if (dup != NULL)
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,233 +0,0 @@
|
||||
From 1452dc5373e66a0752364d17ff9416b23e4e2268 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 22 Feb 2022 19:57:12 +0100
|
||||
Subject: [PATCH 1/3] Fix unused variable warnings with disabled features
|
||||
|
||||
---
|
||||
SAX2.c | 65 +++++++++++++++++++++++++++++++++---------------------
|
||||
encoding.c | 3 +++
|
||||
parser.c | 4 ++++
|
||||
tree.c | 3 +++
|
||||
xmlIO.c | 3 +++
|
||||
xmllint.c | 3 +++
|
||||
xzlib.c | 8 +++++++
|
||||
7 files changed, 64 insertions(+), 25 deletions(-)
|
||||
|
||||
diff --git a/SAX2.c b/SAX2.c
|
||||
index ae6181c..8f27113 100644
|
||||
--- a/SAX2.c
|
||||
+++ b/SAX2.c
|
||||
@@ -180,31 +180,6 @@ xmlWarnMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
||||
NULL, 0, 0, msg, str1);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * xmlNsErrMsg:
|
||||
- * @ctxt: an XML parser context
|
||||
- * @error: the error number
|
||||
- * @msg: the error message
|
||||
- * @str1: an error string
|
||||
- * @str2: an error string
|
||||
- *
|
||||
- * Handle a namespace error
|
||||
- */
|
||||
-static void LIBXML_ATTR_FORMAT(3,0)
|
||||
-xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
||||
- const char *msg, const xmlChar *str1, const xmlChar *str2)
|
||||
-{
|
||||
- if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
||||
- (ctxt->instate == XML_PARSER_EOF))
|
||||
- return;
|
||||
- if (ctxt != NULL)
|
||||
- ctxt->errNo = error;
|
||||
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
||||
- XML_ERR_ERROR, NULL, 0,
|
||||
- (const char *) str1, (const char *) str2,
|
||||
- NULL, 0, 0, msg, str1, str2);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* xmlNsWarnMsg:
|
||||
* @ctxt: an XML parser context
|
||||
@@ -709,6 +684,9 @@ xmlSAX2AttributeDecl(void *ctx, const xmlChar *elem, const xmlChar *fullname,
|
||||
xmlAttributePtr attr;
|
||||
xmlChar *name = NULL, *prefix = NULL;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) attr;
|
||||
+
|
||||
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
||||
return;
|
||||
|
||||
@@ -776,6 +754,9 @@ xmlSAX2ElementDecl(void *ctx, const xmlChar * name, int type,
|
||||
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
||||
xmlElementPtr elem = NULL;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) elem;
|
||||
+
|
||||
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
||||
return;
|
||||
|
||||
@@ -822,6 +803,9 @@ xmlSAX2NotationDecl(void *ctx, const xmlChar *name,
|
||||
xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
|
||||
xmlNotationPtr nota = NULL;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) nota;
|
||||
+
|
||||
if ((ctxt == NULL) || (ctxt->myDoc == NULL))
|
||||
return;
|
||||
|
||||
@@ -1051,6 +1035,31 @@ xmlSAX2EndDocument(void *ctx)
|
||||
}
|
||||
|
||||
#if defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED) || defined(LIBXML_LEGACY_ENABLED)
|
||||
+/**
|
||||
+ * xmlNsErrMsg:
|
||||
+ * @ctxt: an XML parser context
|
||||
+ * @error: the error number
|
||||
+ * @msg: the error message
|
||||
+ * @str1: an error string
|
||||
+ * @str2: an error string
|
||||
+ *
|
||||
+ * Handle a namespace error
|
||||
+ */
|
||||
+static void LIBXML_ATTR_FORMAT(3,0)
|
||||
+xmlNsErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error,
|
||||
+ const char *msg, const xmlChar *str1, const xmlChar *str2)
|
||||
+{
|
||||
+ if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
|
||||
+ (ctxt->instate == XML_PARSER_EOF))
|
||||
+ return;
|
||||
+ if (ctxt != NULL)
|
||||
+ ctxt->errNo = error;
|
||||
+ __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_NAMESPACE, error,
|
||||
+ XML_ERR_ERROR, NULL, 0,
|
||||
+ (const char *) str1, (const char *) str2,
|
||||
+ NULL, 0, 0, msg, str1, str2);
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* xmlSAX2AttributeInternal:
|
||||
* @ctx: the user data (XML parser context)
|
||||
@@ -1144,6 +1153,9 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
||||
xmlNsPtr nsret;
|
||||
xmlChar *val;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) nsret;
|
||||
+
|
||||
if (!ctxt->replaceEntities) {
|
||||
ctxt->depth++;
|
||||
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
||||
@@ -1206,6 +1218,9 @@ xmlSAX2AttributeInternal(void *ctx, const xmlChar *fullname,
|
||||
xmlNsPtr nsret;
|
||||
xmlChar *val;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) nsret;
|
||||
+
|
||||
if (!ctxt->replaceEntities) {
|
||||
ctxt->depth++;
|
||||
val = xmlStringDecodeEntities(ctxt, value, XML_SUBSTITUTE_REF,
|
||||
diff --git a/encoding.c b/encoding.c
|
||||
index c14c9ff..ba03772 100644
|
||||
--- a/encoding.c
|
||||
+++ b/encoding.c
|
||||
@@ -2784,6 +2784,9 @@ xmlCharEncCloseFunc(xmlCharEncodingHandler *handler) {
|
||||
int tofree = 0;
|
||||
int i, handler_in_list = 0;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) handler_in_list;
|
||||
+
|
||||
if (handler == NULL) return(-1);
|
||||
if (handler->name == NULL) return(-1);
|
||||
if (handlers != NULL) {
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 0d5bcc1..0bdc252 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -1106,6 +1106,10 @@ xmlHasFeature(xmlFeature feature)
|
||||
static void
|
||||
xmlDetectSAX2(xmlParserCtxtPtr ctxt) {
|
||||
xmlSAXHandlerPtr sax;
|
||||
+
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) sax;
|
||||
+
|
||||
if (ctxt == NULL) return;
|
||||
sax = ctxt->sax;
|
||||
#ifdef LIBXML_SAX1_ENABLED
|
||||
diff --git a/tree.c b/tree.c
|
||||
index 0cf2483..4345eea 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -6542,6 +6542,9 @@ xmlGetPropNodeInternal(const xmlNode *node, const xmlChar *name,
|
||||
{
|
||||
xmlAttrPtr prop;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) useDTD;
|
||||
+
|
||||
if ((node == NULL) || (node->type != XML_ELEMENT_NODE) || (name == NULL))
|
||||
return(NULL);
|
||||
|
||||
diff --git a/xmlIO.c b/xmlIO.c
|
||||
index 007144c..b716ed3 100644
|
||||
--- a/xmlIO.c
|
||||
+++ b/xmlIO.c
|
||||
@@ -3821,6 +3821,9 @@ xmlParserGetDirectory(const char *filename) {
|
||||
*/
|
||||
xmlParserInputPtr
|
||||
xmlCheckHTTPInput(xmlParserCtxtPtr ctxt, xmlParserInputPtr ret) {
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) ctxt;
|
||||
+
|
||||
#ifdef LIBXML_HTTP_ENABLED
|
||||
if ((ret != NULL) && (ret->buf != NULL) &&
|
||||
(ret->buf->readcallback == xmlIOHTTPRead) &&
|
||||
diff --git a/xmllint.c b/xmllint.c
|
||||
index ee6bfdc..b314189 100644
|
||||
--- a/xmllint.c
|
||||
+++ b/xmllint.c
|
||||
@@ -3853,6 +3853,9 @@ main(int argc, char **argv) {
|
||||
xmlFreePattern(patternc);
|
||||
#endif
|
||||
|
||||
+ /* Avoid unused label warning if features are disabled. */
|
||||
+ goto error;
|
||||
+
|
||||
error:
|
||||
xmlCleanupParser();
|
||||
xmlMemoryDump();
|
||||
diff --git a/xzlib.c b/xzlib.c
|
||||
index 9a34738..62cb2b0 100644
|
||||
--- a/xzlib.c
|
||||
+++ b/xzlib.c
|
||||
@@ -389,6 +389,10 @@ xz_head(xz_statep state)
|
||||
int flags;
|
||||
unsigned len;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) flags;
|
||||
+ (void) len;
|
||||
+
|
||||
/* allocate read buffers and inflate memory */
|
||||
if (state->size == 0) {
|
||||
/* allocate buffers */
|
||||
@@ -536,6 +540,10 @@ xz_decomp(xz_statep state)
|
||||
|
||||
lzma_action action = LZMA_RUN;
|
||||
|
||||
+ /* Avoid unused variable warning if features are disabled. */
|
||||
+ (void) crc;
|
||||
+ (void) len;
|
||||
+
|
||||
/* fill output buffer up to end of deflate stream */
|
||||
had = strm->avail_out;
|
||||
do {
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,112 +0,0 @@
|
||||
From ce0871e15cdb68e505ccd9d9c96ff8455ed936ab Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 20 Feb 2022 16:44:41 +0100
|
||||
Subject: [PATCH 1/3] Only warn on invalid redeclarations of predefined
|
||||
entities
|
||||
|
||||
Downgrade the error message to a warning since the error was ignored,
|
||||
anyway. Also print the name of redeclared entity. For a proper fix that
|
||||
also shows filename and line number of the invalid redeclaration, we'd
|
||||
have to
|
||||
|
||||
- pass the parser context to the entity functions somehow, or
|
||||
- make these functions return distinct error codes.
|
||||
|
||||
Partial fix for #308.
|
||||
---
|
||||
entities.c | 21 +++++++++++++++++++--
|
||||
result/errors/ent_redecl.xml | 3 +++
|
||||
result/errors/ent_redecl.xml.ent | 1 +
|
||||
result/errors/ent_redecl.xml.err | 1 +
|
||||
result/errors/ent_redecl.xml.str | 1 +
|
||||
test/errors/ent_redecl.xml | 4 ++++
|
||||
6 files changed, 29 insertions(+), 2 deletions(-)
|
||||
create mode 100644 result/errors/ent_redecl.xml
|
||||
create mode 100644 result/errors/ent_redecl.xml.ent
|
||||
create mode 100644 result/errors/ent_redecl.xml.err
|
||||
create mode 100644 result/errors/ent_redecl.xml.str
|
||||
create mode 100644 test/errors/ent_redecl.xml
|
||||
|
||||
diff --git a/entities.c b/entities.c
|
||||
index 1a8f86f0..a27209d1 100644
|
||||
--- a/entities.c
|
||||
+++ b/entities.c
|
||||
@@ -94,6 +94,23 @@ xmlEntitiesErr(xmlParserErrors code, const char *msg)
|
||||
__xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * xmlEntitiesWarn:
|
||||
+ * @code: the error code
|
||||
+ * @msg: the message
|
||||
+ *
|
||||
+ * Handle an out of memory condition
|
||||
+ */
|
||||
+static void LIBXML_ATTR_FORMAT(2,0)
|
||||
+xmlEntitiesWarn(xmlParserErrors code, const char *msg, const xmlChar *str1)
|
||||
+{
|
||||
+ __xmlRaiseError(NULL, NULL, NULL,
|
||||
+ NULL, NULL, XML_FROM_TREE, code,
|
||||
+ XML_ERR_WARNING, NULL, 0,
|
||||
+ (const char *)str1, NULL, NULL, 0, 0,
|
||||
+ msg, (const char *)str1, NULL);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* xmlFreeEntity : clean-up an entity record.
|
||||
*/
|
||||
@@ -255,9 +272,9 @@ xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type,
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
- xmlEntitiesErr(XML_ERR_ENTITY_PROCESSING,
|
||||
+ xmlEntitiesWarn(XML_ERR_ENTITY_PROCESSING,
|
||||
"xmlAddEntity: invalid redeclaration of predefined"
|
||||
- " entity");
|
||||
+ " entity '%s'", name);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
diff --git a/result/errors/ent_redecl.xml b/result/errors/ent_redecl.xml
|
||||
new file mode 100644
|
||||
index 00000000..04216b65
|
||||
--- /dev/null
|
||||
+++ b/result/errors/ent_redecl.xml
|
||||
@@ -0,0 +1,3 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!DOCTYPE doc>
|
||||
+<doc/>
|
||||
diff --git a/result/errors/ent_redecl.xml.ent b/result/errors/ent_redecl.xml.ent
|
||||
new file mode 100644
|
||||
index 00000000..31908b05
|
||||
--- /dev/null
|
||||
+++ b/result/errors/ent_redecl.xml.ent
|
||||
@@ -0,0 +1 @@
|
||||
+warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt'
|
||||
diff --git a/result/errors/ent_redecl.xml.err b/result/errors/ent_redecl.xml.err
|
||||
new file mode 100644
|
||||
index 00000000..31908b05
|
||||
--- /dev/null
|
||||
+++ b/result/errors/ent_redecl.xml.err
|
||||
@@ -0,0 +1 @@
|
||||
+warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt'
|
||||
diff --git a/result/errors/ent_redecl.xml.str b/result/errors/ent_redecl.xml.str
|
||||
new file mode 100644
|
||||
index 00000000..31908b05
|
||||
--- /dev/null
|
||||
+++ b/result/errors/ent_redecl.xml.str
|
||||
@@ -0,0 +1 @@
|
||||
+warning : xmlAddEntity: invalid redeclaration of predefined entity 'lt'
|
||||
diff --git a/test/errors/ent_redecl.xml b/test/errors/ent_redecl.xml
|
||||
new file mode 100644
|
||||
index 00000000..e446681b
|
||||
--- /dev/null
|
||||
+++ b/test/errors/ent_redecl.xml
|
||||
@@ -0,0 +1,4 @@
|
||||
+<!DOCTYPE doc [
|
||||
+ <!ENTITY lt '<'>
|
||||
+]>
|
||||
+<doc/>
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,186 +0,0 @@
|
||||
From 274a1b5bec980ababa23e267a8fdcd8b71a5b2b7 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Sun, 20 Feb 2022 16:05:53 +0100
|
||||
Subject: [PATCH 2/3] Remove unneeded code in xmlreader.c
|
||||
|
||||
Now that no references to ID and IDREF attributes are stored in
|
||||
streaming validation mode, there's no need to try and remove them.
|
||||
|
||||
Also remove xmlTextReaderFreeIDTable which was identical to
|
||||
xmlFreeIDTable.
|
||||
---
|
||||
xmlreader.c | 137 +---------------------------------------------------
|
||||
1 file changed, 1 insertion(+), 136 deletions(-)
|
||||
|
||||
diff --git a/xmlreader.c b/xmlreader.c
|
||||
index 72e40b03..b20c70ad 100644
|
||||
--- a/xmlreader.c
|
||||
+++ b/xmlreader.c
|
||||
@@ -228,116 +228,6 @@ static int xmlTextReaderNextTree(xmlTextReaderPtr reader);
|
||||
static void xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur);
|
||||
static void xmlTextReaderFreeNodeList(xmlTextReaderPtr reader, xmlNodePtr cur);
|
||||
|
||||
-/**
|
||||
- * xmlFreeID:
|
||||
- * @not: A id
|
||||
- *
|
||||
- * Deallocate the memory used by an id definition
|
||||
- */
|
||||
-static void
|
||||
-xmlFreeID(xmlIDPtr id) {
|
||||
- xmlDictPtr dict = NULL;
|
||||
-
|
||||
- if (id == NULL) return;
|
||||
-
|
||||
- if (id->doc != NULL)
|
||||
- dict = id->doc->dict;
|
||||
-
|
||||
- if (id->value != NULL)
|
||||
- DICT_FREE(id->value)
|
||||
- if (id->name != NULL)
|
||||
- DICT_FREE(id->name)
|
||||
- xmlFree(id);
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * xmlTextReaderRemoveID:
|
||||
- * @doc: the document
|
||||
- * @attr: the attribute
|
||||
- *
|
||||
- * Remove the given attribute from the ID table maintained internally.
|
||||
- *
|
||||
- * Returns -1 if the lookup failed and 0 otherwise
|
||||
- */
|
||||
-static int
|
||||
-xmlTextReaderRemoveID(xmlDocPtr doc, xmlAttrPtr attr) {
|
||||
- xmlIDTablePtr table;
|
||||
- xmlIDPtr id;
|
||||
- xmlChar *ID;
|
||||
-
|
||||
- if (doc == NULL) return(-1);
|
||||
- if (attr == NULL) return(-1);
|
||||
- table = (xmlIDTablePtr) doc->ids;
|
||||
- if (table == NULL)
|
||||
- return(-1);
|
||||
-
|
||||
- ID = xmlNodeListGetString(doc, attr->children, 1);
|
||||
- if (ID == NULL)
|
||||
- return(-1);
|
||||
- id = xmlHashLookup(table, ID);
|
||||
- xmlFree(ID);
|
||||
- if (id == NULL || id->attr != attr) {
|
||||
- return(-1);
|
||||
- }
|
||||
- id->name = attr->name;
|
||||
- attr->name = NULL;
|
||||
- id->attr = NULL;
|
||||
- return(0);
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * xmlTextReaderWalkRemoveRef:
|
||||
- * @data: Contents of current link
|
||||
- * @user: Value supplied by the user
|
||||
- *
|
||||
- * Returns 0 to abort the walk or 1 to continue
|
||||
- */
|
||||
-static int
|
||||
-xmlTextReaderWalkRemoveRef(const void *data, void *user)
|
||||
-{
|
||||
- xmlRefPtr ref = (xmlRefPtr)data;
|
||||
- xmlAttrPtr attr = (xmlAttrPtr)user;
|
||||
-
|
||||
- if (ref->attr == attr) { /* Matched: remove and terminate walk */
|
||||
- ref->name = xmlStrdup(attr->name);
|
||||
- ref->attr = NULL;
|
||||
- return 0;
|
||||
- }
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * xmlTextReaderRemoveRef:
|
||||
- * @doc: the document
|
||||
- * @attr: the attribute
|
||||
- *
|
||||
- * Remove the given attribute from the Ref table maintained internally.
|
||||
- *
|
||||
- * Returns -1 if the lookup failed and 0 otherwise
|
||||
- */
|
||||
-static int
|
||||
-xmlTextReaderRemoveRef(xmlDocPtr doc, xmlAttrPtr attr) {
|
||||
- xmlListPtr ref_list;
|
||||
- xmlRefTablePtr table;
|
||||
- xmlChar *ID;
|
||||
-
|
||||
- if (doc == NULL) return(-1);
|
||||
- if (attr == NULL) return(-1);
|
||||
- table = (xmlRefTablePtr) doc->refs;
|
||||
- if (table == NULL)
|
||||
- return(-1);
|
||||
-
|
||||
- ID = xmlNodeListGetString(doc, attr->children, 1);
|
||||
- if (ID == NULL)
|
||||
- return(-1);
|
||||
- ref_list = xmlHashLookup(table, ID);
|
||||
- xmlFree(ID);
|
||||
- if(ref_list == NULL)
|
||||
- return (-1);
|
||||
- xmlListWalk(ref_list, xmlTextReaderWalkRemoveRef, attr);
|
||||
- return(0);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* xmlTextReaderFreeProp:
|
||||
* @reader: the xmlTextReaderPtr used
|
||||
@@ -358,15 +248,6 @@ xmlTextReaderFreeProp(xmlTextReaderPtr reader, xmlAttrPtr cur) {
|
||||
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
|
||||
xmlDeregisterNodeDefaultValue((xmlNodePtr) cur);
|
||||
|
||||
- /* Check for ID removal -> leading to invalid references ! */
|
||||
- if ((cur->parent != NULL) && (cur->parent->doc != NULL)) {
|
||||
- if (xmlIsID(cur->parent->doc, cur->parent, cur))
|
||||
- xmlTextReaderRemoveID(cur->parent->doc, cur);
|
||||
- if (((cur->parent->doc->intSubset != NULL) ||
|
||||
- (cur->parent->doc->extSubset != NULL)) &&
|
||||
- (xmlIsRef(cur->parent->doc, cur->parent, cur)))
|
||||
- xmlTextReaderRemoveRef(cur->parent->doc, cur);
|
||||
- }
|
||||
if (cur->children != NULL)
|
||||
xmlTextReaderFreeNodeList(reader, cur->children);
|
||||
|
||||
@@ -570,22 +451,6 @@ xmlTextReaderFreeNode(xmlTextReaderPtr reader, xmlNodePtr cur) {
|
||||
}
|
||||
}
|
||||
|
||||
-static void
|
||||
-xmlTextReaderFreeIDTableEntry(void *id, const xmlChar *name ATTRIBUTE_UNUSED) {
|
||||
- xmlFreeID((xmlIDPtr) id);
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * xmlTextReaderFreeIDTable:
|
||||
- * @table: An id table
|
||||
- *
|
||||
- * Deallocate the memory used by an ID hash table.
|
||||
- */
|
||||
-static void
|
||||
-xmlTextReaderFreeIDTable(xmlIDTablePtr table) {
|
||||
- xmlHashFree(table, xmlTextReaderFreeIDTableEntry);
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* xmlTextReaderFreeDoc:
|
||||
* @reader: the xmlTextReaderPtr used
|
||||
@@ -605,7 +470,7 @@ xmlTextReaderFreeDoc(xmlTextReaderPtr reader, xmlDocPtr cur) {
|
||||
/*
|
||||
* Do this before freeing the children list to avoid ID lookups
|
||||
*/
|
||||
- if (cur->ids != NULL) xmlTextReaderFreeIDTable((xmlIDTablePtr) cur->ids);
|
||||
+ if (cur->ids != NULL) xmlFreeIDTable((xmlIDTablePtr) cur->ids);
|
||||
cur->ids = NULL;
|
||||
if (cur->refs != NULL) xmlFreeRefTable((xmlRefTablePtr) cur->refs);
|
||||
cur->refs = NULL;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,246 +0,0 @@
|
||||
From d7cb33cf44aa688f24215c9cd398c1a26f0d25ff Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 13 Jan 2022 17:06:14 +0100
|
||||
Subject: [PATCH 1/3] Rework validation context flags
|
||||
|
||||
Use a bitmask instead of magic values to
|
||||
|
||||
- keep track whether the validation context is part of a parser context
|
||||
- keep track whether xmlValidateDtdFinal was called
|
||||
|
||||
This allows to add addtional flags later.
|
||||
|
||||
Note that this deliberately changes the name of a public struct member,
|
||||
assuming that this was always private data never to be used by client
|
||||
code.
|
||||
---
|
||||
HTMLparser.c | 2 +-
|
||||
SAX2.c | 10 ++++++----
|
||||
include/libxml/valid.h | 14 +++++++-------
|
||||
parserInternals.c | 2 +-
|
||||
valid.c | 43 +++++++++++++++---------------------------
|
||||
5 files changed, 30 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/HTMLparser.c b/HTMLparser.c
|
||||
index 3e8a1657..eb3a820a 100644
|
||||
--- a/HTMLparser.c
|
||||
+++ b/HTMLparser.c
|
||||
@@ -5118,7 +5118,7 @@ htmlInitParserCtxt(htmlParserCtxtPtr ctxt)
|
||||
ctxt->linenumbers = xmlLineNumbersDefaultValue;
|
||||
ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
|
||||
ctxt->html = 1;
|
||||
- ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
|
||||
+ ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
|
||||
ctxt->vctxt.userData = ctxt;
|
||||
ctxt->vctxt.error = xmlParserValidityError;
|
||||
ctxt->vctxt.warning = xmlParserValidityWarning;
|
||||
diff --git a/SAX2.c b/SAX2.c
|
||||
index 03192465..edfb06f3 100644
|
||||
--- a/SAX2.c
|
||||
+++ b/SAX2.c
|
||||
@@ -1747,7 +1747,8 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
|
||||
* If it's the Document root, finish the DTD validation and
|
||||
* check the document root element for validity
|
||||
*/
|
||||
- if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
|
||||
+ if ((ctxt->validate) &&
|
||||
+ ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
|
||||
int chk;
|
||||
|
||||
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
|
||||
@@ -1756,7 +1757,7 @@ xmlSAX2StartElement(void *ctx, const xmlChar *fullname, const xmlChar **atts)
|
||||
if (chk < 0)
|
||||
ctxt->wellFormed = 0;
|
||||
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
|
||||
- ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
|
||||
+ ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
|
||||
}
|
||||
#endif /* LIBXML_VALID_ENABLED */
|
||||
|
||||
@@ -2405,7 +2406,8 @@ xmlSAX2StartElementNs(void *ctx,
|
||||
* If it's the Document root, finish the DTD validation and
|
||||
* check the document root element for validity
|
||||
*/
|
||||
- if ((ctxt->validate) && (ctxt->vctxt.finishDtd == XML_CTXT_FINISH_DTD_0)) {
|
||||
+ if ((ctxt->validate) &&
|
||||
+ ((ctxt->vctxt.flags & XML_VCTXT_DTD_VALIDATED) == 0)) {
|
||||
int chk;
|
||||
|
||||
chk = xmlValidateDtdFinal(&ctxt->vctxt, ctxt->myDoc);
|
||||
@@ -2414,7 +2416,7 @@ xmlSAX2StartElementNs(void *ctx,
|
||||
if (chk < 0)
|
||||
ctxt->wellFormed = 0;
|
||||
ctxt->valid &= xmlValidateRoot(&ctxt->vctxt, ctxt->myDoc);
|
||||
- ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_1;
|
||||
+ ctxt->vctxt.flags |= XML_VCTXT_DTD_VALIDATED;
|
||||
}
|
||||
#endif /* LIBXML_VALID_ENABLED */
|
||||
}
|
||||
diff --git a/include/libxml/valid.h b/include/libxml/valid.h
|
||||
index 2bc7b380..15c9772c 100644
|
||||
--- a/include/libxml/valid.h
|
||||
+++ b/include/libxml/valid.h
|
||||
@@ -60,17 +60,17 @@ typedef void (XMLCDECL *xmlValidityWarningFunc) (void *ctx,
|
||||
|
||||
#ifdef IN_LIBXML
|
||||
/**
|
||||
- * XML_CTXT_FINISH_DTD_0:
|
||||
+ * XML_VCTXT_DTD_VALIDATED:
|
||||
*
|
||||
- * Special value for finishDtd field when embedded in an xmlParserCtxt
|
||||
+ * Set after xmlValidateDtdFinal was called.
|
||||
*/
|
||||
-#define XML_CTXT_FINISH_DTD_0 0xabcd1234
|
||||
+#define XML_VCTXT_DTD_VALIDATED (1u << 0)
|
||||
/**
|
||||
- * XML_CTXT_FINISH_DTD_1:
|
||||
+ * XML_VCTXT_USE_PCTXT:
|
||||
*
|
||||
- * Special value for finishDtd field when embedded in an xmlParserCtxt
|
||||
+ * Set if the validation context is part of a parser context.
|
||||
*/
|
||||
-#define XML_CTXT_FINISH_DTD_1 0xabcd1235
|
||||
+#define XML_VCTXT_USE_PCTXT (1u << 1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -90,7 +90,7 @@ struct _xmlValidCtxt {
|
||||
int nodeMax; /* Max depth of the parsing stack */
|
||||
xmlNodePtr *nodeTab; /* array of nodes */
|
||||
|
||||
- unsigned int finishDtd; /* finished validating the Dtd ? */
|
||||
+ unsigned int flags; /* internal flags */
|
||||
xmlDocPtr doc; /* the document */
|
||||
int valid; /* temporary validity check result */
|
||||
|
||||
diff --git a/parserInternals.c b/parserInternals.c
|
||||
index c5c0b16d..cf5ad369 100644
|
||||
--- a/parserInternals.c
|
||||
+++ b/parserInternals.c
|
||||
@@ -1733,7 +1733,7 @@ xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
|
||||
ctxt->options |= XML_PARSE_NOBLANKS;
|
||||
}
|
||||
|
||||
- ctxt->vctxt.finishDtd = XML_CTXT_FINISH_DTD_0;
|
||||
+ ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
|
||||
ctxt->vctxt.userData = ctxt;
|
||||
ctxt->vctxt.error = xmlParserValidityError;
|
||||
ctxt->vctxt.warning = xmlParserValidityWarning;
|
||||
diff --git a/valid.c b/valid.c
|
||||
index 8e596f1d..5cd1e676 100644
|
||||
--- a/valid.c
|
||||
+++ b/valid.c
|
||||
@@ -64,10 +64,9 @@ xmlVErrMemory(xmlValidCtxtPtr ctxt, const char *extra)
|
||||
if (ctxt != NULL) {
|
||||
channel = ctxt->error;
|
||||
data = ctxt->userData;
|
||||
- /* Use the special values to detect if it is part of a parsing
|
||||
+ /* Look up flag to detect if it is part of a parsing
|
||||
context */
|
||||
- if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
|
||||
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
|
||||
long delta = (char *) ctxt - (char *) ctxt->userData;
|
||||
if ((delta > 0) && (delta < 250))
|
||||
pctxt = ctxt->userData;
|
||||
@@ -104,10 +103,9 @@ xmlErrValid(xmlValidCtxtPtr ctxt, xmlParserErrors error,
|
||||
if (ctxt != NULL) {
|
||||
channel = ctxt->error;
|
||||
data = ctxt->userData;
|
||||
- /* Use the special values to detect if it is part of a parsing
|
||||
+ /* Look up flag to detect if it is part of a parsing
|
||||
context */
|
||||
- if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
|
||||
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
|
||||
long delta = (char *) ctxt - (char *) ctxt->userData;
|
||||
if ((delta > 0) && (delta < 250))
|
||||
pctxt = ctxt->userData;
|
||||
@@ -151,10 +149,9 @@ xmlErrValidNode(xmlValidCtxtPtr ctxt,
|
||||
if (ctxt != NULL) {
|
||||
channel = ctxt->error;
|
||||
data = ctxt->userData;
|
||||
- /* Use the special values to detect if it is part of a parsing
|
||||
+ /* Look up flag to detect if it is part of a parsing
|
||||
context */
|
||||
- if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
|
||||
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
|
||||
long delta = (char *) ctxt - (char *) ctxt->userData;
|
||||
if ((delta > 0) && (delta < 250))
|
||||
pctxt = ctxt->userData;
|
||||
@@ -194,10 +191,9 @@ xmlErrValidNodeNr(xmlValidCtxtPtr ctxt,
|
||||
if (ctxt != NULL) {
|
||||
channel = ctxt->error;
|
||||
data = ctxt->userData;
|
||||
- /* Use the special values to detect if it is part of a parsing
|
||||
+ /* Look up flag to detect if it is part of a parsing
|
||||
context */
|
||||
- if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
|
||||
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
|
||||
long delta = (char *) ctxt - (char *) ctxt->userData;
|
||||
if ((delta > 0) && (delta < 250))
|
||||
pctxt = ctxt->userData;
|
||||
@@ -235,10 +231,9 @@ xmlErrValidWarning(xmlValidCtxtPtr ctxt,
|
||||
if (ctxt != NULL) {
|
||||
channel = ctxt->warning;
|
||||
data = ctxt->userData;
|
||||
- /* Use the special values to detect if it is part of a parsing
|
||||
+ /* Look up flag to detect if it is part of a parsing
|
||||
context */
|
||||
- if ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1)) {
|
||||
+ if (ctxt->flags & XML_VCTXT_USE_PCTXT) {
|
||||
long delta = (char *) ctxt - (char *) ctxt->userData;
|
||||
if ((delta > 0) && (delta < 250))
|
||||
pctxt = ctxt->userData;
|
||||
@@ -1642,9 +1637,7 @@ xmlAddElementDecl(xmlValidCtxtPtr ctxt,
|
||||
* and flag it by setting a special parent value
|
||||
* so the parser doesn't unallocate it.
|
||||
*/
|
||||
- if ((ctxt != NULL) &&
|
||||
- ((ctxt->finishDtd == XML_CTXT_FINISH_DTD_0) ||
|
||||
- (ctxt->finishDtd == XML_CTXT_FINISH_DTD_1))) {
|
||||
+ if ((ctxt != NULL) && (ctxt->flags & XML_VCTXT_USE_PCTXT)) {
|
||||
ret->content = content;
|
||||
if (content != NULL)
|
||||
content->parent = (xmlElementContentPtr) 1;
|
||||
@@ -2642,13 +2635,7 @@ xmlIsStreaming(xmlValidCtxtPtr ctxt) {
|
||||
|
||||
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))
|
||||
+ if ((ctxt->flags & XML_VCTXT_USE_PCTXT) == 0)
|
||||
return(0);
|
||||
pctxt = ctxt->userData;
|
||||
return(pctxt->parseMode == XML_PARSE_READER);
|
||||
@@ -6677,8 +6664,8 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
|
||||
}
|
||||
|
||||
/* trick to get correct line id report */
|
||||
- save = ctxt->finishDtd;
|
||||
- ctxt->finishDtd = 0;
|
||||
+ save = ctxt->flags;
|
||||
+ ctxt->flags &= ~XML_VCTXT_USE_PCTXT;
|
||||
|
||||
/*
|
||||
* Check all the NOTATION/NOTATIONS attributes
|
||||
@@ -6694,7 +6681,7 @@ xmlValidateDocumentFinal(xmlValidCtxtPtr ctxt, xmlDocPtr doc) {
|
||||
ctxt->valid = 1;
|
||||
xmlHashScan(table, xmlValidateCheckRefCallback, ctxt);
|
||||
|
||||
- ctxt->finishDtd = save;
|
||||
+ ctxt->flags = save;
|
||||
return(ctxt->valid);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From 43c97c9c203d9920b21db8b1d5a999eac2fa8d69 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Dalessio <mike.dalessio@gmail.com>
|
||||
Date: Mon, 21 Feb 2022 09:35:59 -0500
|
||||
Subject: [PATCH 2/3] Update `xmlStrlen()` to use POSIX / ISO C `strlen()`
|
||||
|
||||
This should be faster on a wide range of platforms.
|
||||
|
||||
Closes #212
|
||||
---
|
||||
xmlstring.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/xmlstring.c b/xmlstring.c
|
||||
index 5a6875f..281b8a7 100644
|
||||
--- a/xmlstring.c
|
||||
+++ b/xmlstring.c
|
||||
@@ -424,13 +424,7 @@ xmlStrsub(const xmlChar *str, int start, int len) {
|
||||
|
||||
int
|
||||
xmlStrlen(const xmlChar *str) {
|
||||
- size_t len = 0;
|
||||
-
|
||||
- if (str == NULL) return(0);
|
||||
- while (*str != 0) { /* non input consuming */
|
||||
- str++;
|
||||
- len++;
|
||||
- }
|
||||
+ size_t len = str ? strlen((const char *)str) : 0;
|
||||
return(len > INT_MAX ? 0 : len);
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
From 1a2d8ddc066143d256fdb8cc554707fe141dd2f6 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 11 Oct 2022 13:02:47 +0200
|
||||
Subject: [PATCH] parser: Fix potential memory leak in xmlParseAttValueInternal
|
||||
|
||||
Fix memory leak in case xmlParseAttValueInternal is called with a NULL
|
||||
`len` a non-NULL `alloc` argument. This static function is never called
|
||||
with such arguments internally, but the misleading code should be fixed
|
||||
nevertheless.
|
||||
|
||||
Fixes #422.
|
||||
|
||||
Reference:https://github.com/GNOME/libxml2/commit/1a2d8ddc066143d256fdb8cc554707fe141dd2f6
|
||||
Conflict:NA
|
||||
|
||||
---
|
||||
parser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/parser.c b/parser.c
|
||||
index 7bb47366..337e62f6 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -9155,6 +9155,7 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
in++;
|
||||
col++;
|
||||
if (len != NULL) {
|
||||
+ if (alloc) *alloc = 0;
|
||||
*len = last - start;
|
||||
ret = (xmlChar *) start;
|
||||
} else {
|
||||
@@ -9164,7 +9165,6 @@ xmlParseAttValueInternal(xmlParserCtxtPtr ctxt, int *len, int *alloc,
|
||||
CUR_PTR = in;
|
||||
ctxt->input->line = line;
|
||||
ctxt->input->col = col;
|
||||
- if (alloc) *alloc = 0;
|
||||
return ret;
|
||||
need_complex:
|
||||
if (alloc) *alloc = 1;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 4a568a14077bd4cf03878ee9e2d8fb7e79ff7641 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Wed, 2 Nov 2022 10:53:24 +0100
|
||||
Subject: [PATCH 3/3] schemas: Fix infinite loop in
|
||||
xmlSchemaCheckElemSubstGroup
|
||||
|
||||
Types like xmlSchemaTypeAnyTypeDef have a base type pointing to itself,
|
||||
resulting in an infinite loop.
|
||||
|
||||
Fixes #430.
|
||||
---
|
||||
xmlschemas.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index 2da962b..a62db2d 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -19957,7 +19957,8 @@ xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
|
||||
/*
|
||||
* The set of all {derivation method}s involved in the derivation
|
||||
*/
|
||||
- while ((type != NULL) && (type != headType)) {
|
||||
+ while ((type != NULL) && (type != headType) &&
|
||||
+ (type != type->baseType)) {
|
||||
if ((WXS_IS_EXTENSION(type)) &&
|
||||
((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
|
||||
methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,75 +0,0 @@
|
||||
From 1d4f5d24ac3976012ab1f5b811385e7b00caaecf Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Tue, 13 Sep 2022 16:40:31 +0200
|
||||
Subject: [PATCH] schemas: Fix null-pointer-deref in
|
||||
xmlSchemaCheckCOSSTDerivedOK
|
||||
|
||||
Found by OSS-Fuzz.
|
||||
|
||||
Reference:https://github.com/GNOME/libxml2/commit/1d4f5d24ac3976012ab1f5b811385e7b00caaecf
|
||||
Conflict:NA
|
||||
|
||||
---
|
||||
result/schemas/oss-fuzz-51295_0_0.err | 2 ++
|
||||
test/schemas/oss-fuzz-51295_0.xml | 1 +
|
||||
test/schemas/oss-fuzz-51295_0.xsd | 4 ++++
|
||||
xmlschemas.c | 15 +++++++++++++--
|
||||
4 files changed, 20 insertions(+), 2 deletions(-)
|
||||
create mode 100644 result/schemas/oss-fuzz-51295_0_0.err
|
||||
create mode 100644 test/schemas/oss-fuzz-51295_0.xml
|
||||
create mode 100644 test/schemas/oss-fuzz-51295_0.xsd
|
||||
|
||||
diff --git a/result/schemas/oss-fuzz-51295_0_0.err b/result/schemas/oss-fuzz-51295_0_0.err
|
||||
new file mode 100644
|
||||
index 00000000..1e89524f
|
||||
--- /dev/null
|
||||
+++ b/result/schemas/oss-fuzz-51295_0_0.err
|
||||
@@ -0,0 +1,2 @@
|
||||
+./test/schemas/oss-fuzz-51295_0.xsd:2: element element: Schemas parser error : element decl. 'e': The element declaration 'e' defines a circular substitution group to element declaration 'e'.
|
||||
+./test/schemas/oss-fuzz-51295_0.xsd:2: element element: Schemas parser error : element decl. 'e': The element declaration 'e' defines a circular substitution group to element declaration 'e'.
|
||||
diff --git a/test/schemas/oss-fuzz-51295_0.xml b/test/schemas/oss-fuzz-51295_0.xml
|
||||
new file mode 100644
|
||||
index 00000000..10a7e703
|
||||
--- /dev/null
|
||||
+++ b/test/schemas/oss-fuzz-51295_0.xml
|
||||
@@ -0,0 +1 @@
|
||||
+<e/>
|
||||
diff --git a/test/schemas/oss-fuzz-51295_0.xsd b/test/schemas/oss-fuzz-51295_0.xsd
|
||||
new file mode 100644
|
||||
index 00000000..fde96af5
|
||||
--- /dev/null
|
||||
+++ b/test/schemas/oss-fuzz-51295_0.xsd
|
||||
@@ -0,0 +1,4 @@
|
||||
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
+ <xs:element name="e" substitutionGroup="e"/>
|
||||
+ <xs:element name="t" substitutionGroup="e" type='xs:decimal'/>
|
||||
+</xs:schema>
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index ade10f78..de6ea2b0 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -13348,8 +13348,19 @@ xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
|
||||
* declaration `resolved` to by the `actual value`
|
||||
* of the substitutionGroup [attribute], if present"
|
||||
*/
|
||||
- if (elemDecl->subtypes == NULL)
|
||||
- elemDecl->subtypes = substHead->subtypes;
|
||||
+ if (elemDecl->subtypes == NULL) {
|
||||
+ if (substHead->subtypes == NULL) {
|
||||
+ /*
|
||||
+ * This can happen with self-referencing substitution
|
||||
+ * groups. The cycle will be detected later, but we have
|
||||
+ * to set subtypes to avoid null-pointer dereferences.
|
||||
+ */
|
||||
+ elemDecl->subtypes = xmlSchemaGetBuiltInType(
|
||||
+ XML_SCHEMAS_ANYTYPE);
|
||||
+ } else {
|
||||
+ elemDecl->subtypes = substHead->subtypes;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
/*
|
||||
--
|
||||
2.27.0
|
||||
|
||||
BIN
libxml2-2.11.4.tar.xz
Normal file
BIN
libxml2-2.11.4.tar.xz
Normal file
Binary file not shown.
Binary file not shown.
43
libxml2.spec
43
libxml2.spec
@ -1,29 +1,12 @@
|
||||
Summary: Library providing XML and HTML support
|
||||
Name: libxml2
|
||||
Version: 2.9.14
|
||||
Release: 9
|
||||
Version: 2.11.4
|
||||
Release: 1
|
||||
License: MIT
|
||||
Group: Development/Libraries
|
||||
Source: https://download.gnome.org/sources/%{name}/2.9/%{name}-%{version}.tar.xz
|
||||
Source: https://download.gnome.org/sources/%{name}/2.11/%{name}-%{version}.tar.xz
|
||||
|
||||
Patch0: libxml2-multilib.patch
|
||||
Patch1: backport-Rework-validation-context-flags.patch
|
||||
Patch2: backport-Remove-unneeded-code-in-xmlreader.c.patch
|
||||
Patch3: backport-Don-t-add-IDs-containing-unexpanded-entity-reference.patch
|
||||
Patch4: backport-Only-warn-on-invalid-redeclarations-of-predefined-en.patch
|
||||
Patch5: backport-Add-XML_DEPRECATED-macro.patch
|
||||
Patch6: Fix-memleaks-in-xmlXIncludeProcessFlags.patch
|
||||
Patch7: Fix-memory-leaks-for-xmlACatalogAdd.patch
|
||||
Patch8: Fix-memory-leaks-in-xmlACatalogAdd-when-xmlHashAddEntry-failed.patch
|
||||
Patch9: backport-CVE-2022-40303-Fix-integer-overflows-with-XML_PARSE_.patch
|
||||
Patch10: backport-CVE-2022-40304-Fix-dict-corruption-caused-by-entity-.patch
|
||||
Patch11: backport-schemas-Fix-null-pointer-deref-in-xmlSchemaCheckCOSS.patch
|
||||
Patch12: backport-parser-Fix-potential-memory-leak-in-xmlParseAttValue.patch
|
||||
Patch13: backport-Fix-unused-variable-warnings-with-disabled-features.patch
|
||||
Patch14: backport-Update-xmlStrlen-to-use-POSIX-ISO-C-strlen.patch
|
||||
Patch15: backport-schemas-Fix-infinite-loop-in-xmlSchemaCheckElemSubst.patch
|
||||
Patch16: backport-CVE-2023-28484-Fix-null-deref-in-xmlSchemaFixupCompl.patch
|
||||
Patch17: backport-CVE-2023-29469-Hashing-of-empty-dict-strings-isn-t-d.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: python3-devel
|
||||
@ -140,7 +123,6 @@ rm -fr %{buildroot}
|
||||
%defattr(-, root, root)
|
||||
|
||||
%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
|
||||
@ -150,35 +132,34 @@ rm -fr %{buildroot}
|
||||
%doc %{_datadir}/gtk-doc/html/libxml2/*.css
|
||||
|
||||
%{_libdir}/lib*.so
|
||||
%{_libdir}/*.sh
|
||||
%{_includedir}/*
|
||||
%{_bindir}/xml2-config
|
||||
%{_datadir}/aclocal/libxml.m4
|
||||
%{_libdir}/pkgconfig/libxml-2.0.pc
|
||||
%{_libdir}/cmake/libxml2/libxml2-config.cmake
|
||||
|
||||
%{_libdir}/*a
|
||||
|
||||
%files -n python3-%{name}
|
||||
%defattr(-, root, root)
|
||||
|
||||
%{_libdir}/python3*/site-packages/libxml2.py*
|
||||
%{_libdir}/python3*/site-packages/drv_libxml2.py*
|
||||
%{_libdir}/python3*/site-packages/__pycache__/*py*
|
||||
%{_libdir}/python3*/site-packages/libxml2mod*
|
||||
%doc python/TODO
|
||||
%{python3_sitearch}/libxml2mod.so
|
||||
%{python3_sitelib}/*.py
|
||||
%{python3_sitelib}/__pycache__/*.pyc
|
||||
%doc python/libxml2class.txt
|
||||
%doc py3doc/*.py
|
||||
%doc doc/python.html
|
||||
|
||||
%files help
|
||||
%doc %{_mandir}/man1/xml2-config.1*
|
||||
%doc %{_mandir}/man1/xmllint.1*
|
||||
%doc %{_mandir}/man1/xmlcatalog.1*
|
||||
%doc %{_mandir}/man3/libxml.3*
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Jul 18 2023 zhuofeng <zhuofeng2@huawei.com.com> - 2.11.4-1
|
||||
- Type:enhancement
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:update version to 2.11.4
|
||||
|
||||
* Thu Apr 20 2023 BruceGW <gyl93216@163.com> - 2.9.14-9
|
||||
- Type:CVE
|
||||
- CVE:CVE-2023-28484 CVE-2023-29469
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user