File libxml2-CVE-2013-2877.patch of Package libxml2
commit e50ba8164eee06461c73cd8abb9b46aa0be81869
Author: Daniel Veillard <veillard@redhat.com>
Date: Thu Apr 11 15:54:51 2013 +0800
Improve handling of xmlStopParser()
Add a specific parser error
Try to stop parsing as quickly as possible
Index: libxml2-2.7.8/include/libxml/xmlerror.h
===================================================================
--- libxml2-2.7.8.orig/include/libxml/xmlerror.h 2013-07-11 17:07:12.505169153 +0200
+++ libxml2-2.7.8/include/libxml/xmlerror.h 2013-07-11 17:08:05.935775345 +0200
@@ -205,6 +205,7 @@ typedef enum {
XML_WAR_ENTITY_REDEFINED, /* 107 */
XML_ERR_UNKNOWN_VERSION, /* 108 */
XML_ERR_VERSION_MISMATCH, /* 109 */
+ XML_ERR_USER_STOP = 111, /* 111 */
XML_NS_ERR_XML_NAMESPACE = 200,
XML_NS_ERR_UNDEFINED_NAMESPACE, /* 201 */
XML_NS_ERR_QNAME, /* 202 */
Index: libxml2-2.7.8/parser.c
===================================================================
--- libxml2-2.7.3/parser.c.orig 2013-07-18 13:50:44.316540032 +0200
+++ libxml2-2.7.3/parser.c 2013-07-18 13:56:41.168527350 +0200
@@ -2360,6 +2360,8 @@
NEXT;
if ((ctxt->sax != NULL) && (ctxt->sax->getParameterEntity != NULL))
entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
if (entity == NULL) {
/*
@@ -4629,7 +4631,8 @@
}
if (buf != NULL)
xmlFree(buf);
- ctxt->instate = state;
+ if (ctxt->instate != XML_PARSER_EOF)
+ ctxt->instate = state;
return;
}
if (buf != NULL)
@@ -5194,6 +5197,8 @@
}
}
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
SKIP_BLANKS;
if (RAW != '>') {
xmlFatalErrMsgStr(ctxt, XML_ERR_ENTITY_NOT_FINISHED,
@@ -7116,6 +7121,8 @@
ent = xmlSAX2GetEntity(ctxt, name);
}
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(NULL);
/*
* [ WFC: Entity Declared ]
* In a document without any DTD, a document with only an
@@ -7307,6 +7314,10 @@
ent = xmlSAX2GetEntity(ctxt, name);
}
}
+ if (ctxt->instate == XML_PARSER_EOF) {
+ xmlFree(name);
+ return;
+ }
/*
* [ WFC: Entity Declared ]
@@ -7468,8 +7479,9 @@
*/
if ((ctxt->sax != NULL) &&
(ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
+ entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
if (entity == NULL) {
/*
* [ WFC: Entity Declared ]
@@ -7694,8 +7706,11 @@
*/
if ((ctxt->sax != NULL) &&
(ctxt->sax->getParameterEntity != NULL))
- entity = ctxt->sax->getParameterEntity(ctxt->userData,
- name);
+ entity = ctxt->sax->getParameterEntity(ctxt->userData, name);
+ if (ctxt->instate == XML_PARSER_EOF) {
+ xmlFree(name);
+ return;
+ }
if (entity == NULL) {
/*
* [ WFC: Entity Declared ]
@@ -7797,6 +7812,8 @@
if ((ctxt->sax != NULL) && (ctxt->sax->internalSubset != NULL) &&
(!ctxt->disableSAX))
ctxt->sax->internalSubset(ctxt->userData, name, ExternalID, URI);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
/*
* Is there any internal subset declarations ?
@@ -9492,6 +9509,8 @@
* Parse the content of the element:
*/
xmlParseContent(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return;
if (!IS_BYTE_CHAR(RAW)) {
xmlFatalErrMsgStrIntStr(ctxt, XML_ERR_TAG_NOT_FINISHED,
"Premature end of data in tag %s line %d\n",
@@ -10050,6 +10069,8 @@
*/
if ((ctxt->sax) && (ctxt->sax->setDocumentLocator))
ctxt->sax->setDocumentLocator(ctxt->userData, &xmlDefaultSAXLocator);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
if ((ctxt->encoding == (const xmlChar *)XML_CHAR_ENCODING_NONE) &&
((ctxt->input->end - ctxt->input->cur) >= 4)) {
@@ -10096,6 +10117,8 @@
}
if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
/*
* The Misc part of the Prolog
@@ -10115,6 +10138,8 @@
if (RAW == '[') {
ctxt->instate = XML_PARSER_DTD;
xmlParseInternalSubset(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
}
/*
@@ -10125,6 +10150,8 @@
(!ctxt->disableSAX))
ctxt->sax->externalSubset(ctxt->userData, ctxt->intSubName,
ctxt->extSubSystem, ctxt->extSubURI);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
ctxt->inSubset = 0;
xmlCleanSpecialAttr(ctxt);
@@ -10265,6 +10292,8 @@
}
if ((ctxt->sax) && (ctxt->sax->startDocument) && (!ctxt->disableSAX))
ctxt->sax->startDocument(ctxt->userData);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
/*
* Doing validity checking on chunk doesn't make sense
@@ -10582,7 +10611,7 @@
}
xmlParseGetLasts(ctxt, &lastlt, &lastgt);
- while (1) {
+ while (ctxt->instate != XML_PARSER_EOF) {
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(0);
@@ -10820,6 +10849,8 @@
ctxt->sax->endElement(ctxt->userData, name);
#endif /* LIBXML_SAX1_ENABLED */
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
spacePop(ctxt);
if (ctxt->nameNr == 0) {
ctxt->instate = XML_PARSER_EPILOG;
@@ -10999,6 +11030,8 @@
ctxt->sax->characters(ctxt->userData,
ctxt->input->cur, tmp);
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
SKIPL(tmp);
ctxt->checkIndex = 0;
}
@@ -11034,6 +11067,8 @@
ctxt->sax->characters(ctxt->userData,
ctxt->input->cur, base);
}
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
SKIPL(base + 3);
ctxt->checkIndex = 0;
ctxt->instate = XML_PARSER_CONTENT;
@@ -11065,6 +11100,8 @@
"PP: Parsing PI\n");
#endif
xmlParsePI(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->checkIndex = 0;
} else if ((cur == '<') && (next == '!') &&
(ctxt->input->cur[2] == '-') &&
@@ -11077,6 +11114,8 @@
"PP: Parsing Comment\n");
#endif
xmlParseComment(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->instate = XML_PARSER_MISC;
ctxt->checkIndex = 0;
} else if ((cur == '<') && (next == '!') &&
@@ -11096,6 +11135,8 @@
#endif
ctxt->inSubset = 1;
xmlParseDocTypeDecl(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
if (RAW == '[') {
ctxt->instate = XML_PARSER_DTD;
#ifdef DEBUG_PUSH
@@ -11152,6 +11193,8 @@
"PP: Parsing PI\n");
#endif
xmlParsePI(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
} else if ((cur == '<') && (next == '!') &&
(ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
if ((!terminate) &&
@@ -11162,6 +11205,8 @@
"PP: Parsing Comment\n");
#endif
xmlParseComment(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->instate = XML_PARSER_PROLOG;
} else if ((cur == '<') && (next == '!') &&
(avail < 4)) {
@@ -11196,6 +11241,8 @@
"PP: Parsing PI\n");
#endif
xmlParsePI(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->instate = XML_PARSER_EPILOG;
} else if ((cur == '<') && (next == '!') &&
(ctxt->input->cur[2] == '-') && (ctxt->input->cur[3] == '-')) {
@@ -11207,6 +11254,8 @@
"PP: Parsing Comment\n");
#endif
xmlParseComment(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->instate = XML_PARSER_EPILOG;
} else if ((cur == '<') && (next == '!') &&
(avail < 4)) {
@@ -11335,6 +11384,8 @@
found_end_int_subset:
xmlParseInternalSubset(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->inSubset = 2;
if ((ctxt->sax != NULL) && (!ctxt->disableSAX) &&
(ctxt->sax->externalSubset != NULL))
@@ -11342,6 +11393,8 @@
ctxt->extSubSystem, ctxt->extSubURI);
ctxt->inSubset = 0;
xmlCleanSpecialAttr(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ goto done;
ctxt->instate = XML_PARSER_PROLOG;
ctxt->checkIndex = 0;
#ifdef DEBUG_PUSH
@@ -11514,6 +11567,11 @@
}
if ((ctxt->errNo != XML_ERR_OK) && (ctxt->disableSAX == 1))
return(ctxt->errNo);
+
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(ctxt->errNo);
+
+
if (terminate) {
/*
* Check for termination
@@ -11694,6 +11752,7 @@
if (ctxt == NULL)
return;
ctxt->instate = XML_PARSER_EOF;
+ ctxt->errNo = XML_ERR_USER_STOP;
ctxt->disableSAX = 1;
if (ctxt->input != NULL) {
ctxt->input->cur = BAD_CAST"";
@@ -12399,6 +12458,8 @@
ctxt->depth = depth;
xmlParseContent(ctxt);
+ if (ctxt->instate == XML_PARSER_EOF)
+ return(-1);
if ((RAW == '<') && (NXT(1) == '/')) {
xmlFatalErr(ctxt, XML_ERR_NOT_WELL_BALANCED, NULL);