1
0
mirror of https://gitlab.gnome.org/GNOME/libxml2.git synced 2025-02-06 05:57:39 +03:00

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!
This commit is contained in:
Nick Wellnhofer 2022-08-25 17:43:08 +02:00
parent 1a2d8ddc06
commit ffaec75809

233
parser.c
View File

@ -112,6 +112,8 @@ xmlParseElementEnd(xmlParserCtxtPtr ctxt);
* *
************************************************************************/
#define XML_MAX_HUGE_LENGTH 1000000000
#define XML_PARSER_BIG_ENTITY 1000
#define XML_PARSER_LOT_ENTITY 5000
@ -562,7 +564,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:
@ -3208,6 +3210,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++;
@ -3273,7 +3278,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);
}
@ -3299,13 +3305,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);
}
@ -3346,7 +3352,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;
@ -3370,8 +3379,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);
}
@ -3392,6 +3400,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
@ -3412,17 +3423,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) {
@ -3440,8 +3447,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);
}
@ -3467,7 +3473,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++;
@ -3492,8 +3501,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);
}
@ -3575,6 +3583,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++;
@ -3610,12 +3621,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);
if (tmp == NULL) {
@ -3628,14 +3633,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);
}
@ -3664,6 +3673,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++;
@ -3715,12 +3727,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);
if (tmp == NULL) {
@ -3733,6 +3739,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);
@ -3740,8 +3751,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);
}
@ -3769,6 +3779,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;
@ -3828,6 +3841,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)
@ -3915,6 +3934,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;
@ -3946,16 +3968,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) == '#') {
@ -4103,6 +4115,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;
@ -4124,16 +4141,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 = len;
return(buf);
@ -4208,6 +4215,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;
@ -4235,13 +4245,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);
if (tmp == NULL) {
@ -4270,6 +4273,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;
@ -4299,6 +4308,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;
@ -4326,12 +4338,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);
if (tmp == NULL) {
@ -4359,6 +4365,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) {
@ -4762,6 +4773,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;
@ -4807,13 +4821,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;
@ -4851,6 +4858,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) {
@ -4897,6 +4911,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;
@ -4979,8 +4996,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);
@ -5184,6 +5200,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;
@ -5259,14 +5278,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);
@ -5276,15 +5287,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,
@ -9026,6 +9036,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;
@ -9065,8 +9078,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);
@ -9079,8 +9091,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);
@ -9113,16 +9124,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);
@ -9135,8 +9144,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);
@ -9144,8 +9152,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);
@ -9837,6 +9844,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', '[')) {
@ -9870,13 +9880,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);
if (tmp == NULL) {
xmlFree(buf);
@ -9903,6 +9906,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;