Index: third_party/libxml/src/parser.c |
diff --git a/third_party/libxml/src/parser.c b/third_party/libxml/src/parser.c |
index 978a58537b6d3a33697241ef067b886374356f8b..53a6b7f0c961a9ead7811e66acbdcacf79eee895 100644 |
--- a/third_party/libxml/src/parser.c |
+++ b/third_party/libxml/src/parser.c |
@@ -138,14 +138,20 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, |
* entities problems |
*/ |
if ((ent != NULL) && (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) && |
- (ent->content != NULL) && (ent->checked == 0)) { |
+ (ent->content != NULL) && (ent->checked == 0) && |
+ (ctxt->errNo != XML_ERR_ENTITY_LOOP)) { |
unsigned long oldnbent = ctxt->nbentities; |
xmlChar *rep; |
ent->checked = 1; |
+ ++ctxt->depth; |
rep = xmlStringDecodeEntities(ctxt, ent->content, |
XML_SUBSTITUTE_REF, 0, 0, 0); |
+ --ctxt->depth; |
+ if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { |
+ ent->content[0] = 0; |
+ } |
ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; |
if (rep != NULL) { |
@@ -344,7 +350,6 @@ static void |
xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) |
{ |
const char *errmsg; |
- char errstr[129] = ""; |
if ((ctxt != NULL) && (ctxt->disableSAX != 0) && |
(ctxt->instate == XML_PARSER_EOF)) |
@@ -531,15 +536,17 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) |
default: |
errmsg = "Unregistered error message"; |
} |
- if (info == NULL) |
- snprintf(errstr, 128, "%s\n", errmsg); |
- else |
- snprintf(errstr, 128, "%s: %%s\n", errmsg); |
if (ctxt != NULL) |
ctxt->errNo = error; |
- __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, |
- XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, &errstr[0], |
- info); |
+ if (info == NULL) { |
+ __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, |
+ XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n", |
+ errmsg); |
+ } else { |
+ __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error, |
+ XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n", |
+ errmsg, info); |
+ } |
if (ctxt != NULL) { |
ctxt->wellFormed = 0; |
if (ctxt->recovery == 0) |
@@ -555,7 +562,7 @@ xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info) |
* |
* Handle a fatal parser error, i.e. violating Well-Formedness constraints |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg) |
{ |
@@ -583,7 +590,7 @@ xmlFatalErrMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a warning. |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, const xmlChar *str1, const xmlChar *str2) |
{ |
@@ -621,7 +628,7 @@ xmlWarningMsg(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a validity error. |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, const xmlChar *str1, const xmlChar *str2) |
{ |
@@ -661,7 +668,7 @@ xmlValidityError(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a fatal parser error, i.e. violating Well-Formedness constraints |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, int val) |
{ |
@@ -691,7 +698,7 @@ xmlFatalErrMsgInt(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a fatal parser error, i.e. violating Well-Formedness constraints |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, const xmlChar *str1, int val, |
const xmlChar *str2) |
@@ -721,7 +728,7 @@ xmlFatalErrMsgStrIntStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a fatal parser error, i.e. violating Well-Formedness constraints |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, const xmlChar * val) |
{ |
@@ -750,7 +757,7 @@ xmlFatalErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a non fatal parser error |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, const xmlChar * val) |
{ |
@@ -775,7 +782,7 @@ xmlErrMsgStr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a fatal parser error, i.e. violating Well-Formedness constraints |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, |
const xmlChar * info1, const xmlChar * info2, |
@@ -804,7 +811,7 @@ xmlNsErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
* |
* Handle a namespace warning error |
*/ |
-static void |
+static void LIBXML_ATTR_FORMAT(3,0) |
xmlNsWarn(xmlParserCtxtPtr ctxt, xmlParserErrors error, |
const char *msg, |
const xmlChar * info1, const xmlChar * info2, |
@@ -2008,6 +2015,7 @@ static int spacePop(xmlParserCtxtPtr ctxt) { |
#define CUR (*ctxt->input->cur) |
#define NXT(val) ctxt->input->cur[(val)] |
#define CUR_PTR ctxt->input->cur |
+#define BASE_PTR ctxt->input->base |
#define CMP4( s, c1, c2, c3, c4 ) \ |
( ((unsigned char *) s)[ 0 ] == c1 && ((unsigned char *) s)[ 1 ] == c2 && \ |
@@ -2858,7 +2866,21 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, |
ctxt->nbentities += ent->checked / 2; |
if (ent != NULL) { |
if (ent->content == NULL) { |
- xmlLoadEntityContent(ctxt, ent); |
+ /* |
+ * Note: external parsed entities will not be loaded, |
+ * it is not required for a non-validating parser to |
+ * complete external PEreferences coming from the |
+ * internal subset |
+ */ |
+ if (((ctxt->options & XML_PARSE_NOENT) != 0) || |
+ ((ctxt->options & XML_PARSE_DTDVALID) != 0) || |
+ (ctxt->validate != 0)) { |
+ xmlLoadEntityContent(ctxt, ent); |
+ } else { |
+ xmlWarningMsg(ctxt, XML_ERR_ENTITY_PROCESSING, |
+ "not validating will not read content for PE entity %s\n", |
+ ent->name, NULL); |
+ } |
} |
ctxt->depth++; |
rep = xmlStringDecodeEntities(ctxt, ent->content, what, |
@@ -3470,7 +3492,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { |
int len = 0, l; |
int c; |
int count = 0; |
- const xmlChar *end; /* needed because CUR_CHAR() can move cur on \r\n */ |
+ size_t startPosition = 0; |
#ifdef DEBUG |
nbParseNCNameComplex++; |
@@ -3480,7 +3502,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { |
* Handler for more complex cases |
*/ |
GROW; |
- end = ctxt->input->cur; |
+ startPosition = CUR_PTR - BASE_PTR; |
c = CUR_CHAR(l); |
if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */ |
(!xmlIsNameStartChar(ctxt, c) || (c == ':'))) { |
@@ -3502,7 +3524,6 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { |
} |
len += l; |
NEXTL(l); |
- end = ctxt->input->cur; |
c = CUR_CHAR(l); |
if (c == 0) { |
count = 0; |
@@ -3516,7 +3537,6 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { |
ctxt->input->cur += l; |
if (ctxt->instate == XML_PARSER_EOF) |
return(NULL); |
- end = ctxt->input->cur; |
c = CUR_CHAR(l); |
} |
} |
@@ -3525,7 +3545,7 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { |
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "NCName"); |
return(NULL); |
} |
- return(xmlDictLookup(ctxt->dict, end - len, len)); |
+ return(xmlDictLookup(ctxt->dict, (BASE_PTR + startPosition), len)); |
} |
/** |
@@ -3966,8 +3986,10 @@ xmlParseEntityValue(xmlParserCtxtPtr ctxt, xmlChar **orig) { |
* an entity declaration, it is bypassed and left as is. |
* so XML_SUBSTITUTE_REF is not set here. |
*/ |
+ ++ctxt->depth; |
ret = xmlStringDecodeEntities(ctxt, buf, XML_SUBSTITUTE_PEREF, |
0, 0, 0); |
+ --ctxt->depth; |
if (orig != NULL) |
*orig = buf; |
else |
@@ -4092,9 +4114,11 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { |
} else if ((ent != NULL) && |
(ctxt->replaceEntities != 0)) { |
if (ent->etype != XML_INTERNAL_PREDEFINED_ENTITY) { |
+ ++ctxt->depth; |
rep = xmlStringDecodeEntities(ctxt, ent->content, |
XML_SUBSTITUTE_REF, |
0, 0, 0); |
+ --ctxt->depth; |
if (rep != NULL) { |
current = rep; |
while (*current != 0) { /* non input consuming */ |
@@ -4130,8 +4154,10 @@ xmlParseAttValueComplex(xmlParserCtxtPtr ctxt, int *attlen, int normalize) { |
(ent->content != NULL) && (ent->checked == 0)) { |
unsigned long oldnbent = ctxt->nbentities; |
+ ++ctxt->depth; |
rep = xmlStringDecodeEntities(ctxt, ent->content, |
XML_SUBSTITUTE_REF, 0, 0, 0); |
+ --ctxt->depth; |
ent->checked = (ctxt->nbentities - oldnbent + 1) * 2; |
if (rep != NULL) { |
@@ -5501,7 +5527,7 @@ xmlParseEntityDecl(xmlParserCtxtPtr ctxt) { |
skipped = SKIP_BLANKS; |
if (skipped == 0) { |
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, |
- "Space required after '%'\n"); |
+ "Space required after '%%'\n"); |
} |
isParameter = 1; |
} |
@@ -6686,6 +6712,7 @@ xmlParseElementDecl(xmlParserCtxtPtr ctxt) { |
if (!IS_BLANK_CH(CUR)) { |
xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED, |
"Space required after 'ELEMENT'\n"); |
+ return(-1); |
} |
SKIP_BLANKS; |
name = xmlParseName(ctxt); |
@@ -6837,6 +6864,7 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) { |
if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) { |
xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL); |
+ xmlHaltParser(ctxt); |
break; |
} |
} |
@@ -9466,7 +9494,10 @@ reparse: |
else |
if (nsPush(ctxt, NULL, URL) > 0) nbNs++; |
skip_default_ns: |
- if (alloc != 0) xmlFree(attvalue); |
+ if ((attvalue != NULL) && (alloc != 0)) { |
+ xmlFree(attvalue); |
+ attvalue = NULL; |
+ } |
if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) |
break; |
if (!IS_BLANK_CH(RAW)) { |
@@ -9475,6 +9506,8 @@ skip_default_ns: |
break; |
} |
SKIP_BLANKS; |
+ if ((ctxt->input->base != base) || (inputNr != ctxt->inputNr)) |
+ goto base_changed; |
continue; |
} |
if (aprefix == ctxt->str_xmlns) { |
@@ -9546,7 +9579,10 @@ skip_default_ns: |
else |
if (nsPush(ctxt, attname, URL) > 0) nbNs++; |
skip_ns: |
- if (alloc != 0) xmlFree(attvalue); |
+ if ((attvalue != NULL) && (alloc != 0)) { |
+ xmlFree(attvalue); |
+ attvalue = NULL; |
+ } |
if ((RAW == '>') || (((RAW == '/') && (NXT(1) == '>')))) |
break; |
if (!IS_BLANK_CH(RAW)) { |
@@ -9817,6 +9853,7 @@ static void |
xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, |
const xmlChar *URI, int line, int nsNr, int tlen) { |
const xmlChar *name; |
+ size_t curLength; |
GROW; |
if ((RAW != '<') || (NXT(1) != '/')) { |
@@ -9825,9 +9862,11 @@ xmlParseEndTag2(xmlParserCtxtPtr ctxt, const xmlChar *prefix, |
} |
SKIP(2); |
- size_t curLength = ctxt->input->end - ctxt->input->cur; |
- if ((tlen > 0) && (curLength >= (size_t)tlen) && (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) { |
- if ((curLength >= (size_t)(tlen + 1)) && (ctxt->input->cur[tlen] == '>')) { |
+ curLength = ctxt->input->end - ctxt->input->cur; |
+ if ((tlen > 0) && (curLength >= (size_t)tlen) && |
+ (xmlStrncmp(ctxt->input->cur, ctxt->name, tlen) == 0)) { |
+ if ((curLength >= (size_t)(tlen + 1)) && |
+ (ctxt->input->cur[tlen] == '>')) { |
ctxt->input->cur += tlen + 1; |
ctxt->input->col += tlen + 1; |
goto done; |