[libxml2] Fix parser progress checks



commit 7d02c7291f5c0ba56b9d8c04af7690cf11e47f07
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Sun Mar 6 00:49:02 2022 +0100

    Fix parser progress checks
    
    Testing the current input pointer for modification is unreliable since
    the input buffer could have been freed and realloced. Check whether the
    input id and the up-to-date number of bytes consumed match.

 parser.c | 49 ++++++++++++++++++++++++++-----------------------
 1 file changed, 26 insertions(+), 23 deletions(-)
---
diff --git a/parser.c b/parser.c
index 3a5da54f..c3068cad 100644
--- a/parser.c
+++ b/parser.c
@@ -2167,6 +2167,9 @@ static void xmlGROW (xmlParserCtxtPtr ctxt) {
     if (l == 1) b[i++] = (xmlChar) v;                                  \
     else i += xmlCopyCharMultiByte(&b[i],v)
 
+#define CUR_CONSUMED \
+    (ctxt->input->consumed + (ctxt->input->cur - ctxt->input->base))
+
 /**
  * xmlSkipBlankChars:
  * @ctxt:  the XML parser context
@@ -6804,12 +6807,12 @@ xmlParseConditionalSections(xmlParserCtxtPtr ctxt) {
             }
             SKIP(3);
         } else {
-            const xmlChar *check = CUR_PTR;
-            unsigned int cons = ctxt->input->consumed;
+            int id = ctxt->input->id;
+            unsigned long cons = CUR_CONSUMED;
 
             xmlParseMarkupDecl(ctxt);
 
-            if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+            if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
                 xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
                 xmlHaltParser(ctxt);
                 goto error;
@@ -7028,8 +7031,8 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
     while (((RAW == '<') && (NXT(1) == '?')) ||
            ((RAW == '<') && (NXT(1) == '!')) ||
           (RAW == '%')) {
-       const xmlChar *check = CUR_PTR;
-       unsigned int cons = ctxt->input->consumed;
+       int id = ctxt->input->id;
+       unsigned long cons = CUR_CONSUMED;
 
        GROW;
         if ((RAW == '<') && (NXT(1) == '!') && (NXT(2) == '[')) {
@@ -7038,7 +7041,7 @@ xmlParseExternalSubset(xmlParserCtxtPtr ctxt, const xmlChar *ExternalID,
            xmlParseMarkupDecl(ctxt);
         SKIP_BLANKS;
 
-       if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+       if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
            xmlFatalErr(ctxt, XML_ERR_EXT_SUBSET_NOT_FINISHED, NULL);
            break;
        }
@@ -8349,8 +8352,8 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
         */
        while (((RAW != ']') || (ctxt->inputNr > baseInputNr)) &&
                (ctxt->instate != XML_PARSER_EOF)) {
-           const xmlChar *check = CUR_PTR;
-           unsigned int cons = ctxt->input->consumed;
+           int id = ctxt->input->id;
+           unsigned long cons = CUR_CONSUMED;
 
            SKIP_BLANKS;
            xmlParseMarkupDecl(ctxt);
@@ -8365,7 +8368,7 @@ xmlParseInternalSubset(xmlParserCtxtPtr ctxt) {
                 xmlParseConditionalSections(ctxt);
             }
 
-           if ((CUR_PTR == check) && (cons == ctxt->input->consumed)) {
+           if ((id == ctxt->input->id) && (cons == CUR_CONSUMED)) {
                xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
             "xmlParseInternalSubset: error detected in Markup declaration\n");
                 if (ctxt->inputNr > baseInputNr)
@@ -8544,8 +8547,8 @@ xmlParseStartTag(xmlParserCtxtPtr ctxt) {
     while (((RAW != '>') &&
           ((RAW != '/') || (NXT(1) != '>')) &&
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
-       const xmlChar *q = CUR_PTR;
-       unsigned int cons = ctxt->input->consumed;
+        int id = ctxt->input->id;
+       unsigned long cons = CUR_CONSUMED;
 
        attname = xmlParseAttribute(ctxt, &attvalue);
         if ((attname != NULL) && (attvalue != NULL)) {
@@ -8610,7 +8613,7 @@ failed:
            xmlFatalErrMsg(ctxt, XML_ERR_SPACE_REQUIRED,
                           "attributes construct error\n");
        }
-        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
+        if ((cons == CUR_CONSUMED) && (id == ctxt->input->id) &&
             (attname == NULL) && (attvalue == NULL)) {
            xmlFatalErrMsg(ctxt, XML_ERR_INTERNAL_ERROR,
                           "xmlParseStartTag: problem parsing attributes\n");
@@ -9294,8 +9297,8 @@ xmlParseStartTag2(xmlParserCtxtPtr ctxt, const xmlChar **pref,
     while (((RAW != '>') &&
           ((RAW != '/') || (NXT(1) != '>')) &&
           (IS_BYTE_CHAR(RAW))) && (ctxt->instate != XML_PARSER_EOF)) {
-       const xmlChar *q = CUR_PTR;
-       unsigned int cons = ctxt->input->consumed;
+       int id = ctxt->input->id;
+       unsigned long cons = CUR_CONSUMED;
        int len = -1, alloc = 0;
 
        attname = xmlParseAttribute2(ctxt, prefix, localname,
@@ -9476,7 +9479,7 @@ next_attr:
                           "attributes construct error\n");
            break;
        }
-        if ((cons == ctxt->input->consumed) && (q == CUR_PTR) &&
+        if ((cons == CUR_CONSUMED) && (id == ctxt->input->id) &&
             (attname == NULL) && (attvalue == NULL)) {
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                 "xmlParseStartTag: problem parsing attributes\n");
@@ -9860,8 +9863,8 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
     GROW;
     while ((RAW != 0) &&
           (ctxt->instate != XML_PARSER_EOF)) {
-       const xmlChar *test = CUR_PTR;
-       unsigned int cons = ctxt->input->consumed;
+        int id = ctxt->input->id;
+       unsigned long cons = CUR_CONSUMED;
        const xmlChar *cur = ctxt->input->cur;
 
        /*
@@ -9920,7 +9923,7 @@ xmlParseContentInternal(xmlParserCtxtPtr ctxt) {
        GROW;
        SHRINK;
 
-       if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
+       if ((cons == CUR_CONSUMED) && (id == ctxt->input->id)) {
            xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                        "detected an error in element content\n");
            xmlHaltParser(ctxt);
@@ -11515,15 +11518,15 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                 break;
            }
             case XML_PARSER_CONTENT: {
-               const xmlChar *test;
-               unsigned int cons;
+               int id;
+               unsigned long cons;
                if ((avail < 2) && (ctxt->inputNr == 1))
                    goto done;
                cur = ctxt->input->cur[0];
                next = ctxt->input->cur[1];
 
-               test = CUR_PTR;
-               cons = ctxt->input->consumed;
+               id = ctxt->input->id;
+               cons = CUR_CONSUMED;
                if ((cur == '<') && (next == '/')) {
                    ctxt->instate = XML_PARSER_END_TAG;
                    break;
@@ -11604,7 +11607,7 @@ xmlParseTryOrFinish(xmlParserCtxtPtr ctxt, int terminate) {
                    ctxt->checkIndex = 0;
                    xmlParseCharData(ctxt, 0);
                }
-               if ((cons == ctxt->input->consumed) && (test == CUR_PTR)) {
+               if ((cons == CUR_CONSUMED) && (id == ctxt->input->id)) {
                    xmlFatalErr(ctxt, XML_ERR_INTERNAL_ERROR,
                                "detected an error in element content\n");
                    xmlHaltParser(ctxt);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]