added a recovery mode for the HTML parser based on the suggestions of bug
* HTMLparser.c include/libxml/HTMLparser.h: added a recovery mode
for the HTML parser based on the suggestions of bug #169834 by
Paul Loberg
Daniel
diff --git a/ChangeLog b/ChangeLog
index 42746c6..c3a9cb9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Tue Aug 23 18:04:08 CEST 2005 Daniel Veillard <daniel@veillard.com>
+
+ * HTMLparser.c include/libxml/HTMLparser.h: added a recovery mode
+ for the HTML parser based on the suggestions of bug #169834 by
+ Paul Loberg
+
Tue Aug 23 15:38:46 CEST 2005 Daniel Veillard <daniel@veillard.com>
* elfgcchack.h testapi.c doc/*: regenerated
diff --git a/HTMLparser.c b/HTMLparser.c
index 0ea0f9c..fe36c89 100644
--- a/HTMLparser.c
+++ b/HTMLparser.c
@@ -2651,15 +2651,34 @@
cur = CUR_CHAR(l);
continue;
} else if ((cur == '<') && (NXT(1) == '/')) {
- /*
- * One should break here, the specification is clear:
- * Authors should therefore escape "</" within the content.
- * Escape mechanisms are specific to each scripting or
- * style sheet language.
- */
- if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
- ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
- break; /* while */
+ /*
+ * One should break here, the specification is clear:
+ * Authors should therefore escape "</" within the content.
+ * Escape mechanisms are specific to each scripting or
+ * style sheet language.
+ *
+ * In recovery mode, only break if end tag match the
+ * current tag, effectively ignoring all tags inside the
+ * script/style block and treating the entire block as
+ * CDATA.
+ */
+ if (ctxt->recovery) {
+ if (xmlStrncasecmp(ctxt->name, ctxt->input->cur+2,
+ xmlStrlen(ctxt->name)) == 0)
+ {
+ break; /* while */
+ } else {
+ htmlParseErr(ctxt, XML_ERR_TAG_NAME_MISMATCH,
+ "Element %s embbeds close tag\n",
+ ctxt->name, NULL);
+ }
+ } else {
+ if (((NXT(2) >= 'A') && (NXT(2) <= 'Z')) ||
+ ((NXT(2) >= 'a') && (NXT(2) <= 'z')))
+ {
+ break; /* while */
+ }
+ }
}
COPY_BUF(l,buf,nbchar,cur);
if (nbchar >= HTML_PARSER_BIG_BUFFER_SIZE) {
@@ -2676,6 +2695,7 @@
NEXTL(l);
cur = CUR_CHAR(l);
}
+
if (!(IS_CHAR_CH(cur))) {
htmlParseErrInt(ctxt, XML_ERR_INVALID_CHAR,
"Invalid char in CDATA 0x%X\n", cur);
@@ -3580,6 +3600,15 @@
if ((!IS_CHAR_CH(CUR)) || (CUR != '>')) {
htmlParseErr(ctxt, XML_ERR_GT_REQUIRED,
"End tag : expected '>'\n", NULL, NULL);
+ if (ctxt->recovery) {
+ /*
+ * We're not at the ending > !!
+ * Error, unless in recover mode where we search forwards
+ * until we find a >
+ */
+ while (CUR != '\0' && CUR != '>') NEXT;
+ NEXT;
+ }
} else
NEXT;
@@ -5787,6 +5816,10 @@
ctxt->options |= XML_PARSE_NOBLANKS;
} else
ctxt->keepBlanks = 1;
+ if (options & HTML_PARSE_RECOVER) {
+ ctxt->recovery = 1;
+ } else
+ ctxt->recovery = 0;
ctxt->dictNames = 0;
return (options);
}
diff --git a/include/libxml/HTMLparser.h b/include/libxml/HTMLparser.h
index 2604d86..2c1e8d2 100644
--- a/include/libxml/HTMLparser.h
+++ b/include/libxml/HTMLparser.h
@@ -173,6 +173,7 @@
* to the xmlReadDoc() and similar calls.
*/
typedef enum {
+ HTML_PARSE_RECOVER = 1<<0, /* Relaxed parsing */
HTML_PARSE_NOERROR = 1<<5, /* suppress error reports */
HTML_PARSE_NOWARNING= 1<<6, /* suppress warning reports */
HTML_PARSE_PEDANTIC = 1<<7, /* pedantic error reporting */