| 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;
|
|
|