fix CVE-2022-40303 CVE-2022-40304
This commit is contained in:
parent
08c8f7924c
commit
8c40086f01
@ -0,0 +1,618 @@
|
||||
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
|
||||
|
||||
@ -0,0 +1,101 @@
|
||||
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
|
||||
|
||||
328
backport-pre-CVE-2022-40303-Remove-useless-comparisons.patch
Normal file
328
backport-pre-CVE-2022-40303-Remove-useless-comparisons.patch
Normal file
@ -0,0 +1,328 @@
|
||||
From 9bd7abfba41ca219ab39cb912f020f8e02116f32 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
Date: Thu, 2 Jan 2020 14:14:48 +0100
|
||||
Subject: [PATCH] Remove useless comparisons
|
||||
|
||||
Found by lgtm.com
|
||||
---
|
||||
nanoftp.c | 3 +-
|
||||
parser.c | 1 -
|
||||
valid.c | 43 ++++++------
|
||||
xmlregexp.c | 4 +-
|
||||
xmlschemas.c | 191 +++++++++++++++++++++++++--------------------------
|
||||
5 files changed, 117 insertions(+), 125 deletions(-)
|
||||
|
||||
diff --git a/nanoftp.c b/nanoftp.c
|
||||
index 54fa026d..80685da4 100644
|
||||
--- a/nanoftp.c
|
||||
+++ b/nanoftp.c
|
||||
@@ -1251,8 +1251,7 @@ xmlNanoFTPConnectTo(const char *server, int port) {
|
||||
xmlNanoFTPFreeCtxt(ctxt);
|
||||
return(NULL);
|
||||
}
|
||||
- if (port != 0)
|
||||
- ctxt->port = port;
|
||||
+ ctxt->port = port;
|
||||
res = xmlNanoFTPConnect(ctxt);
|
||||
if (res < 0) {
|
||||
xmlNanoFTPFreeCtxt(ctxt);
|
||||
diff --git a/parser.c b/parser.c
|
||||
index a34bb6cd..43a1a0ab 100644
|
||||
--- a/parser.c
|
||||
+++ b/parser.c
|
||||
@@ -3912,7 +3912,6 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) {
|
||||
"AttValue length too long\n");
|
||||
goto mem_error;
|
||||
}
|
||||
- if (c == 0) break;
|
||||
if (c == '&') {
|
||||
in_space = 0;
|
||||
if (NXT(1) == '#') {
|
||||
diff --git a/valid.c b/valid.c
|
||||
index 07963e74..b828bc65 100644
|
||||
--- a/valid.c
|
||||
+++ b/valid.c
|
||||
@@ -5919,28 +5919,27 @@ xmlValidatePushCData(xmlValidCtxtPtr ctxt, const xmlChar *data, int len) {
|
||||
break;
|
||||
case XML_ELEMENT_TYPE_MIXED:
|
||||
break;
|
||||
- case XML_ELEMENT_TYPE_ELEMENT:
|
||||
- if (len > 0) {
|
||||
- int i;
|
||||
-
|
||||
- for (i = 0;i < len;i++) {
|
||||
- if (!IS_BLANK_CH(data[i])) {
|
||||
- xmlErrValidNode(ctxt, state->node,
|
||||
- XML_DTD_CONTENT_MODEL,
|
||||
- "Element %s content does not follow the DTD, Text not allowed\n",
|
||||
- state->node->name, NULL, NULL);
|
||||
- ret = 0;
|
||||
- goto done;
|
||||
- }
|
||||
- }
|
||||
- /*
|
||||
- * TODO:
|
||||
- * VC: Standalone Document Declaration
|
||||
- * element types with element content, if white space
|
||||
- * occurs directly within any instance of those types.
|
||||
- */
|
||||
- }
|
||||
- break;
|
||||
+ case XML_ELEMENT_TYPE_ELEMENT: {
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0;i < len;i++) {
|
||||
+ if (!IS_BLANK_CH(data[i])) {
|
||||
+ xmlErrValidNode(ctxt, state->node,
|
||||
+ XML_DTD_CONTENT_MODEL,
|
||||
+ "Element %s content does not follow the DTD, Text not allowed\n",
|
||||
+ state->node->name, NULL, NULL);
|
||||
+ ret = 0;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ /*
|
||||
+ * TODO:
|
||||
+ * VC: Standalone Document Declaration
|
||||
+ * element types with element content, if white space
|
||||
+ * occurs directly within any instance of those types.
|
||||
+ */
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/xmlregexp.c b/xmlregexp.c
|
||||
index c119ff1f..5a2deb9e 100644
|
||||
--- a/xmlregexp.c
|
||||
+++ b/xmlregexp.c
|
||||
@@ -6055,7 +6055,7 @@ xmlAutomataNewOnceTrans2(xmlAutomataPtr am, xmlAutomataStatePtr from,
|
||||
return(NULL);
|
||||
if (min < 1)
|
||||
return(NULL);
|
||||
- if ((max < min) || (max < 1))
|
||||
+ if (max < min)
|
||||
return(NULL);
|
||||
atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
|
||||
if (atom == NULL)
|
||||
@@ -6134,7 +6134,7 @@ xmlAutomataNewOnceTrans(xmlAutomataPtr am, xmlAutomataStatePtr from,
|
||||
return(NULL);
|
||||
if (min < 1)
|
||||
return(NULL);
|
||||
- if ((max < min) || (max < 1))
|
||||
+ if (max < min)
|
||||
return(NULL);
|
||||
atom = xmlRegNewAtom(am, XML_REGEXP_STRING);
|
||||
if (atom == NULL)
|
||||
diff --git a/xmlschemas.c b/xmlschemas.c
|
||||
index d19de6df..301c8449 100644
|
||||
--- a/xmlschemas.c
|
||||
+++ b/xmlschemas.c
|
||||
@@ -24184,7 +24184,7 @@ xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
|
||||
unsigned long length,
|
||||
int fireErrors)
|
||||
{
|
||||
- int ret, error = 0;
|
||||
+ int ret, error = 0, found;
|
||||
|
||||
xmlSchemaTypePtr tmpType;
|
||||
xmlSchemaFacetLinkPtr facetLink;
|
||||
@@ -24308,103 +24308,98 @@ WXS_IS_LIST:
|
||||
}
|
||||
|
||||
pattern_and_enum:
|
||||
- if (error >= 0) {
|
||||
- int found = 0;
|
||||
- /*
|
||||
- * Process enumerations. Facet values are in the value space
|
||||
- * of the defining type's base type. This seems to be a bug in the
|
||||
- * XML Schema 1.0 spec. Use the whitespace type of the base type.
|
||||
- * Only the first set of enumerations in the ancestor-or-self axis
|
||||
- * is used for validation.
|
||||
- */
|
||||
- ret = 0;
|
||||
- tmpType = type;
|
||||
- do {
|
||||
- for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
|
||||
- if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
|
||||
- continue;
|
||||
- found = 1;
|
||||
- ret = xmlSchemaAreValuesEqual(facet->val, val);
|
||||
- if (ret == 1)
|
||||
- break;
|
||||
- else if (ret < 0) {
|
||||
- AERROR_INT("xmlSchemaValidateFacets",
|
||||
- "validating against an enumeration facet");
|
||||
- return (-1);
|
||||
- }
|
||||
- }
|
||||
- if (ret != 0)
|
||||
- break;
|
||||
- /*
|
||||
- * Break on the first set of enumerations. Any additional
|
||||
- * enumerations which might be existent on the ancestors
|
||||
- * of the current type are restricted by this set; thus
|
||||
- * *must* *not* be taken into account.
|
||||
- */
|
||||
- if (found)
|
||||
- break;
|
||||
- tmpType = tmpType->baseType;
|
||||
- } while ((tmpType != NULL) &&
|
||||
- (tmpType->type != XML_SCHEMA_TYPE_BASIC));
|
||||
- if (found && (ret == 0)) {
|
||||
- ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
|
||||
- if (fireErrors) {
|
||||
- xmlSchemaFacetErr(actxt, ret, node,
|
||||
- value, 0, type, NULL, NULL, NULL, NULL);
|
||||
- } else
|
||||
- return (ret);
|
||||
- if (error == 0)
|
||||
- error = ret;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (error >= 0) {
|
||||
- int found;
|
||||
- /*
|
||||
- * Process patters. Pattern facets are ORed at type level
|
||||
- * and ANDed if derived. Walk the base type axis.
|
||||
- */
|
||||
- tmpType = type;
|
||||
- facet = NULL;
|
||||
- do {
|
||||
- found = 0;
|
||||
- for (facetLink = tmpType->facetSet; facetLink != NULL;
|
||||
- facetLink = facetLink->next) {
|
||||
- if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
|
||||
- continue;
|
||||
- found = 1;
|
||||
- /*
|
||||
- * NOTE that for patterns, @value needs to be the
|
||||
- * normalized value.
|
||||
- */
|
||||
- ret = xmlRegexpExec(facetLink->facet->regexp, value);
|
||||
- if (ret == 1)
|
||||
- break;
|
||||
- else if (ret < 0) {
|
||||
- AERROR_INT("xmlSchemaValidateFacets",
|
||||
- "validating against a pattern facet");
|
||||
- return (-1);
|
||||
- } else {
|
||||
- /*
|
||||
- * Save the last non-validating facet.
|
||||
- */
|
||||
- facet = facetLink->facet;
|
||||
- }
|
||||
- }
|
||||
- if (found && (ret != 1)) {
|
||||
- ret = XML_SCHEMAV_CVC_PATTERN_VALID;
|
||||
- if (fireErrors) {
|
||||
- xmlSchemaFacetErr(actxt, ret, node,
|
||||
- value, 0, type, facet, NULL, NULL, NULL);
|
||||
- } else
|
||||
- return (ret);
|
||||
- if (error == 0)
|
||||
- error = ret;
|
||||
- break;
|
||||
- }
|
||||
- tmpType = tmpType->baseType;
|
||||
- } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
|
||||
- }
|
||||
+ found = 0;
|
||||
+ /*
|
||||
+ * Process enumerations. Facet values are in the value space
|
||||
+ * of the defining type's base type. This seems to be a bug in the
|
||||
+ * XML Schema 1.0 spec. Use the whitespace type of the base type.
|
||||
+ * Only the first set of enumerations in the ancestor-or-self axis
|
||||
+ * is used for validation.
|
||||
+ */
|
||||
+ ret = 0;
|
||||
+ tmpType = type;
|
||||
+ do {
|
||||
+ for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
|
||||
+ if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
|
||||
+ continue;
|
||||
+ found = 1;
|
||||
+ ret = xmlSchemaAreValuesEqual(facet->val, val);
|
||||
+ if (ret == 1)
|
||||
+ break;
|
||||
+ else if (ret < 0) {
|
||||
+ AERROR_INT("xmlSchemaValidateFacets",
|
||||
+ "validating against an enumeration facet");
|
||||
+ return (-1);
|
||||
+ }
|
||||
+ }
|
||||
+ if (ret != 0)
|
||||
+ break;
|
||||
+ /*
|
||||
+ * Break on the first set of enumerations. Any additional
|
||||
+ * enumerations which might be existent on the ancestors
|
||||
+ * of the current type are restricted by this set; thus
|
||||
+ * *must* *not* be taken into account.
|
||||
+ */
|
||||
+ if (found)
|
||||
+ break;
|
||||
+ tmpType = tmpType->baseType;
|
||||
+ } while ((tmpType != NULL) &&
|
||||
+ (tmpType->type != XML_SCHEMA_TYPE_BASIC));
|
||||
+ if (found && (ret == 0)) {
|
||||
+ ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
|
||||
+ if (fireErrors) {
|
||||
+ xmlSchemaFacetErr(actxt, ret, node,
|
||||
+ value, 0, type, NULL, NULL, NULL, NULL);
|
||||
+ } else
|
||||
+ return (ret);
|
||||
+ if (error == 0)
|
||||
+ error = ret;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Process patters. Pattern facets are ORed at type level
|
||||
+ * and ANDed if derived. Walk the base type axis.
|
||||
+ */
|
||||
+ tmpType = type;
|
||||
+ facet = NULL;
|
||||
+ do {
|
||||
+ found = 0;
|
||||
+ for (facetLink = tmpType->facetSet; facetLink != NULL;
|
||||
+ facetLink = facetLink->next) {
|
||||
+ if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
|
||||
+ continue;
|
||||
+ found = 1;
|
||||
+ /*
|
||||
+ * NOTE that for patterns, @value needs to be the
|
||||
+ * normalized value.
|
||||
+ */
|
||||
+ ret = xmlRegexpExec(facetLink->facet->regexp, value);
|
||||
+ if (ret == 1)
|
||||
+ break;
|
||||
+ else if (ret < 0) {
|
||||
+ AERROR_INT("xmlSchemaValidateFacets",
|
||||
+ "validating against a pattern facet");
|
||||
+ return (-1);
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Save the last non-validating facet.
|
||||
+ */
|
||||
+ facet = facetLink->facet;
|
||||
+ }
|
||||
+ }
|
||||
+ if (found && (ret != 1)) {
|
||||
+ ret = XML_SCHEMAV_CVC_PATTERN_VALID;
|
||||
+ if (fireErrors) {
|
||||
+ xmlSchemaFacetErr(actxt, ret, node,
|
||||
+ value, 0, type, facet, NULL, NULL, NULL);
|
||||
+ } else
|
||||
+ return (ret);
|
||||
+ if (error == 0)
|
||||
+ error = ret;
|
||||
+ break;
|
||||
+ }
|
||||
+ tmpType = tmpType->baseType;
|
||||
+ } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
|
||||
|
||||
return (error);
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
Summary: Library providing XML and HTML support
|
||||
Name: libxml2
|
||||
Version: 2.9.10
|
||||
Release: 33
|
||||
Release: 34
|
||||
License: MIT
|
||||
Group: Development/Libraries
|
||||
Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
|
||||
@ -123,6 +123,9 @@ Patch110:backport-CVE-2022-29824-Fix-integer-overflows-in-xmlBuf-and-xmlBuffer.p
|
||||
Patch111:Fix-memory-leaks-for-xmlACatalogAdd.patch
|
||||
Patch112:Fix-memory-leaks-in-xmlACatalogAdd-when-xmlHashAddEntry-failed.patch
|
||||
Patch113:backport-CVE-2016-3709.patch
|
||||
Patch114:backport-pre-CVE-2022-40303-Remove-useless-comparisons.patch
|
||||
Patch115:backport-CVE-2022-40303-Fix-integer-overflows-with-XML_PARSE_.patch
|
||||
Patch116:backport-CVE-2022-40304-Fix-dict-corruption-caused-by-entity-.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
BuildRequires: python2-devel
|
||||
@ -314,6 +317,9 @@ rm -fr %{buildroot}
|
||||
|
||||
|
||||
%changelog
|
||||
* Tue Nov 08 2022 fuanan <fuanan3@h-partners.com> - 2.9.10-34
|
||||
- fix CVE-2022-40303 CVE-2022-40304
|
||||
|
||||
* Wed Sep 14 2022 hubin <hubin73@huawei.com> - 2.9.10-33
|
||||
- remove recommend in spec
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user