[xml] PEReference patch part 2 and (non-)future of ctxt->token



Hi Daniel, All,

Find attached the second step for correctly validating obscure uses of 
PEReferences. In addition it elimates the last (non-zero) assignments to 
ctxt->token, see discussion below.

What's the patch doing: when including a PEReference (other than in
an entity value), it doesn't set input to xmlNewEntityInputStream but
to newly defined xmlNewBlanksWrapperEntityStream. This consists
of a rewritten PEReference with spaces added at front and end. A test
whether the current input is already the from 
xmlNewBlanksWrapperEntityStream prevents infinite recursion.

The old ctxt->token = ' ' assignments which generate only one sided 
blank padding are removed.

One more test of IS_BLANK is replaced by skipped = xmlSkipBlanks(),
as the IS_BLANK macro doesn't pop input streams.

The attached t4a.xml and t4a.dtd are the test case which need this 
second part of the PEReference patch.

ctxt->token is obsolete now!

Apart from the two assignments eliminated by this patch, there are
only assignments of 0, and some relicts in parserinternals, which are
commented out.

So, in the context of further performance patches, I'm tempted to 
eliminate all uses of ctxt->token, which will help to streamline some 
code.

There is a stylistic issue to decide: with the elimination of ctxt->token
following four expressions are identical after preprocessing:

RAW
CUR
NXT(0)
*ctxt->input->current

Do you have a preference which of these to use in the future?

Regards,
Peter Jacobi


*** ..\temp\parser.c    Mon Jun 03 17:14:55 2002
--- parser.c    Tue Jun 04 16:29:46 2002
***************
*** 658,663 ****
--- 658,716 ----
      return(0);
  }
  
+ 
+ /**
+  * xmlNewBlanksWrapperInputStream:
+  * @ctxt:  an XML parser context
+  * @entity:  an Entity pointer
+  *
+  * Create a new input stream for wrapping
+  * blanks around a PEReference
+  *
+  * Returns the new input stream or NULL
+  */
+  
+ static void deallocblankswrapper (xmlChar *str) {xmlFree(str);}
+  
+ xmlParserInputPtr
+ xmlNewBlanksWrapperInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
+     xmlParserInputPtr input;
+     xmlChar *buffer;
+     size_t length;
+     if (entity == NULL) {
+         ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+         if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
+           ctxt->sax->error(ctxt->userData,
+             "internal: xmlNewBlanksWrapperInputStream entity = NULL\n");
+       ctxt->errNo = XML_ERR_INTERNAL_ERROR;
+       return(NULL);
+     }
+     if (xmlParserDebugEntities)
+       xmlGenericError(xmlGenericErrorContext,
+               "new blanks wrapper for entity: %s\n", entity->name);
+     input = xmlNewInputStream(ctxt);
+     if (input == NULL) {
+       return(NULL);
+     }
+     length = xmlStrlen(entity->name) + 5;
+     buffer = xmlMalloc(length);
+     if (buffer == NULL) {
+       return(NULL);
+     }
+     buffer [0] = ' ';
+     buffer [1] = '%';
+     buffer [length-3] = ';';
+     buffer [length-2] = ' ';
+     buffer [length-1] = 0;
+     memcpy(buffer + 2, entity->name, length - 5);
+     input->free = deallocblankswrapper;
+     input->base = buffer;
+     input->cur = buffer;
+     input->length = length;
+     input->end = &buffer[length];
+     return(input);
+ }
+ 
  /**
   * xmlParserHandlePEReference:
   * @ctxt:  the parser context
***************
*** 817,823 ****
--- 870,883 ----
                         "PEReference: %%%s; not found\n", name);
                    ctxt->valid = 0;
                }
+ 
+           } else if (ctxt->input->free != deallocblankswrapper) {
+ 
+                   input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+                   xmlPushInput(ctxt, input);
+ 
            } else {
+               
                if ((entity->etype == XML_INTERNAL_PARAMETER_ENTITY) ||
                    (entity->etype == XML_EXTERNAL_PARAMETER_ENTITY)) {
                    xmlChar start[4];
***************
*** 852,859 ****
                        (NXT(4) == 'l') && (IS_BLANK(NXT(5)))) {
                        xmlParseTextDecl(ctxt);
                    }
-                   if (ctxt->token == 0)
-                       ctxt->token = ' ';
                } else {
                    if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                        ctxt->sax->error(ctxt->userData,
--- 912,917 ----
***************
*** 3382,3388 ****
            ctxt->disableSAX = 1;
              return;
        }
!       if (!IS_BLANK(CUR)) {
            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                ctxt->sax->error(ctxt->userData,
--- 3440,3447 ----
            ctxt->disableSAX = 1;
              return;
        }
!       skipped = SKIP_BLANKS;
!       if (skipped == 0) {
            ctxt->errNo = XML_ERR_SPACE_REQUIRED;
            if ((ctxt->sax != NULL) && (ctxt->sax->error != NULL))
                ctxt->sax->error(ctxt->userData,
***************
*** 3390,3396 ****
            ctxt->wellFormed = 0;
            ctxt->disableSAX = 1;
        }
-         SKIP_BLANKS;
  
        /*
         * handle the various case of definitions...
--- 3449,3454 ----
***************
*** 5946,5951 ****
--- 6004,6012 ----
                             "PEReference: %%%s; not found\n", name);
                        ctxt->valid = 0;
                    }
+               } else if (ctxt->input->free != deallocblankswrapper) {
+                   input = xmlNewBlanksWrapperInputStream(ctxt, entity);
+                   xmlPushInput(ctxt, input);
                } else {
                    /*
                     * Internal checking in case the entity quest barfed
***************
*** 5978,5985 ****
                                return;
                            }
                        }
-                       if (ctxt->token == 0)
-                           ctxt->token = ' ';
                    }
                }
                ctxt->hasPErefs = 1;
--- 6039,6044 ----
<?xml version='1.0'?>
<!DOCTYPE root SYSTEM 't4a.dtd'>
<root>&abc;</root>
<!ENTITY % percent "&#x25;">
<!ENTITY%percent;def "ghi">
<!ENTITY abc "%def;">
<!ELEMENT root (#PCDATA)>



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