You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by mr...@apache.org on 2004/08/16 03:05:01 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/impl/msg XIncludeMessages.properties

mrglavas    2004/08/15 18:05:01

  Modified:    java/src/org/apache/xerces/xinclude XIncludeHandler.java
               java/src/org/apache/xerces/impl/msg
                        XIncludeMessages.properties
  Log:
  The XInclude 1.0 CR [1] states that: "It is a fatal error to attempt to
  replace an xi:include element appearing as the document (top-level)
  element in the source infoset with something other than a list of zero
  or more comments, zero or more processing instructions, and one
  element."
  
  We were allowing merged infosets with multiple or no root elements
  to pass through as well as those containing non-whitespace
  characters and unexpanded entity references outside of the root.
  This should be fixed for now except for an edge case involving
  text includes.
  
  [1] http://www.w3.org/TR/xinclude/#creating-result
  
  Revision  Changes    Path
  1.34      +105 -37   xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java
  
  Index: XIncludeHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/xinclude/XIncludeHandler.java,v
  retrieving revision 1.33
  retrieving revision 1.34
  diff -u -r1.33 -r1.34
  --- XIncludeHandler.java	13 Aug 2004 19:15:30 -0000	1.33
  +++ XIncludeHandler.java	16 Aug 2004 01:05:01 -0000	1.34
  @@ -35,6 +35,7 @@
   import org.apache.xerces.util.URI;
   import org.apache.xerces.util.XMLAttributesImpl;
   import org.apache.xerces.util.XMLResourceIdentifierImpl;
  +import org.apache.xerces.util.XMLChar;
   import org.apache.xerces.util.XMLSymbols;
   import org.apache.xerces.util.URI.MalformedURIException;
   import org.apache.xerces.xni.Augmentations;
  @@ -273,9 +274,12 @@
       // used for passing features on to child XIncludeHandler objects
       protected ParserConfigurationSettings fSettings;
   
  -    // The current element depth.  We start at depth 0 (before we've reached any elements)
  +    // The current element depth.  We start at depth 0 (before we've reached any elements).
       // The first element is at depth 1.
       private int fDepth;
  +    
  +    // The current element depth of the result infoset.
  +    private int fResultDepth;
   
       // this value must be at least 1
       private static final int INITIAL_SIZE = 8;
  @@ -307,6 +311,9 @@
   
       // track whether a DTD is being parsed
       private boolean fInDTD;
  +    
  +    // track whether the root element of the result infoset has been processed
  +    private boolean fSeenRootElement;
   
       // Constructors
   
  @@ -336,11 +343,13 @@
           throws XNIException {
           fNamespaceContext = null;
           fDepth = 0;
  +        fResultDepth = 0;
           fNotations = new Vector();
           fUnparsedEntities = new Vector();
           fParentRelativeURI = null;
           fIsXML11 = false;
           fInDTD = false;
  +        fSeenRootElement = false;
   
           fBaseURIScope.clear();
           fBaseURI.clear();
  @@ -786,19 +795,26 @@
                       "FallbackChild",
                       new Object[] { element.rawname });
               }
  -            if (fDocumentHandler != null
  -                    && getState() == STATE_NORMAL_PROCESSING) {
  +            if (getState() == STATE_NORMAL_PROCESSING) {
  +                if (fResultDepth++ == 0 && isRootDocument()) {
  +                    checkMultipleRootElements();
  +                }
  +                if (fDocumentHandler != null) {
  +                    augs = modifyAugmentations(augs);
  +                    attributes = processAttributes(attributes);
  +                    fDocumentHandler.startElement(element, attributes, augs);
  +                }            
  +            }
  +        }
  +        else if (getState() == STATE_NORMAL_PROCESSING) {
  +            if (fResultDepth++ == 0 && isRootDocument()) {
  +                checkMultipleRootElements();
  +            }
  +            if (fDocumentHandler != null) {
                   augs = modifyAugmentations(augs);
                   attributes = processAttributes(attributes);
                   fDocumentHandler.startElement(element, attributes, augs);
  -            }
  -        }
  -        else if (
  -            fDocumentHandler != null
  -                && getState() == STATE_NORMAL_PROCESSING) {
  -            augs = modifyAugmentations(augs);
  -            attributes = processAttributes(attributes);
  -            fDocumentHandler.startElement(element, attributes, augs);
  +            }            
           }
       }
   
  @@ -838,20 +854,27 @@
                       "FallbackChild",
                       new Object[] { element.rawname });
               }
  -            if (fDocumentHandler != null
  -                    && getState() == STATE_NORMAL_PROCESSING) {
  +            if (getState() == STATE_NORMAL_PROCESSING) {
  +                if (fResultDepth == 0 && isRootDocument()) {
  +                    checkMultipleRootElements();
  +                }
  +                if (fDocumentHandler != null) {
  +                    augs = modifyAugmentations(augs);
  +                    attributes = processAttributes(attributes);
  +                    fDocumentHandler.emptyElement(element, attributes, augs);
  +                }
  +            }
  +        }
  +        else if (getState() == STATE_NORMAL_PROCESSING) {
  +            if (fResultDepth == 0 && isRootDocument()) {
  +                checkMultipleRootElements();
  +            }
  +            if (fDocumentHandler != null) {
                   augs = modifyAugmentations(augs);
                   attributes = processAttributes(attributes);
                   fDocumentHandler.emptyElement(element, attributes, augs);
               }
           }
  -        else if (
  -            fDocumentHandler != null
  -                && getState() == STATE_NORMAL_PROCESSING) {
  -            augs = modifyAugmentations(augs);
  -            attributes = processAttributes(attributes);
  -            fDocumentHandler.emptyElement(element, attributes, augs);
  -        }
           // reset the out of scope stack elements
           setSawFallback(fDepth + 1, false);
           setSawInclude(fDepth + 1, false);
  @@ -885,6 +908,7 @@
           else if (
               fDocumentHandler != null
                   && getState() == STATE_NORMAL_PROCESSING) {
  +            --fResultDepth;
               fDocumentHandler.endElement(element, augs);
           }
   
  @@ -913,9 +937,15 @@
           String encoding,
           Augmentations augs)
           throws XNIException {
  -        if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  -            fDocumentHandler.startGeneralEntity(name, resId, encoding, augs);
  +        if (getState() == STATE_NORMAL_PROCESSING) {
  +            if (fResultDepth == 0 && isRootDocument()) {
  +                if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
  +                    reportFatalError("UnexpandedEntityReferenceIllegal");
  +                }
  +            }
  +            else if (fDocumentHandler != null) {
  +                fDocumentHandler.startGeneralEntity(name, resId, encoding, augs);
  +            }
           }
       }
   
  @@ -930,48 +960,61 @@
       public void endGeneralEntity(String name, Augmentations augs)
           throws XNIException {
           if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  +            && getState() == STATE_NORMAL_PROCESSING
  +            && (fResultDepth != 0 || !isRootDocument())) {
               fDocumentHandler.endGeneralEntity(name, augs);
           }
       }
   
       public void characters(XMLString text, Augmentations augs)
           throws XNIException {
  -        if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  -            // we need to change the depth like this so that modifyAugmentations() works
  -            fDepth++;
  -            augs = modifyAugmentations(augs);
  -            fDocumentHandler.characters(text, augs);
  -            fDepth--;
  +        if (getState() == STATE_NORMAL_PROCESSING) {
  +            if (fResultDepth == 0 && isRootDocument()) {
  +                checkWhitespace(text);
  +            }
  +            else if (fDocumentHandler != null) {
  +                // we need to change the depth like this so that modifyAugmentations() works
  +                fDepth++;
  +                augs = modifyAugmentations(augs);
  +                fDocumentHandler.characters(text, augs);
  +                fDepth--;
  +            }
           }
       }
   
       public void ignorableWhitespace(XMLString text, Augmentations augs)
           throws XNIException {
           if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  +            && getState() == STATE_NORMAL_PROCESSING
  +            && (fResultDepth != 0 || !isRootDocument())) {
               fDocumentHandler.ignorableWhitespace(text, augs);
           }
       }
   
       public void startCDATA(Augmentations augs) throws XNIException {
           if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  +            && getState() == STATE_NORMAL_PROCESSING
  +            && (fResultDepth != 0 || !isRootDocument())) {
               fDocumentHandler.startCDATA(augs);
           }
       }
   
       public void endCDATA(Augmentations augs) throws XNIException {
           if (fDocumentHandler != null
  -            && getState() == STATE_NORMAL_PROCESSING) {
  +            && getState() == STATE_NORMAL_PROCESSING
  +            && (fResultDepth != 0 || !isRootDocument())) {
               fDocumentHandler.endCDATA(augs);
           }
       }
   
       public void endDocument(Augmentations augs) throws XNIException {
  -        if (isRootDocument() && fDocumentHandler != null) {
  -            fDocumentHandler.endDocument(augs);
  +        if (isRootDocument()) {
  +            if (!fSeenRootElement) {
  +                reportFatalError("RootElementRequired");
  +            }
  +            if (fDocumentHandler != null) {
  +                fDocumentHandler.endDocument(augs);
  +            }
           }
       }
   
  @@ -2174,6 +2217,31 @@
           else {
               fParentXIncludeHandler.checkAndSendNotation(not);
           }
  +    }
  +    
  +    /**
  +     * Checks whether the string only contains white space characters.
  +     * 
  +     * @param value the text to check
  +     */
  +    private void checkWhitespace(XMLString value) {
  +        int end = value.offset + value.length;
  +        for (int i = value.offset; i < end; ++i) {
  +            if (!XMLChar.isSpace(value.ch[i])) {
  +                reportFatalError("ContentIllegalAtTopLevel");
  +                return;
  +            }
  +        }
  +    }
  +    
  +    /**
  +     * Checks whether the root element has already been processed.
  +     */
  +    private void checkMultipleRootElements() {
  +        if (fSeenRootElement) {
  +            reportFatalError("MultipleRootElements");
  +        }
  +        fSeenRootElement = true;
       }
   
       // It would be nice if we didn't have to repeat code like this, but there's no interface that has
  
  
  
  1.10      +4 -0      xml-xerces/java/src/org/apache/xerces/impl/msg/XIncludeMessages.properties
  
  Index: XIncludeMessages.properties
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/msg/XIncludeMessages.properties,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- XIncludeMessages.properties	20 Jul 2004 04:09:26 -0000	1.9
  +++ XIncludeMessages.properties	16 Aug 2004 01:05:01 -0000	1.10
  @@ -19,6 +19,10 @@
   XpointerMissing = xpointer attribute must be present when href attribute is absent.
   AcceptMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept' attribute of an 'include' element.
   AcceptLanguageMalformed = Characters outside the range #x20 through #x7E are not allowed in the value of the 'accept-language' attribute of an 'include' element.
  +RootElementRequired = The root element is required in a well-formed document.
  +MultipleRootElements = A well-formed document must not contain multiple root elements.
  +ContentIllegalAtTopLevel = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain characters.
  +UnexpandedEntityReferenceIllegal = The replacement of an 'include' element appearing as the document element in the top-level source infoset cannot contain unexpanded entity references.
   
   # Messages from erroneous set-up
   IncompatibleNamespaceContext = The type of the NamespaceContext is incompatible with using XInclude; it must be an instance of XIncludeNamespaceSupport
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org