7148925: StAXSource causes exceptions to be thrown with certain wellformed XML instances
authorjoehw
Wed, 10 Jul 2019 16:45:28 +0000
changeset 55648 ba72dac556c3
parent 55647 f60890de1dfb
child 55649 ad8e3b295615
7148925: StAXSource causes exceptions to be thrown with certain wellformed XML instances Reviewed-by: lancea
src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java
test/jaxp/javax/xml/jaxp/unittest/transform/StAXSourceTest.java
--- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java	Tue Jul 02 08:43:44 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java	Wed Jul 10 16:45:28 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,25 +119,41 @@
         try {
             // remembers the nest level of elements to know when we are done.
             int depth=0;
+            boolean startedAtDocument = false;
 
             // skip over START_DOCUMENT
             int event = staxStreamReader.getEventType();
             if (event == XMLStreamConstants.START_DOCUMENT) {
+                startedAtDocument = true;
                 event = staxStreamReader.next();
             }
 
-            // If not a START_ELEMENT (e.g., a DTD), skip to next tag
-            if (event != XMLStreamConstants.START_ELEMENT) {
-                event = staxStreamReader.nextTag();
-                // An error if a START_ELEMENT isn't found now
-                if (event != XMLStreamConstants.START_ELEMENT) {
-                    throw new IllegalStateException("The current event is " +
-                            "not START_ELEMENT\n but" + event);
+            handleStartDocument();
+
+            // Handle the prolog: http://www.w3.org/TR/REC-xml/#NT-prolog
+            while (event != XMLStreamConstants.START_ELEMENT) {
+                switch (event) {
+                    case XMLStreamConstants.CHARACTERS :
+                        handleCharacters();
+                        break;
+                    case XMLStreamConstants.PROCESSING_INSTRUCTION :
+                        handlePI();
+                        break;
+                    case XMLStreamConstants.COMMENT :
+                        handleComment();
+                        break;
+                    case XMLStreamConstants.DTD :
+                        handleDTD();
+                        break;
+                    case XMLStreamConstants.SPACE :
+                        handleSpace();
+                        break;
+                    default :
+                        throw new InternalError("processing prolog event: " + event);
                 }
+                event=staxStreamReader.next();
             }
 
-            handleStartDocument();
-
             do {
                 // These are all of the events listed in the javadoc for
                 // XMLEvent.
@@ -191,6 +207,29 @@
                 event=staxStreamReader.next();
             } while (depth!=0);
 
+            if (startedAtDocument) {
+                // Handle the Misc (http://www.w3.org/TR/REC-xml/#NT-Misc) that can follow the document element
+                while (event != XMLStreamConstants.END_DOCUMENT) {
+                    switch (event) {
+                        case XMLStreamConstants.CHARACTERS :
+                            handleCharacters();
+                            break;
+                        case XMLStreamConstants.PROCESSING_INSTRUCTION :
+                            handlePI();
+                            break;
+                        case XMLStreamConstants.COMMENT :
+                            handleComment();
+                            break;
+                        case XMLStreamConstants.SPACE :
+                            handleSpace();
+                            break;
+                        default :
+                            throw new InternalError("processing misc event after document element: " + event);
+                    }
+                    event=staxStreamReader.next();
+                }
+            }
+
             handleEndDocument();
         } catch (SAXException e) {
             throw new XMLStreamException(e);
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/StAXSourceTest.java	Tue Jul 02 08:43:44 2019 -0700
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/StAXSourceTest.java	Wed Jul 10 16:45:28 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 package transform;
 
+import java.io.ByteArrayInputStream;
 import static jaxp.library.JAXPTestUtilities.setSystemProperty;
 import java.io.StringReader;
 import java.io.StringWriter;
@@ -33,6 +34,8 @@
 import javax.xml.stream.XMLStreamConstants;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
@@ -41,14 +44,16 @@
 import javax.xml.transform.stax.StAXResult;
 import javax.xml.transform.stax.StAXSource;
 import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
 
 import org.testng.Assert;
+import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;
 import org.testng.annotations.Test;
 
 /*
  * @test
- * @bug 8152530 8202426
+ * @bug 8152530 8202426 7148925
  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  * @modules java.xml
  * @modules java.xml/com.sun.org.apache.xerces.internal.impl
@@ -62,6 +67,100 @@
  */
 @Listeners({jaxp.library.JAXPTestPolicy.class})
 public class StAXSourceTest {
+    @DataProvider(name = "xml")
+    public Object[][] getData() throws Exception {
+        // from 6715417, all other data were from 7148925
+        String xmlDT = "<?xml version=\"1.0\" encoding=\"utf-8\"?> "
+                + "<!DOCTYPE bookstore [ "
+                + "<!ELEMENT bookstore (book)*> "
+                + "<!ELEMENT book (title,author,price)> "
+                + "<!ATTLIST book genre CDATA #REQUIRED> "
+                + "<!ELEMENT title (#PCDATA)> "
+                + "<!ELEMENT author (#PCDATA)> "
+                + "<!ELEMENT price (#PCDATA)> ]> "
+                + "<bookstore> "
+                + "<book genre=\"fantasy\" > "
+                + "<title>Oberon's Legacy</title> "
+                + "<author>Corets, Eva</author> "
+                + "<price>5.95</price> "
+                + "</book> "
+                + "</bookstore>";
+        return new Object[][]{
+            {"<root/>"},
+            {"<!DOCTYPE root [<!ENTITY et 'Come Home'>]><root et='&et;'/>"},
+            {"<?xml-stylesheet href='show.xsl' type='text/html'?><root/>"},
+            {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?><root/>"},
+            {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?>"
+                + "<!DOCTYPE root><root/>"},
+            {"<?xml version='1.0'?><!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>"},
+            {"<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?>"
+                + "<!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>"},
+            {xmlDT},
+        };
+    }
+
+    /**
+     * @bug 7148925 6715417
+     *
+     * Verifies that the transformation is successful with a StreamSource.
+     *
+     * @param xml the xml
+     * @throws Exception if the test fails
+     */
+    @Test(dataProvider = "xml")
+    public void parseStreamSource(String xml) throws Exception {
+        Source source = new StreamSource(new StringReader(xml));
+        transform(source, xml);
+    }
+
+    /**
+     * @bug 7148925 6715417
+     *
+     * Verifies that the transformation is successful with a StAXSource created
+     * out of a StreamReader.
+     *
+     * Note that the patch fixes the Exception, but does not include any improvement
+     * over the current. The result may differ from that of StreamSource.
+     *
+     * @param xml the xml
+     * @throws Exception if the test fails
+     */
+    @Test(dataProvider = "xml")
+    public void parseSSSR(String xml) throws Exception {
+        XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
+        XMLStreamReader sr = xif.createXMLStreamReader(new StringReader(xml));
+        StAXSource source = new StAXSource(sr);
+        transform(source, xml);
+    }
+
+    /**
+     * @bug 7148925 6715417
+     *
+     * Verifies that the transformation is successful with a StAXSource created
+     * out of an EventReader.
+     *
+     * Note that the patch fixes the Exception, but does not include any improvement
+     * over the current. The result may differ from that of StreamSource.
+     *
+     * @param xml the xml
+     * @throws Exception if the test fails
+     */
+    @Test(dataProvider = "xml")
+    public void parseSSER(String xml) throws Exception {
+        XMLInputFactory xif = XMLInputFactory.newDefaultFactory();
+        XMLEventReader er = xif.createXMLEventReader(new StringReader(xml));
+        StAXSource source = new StAXSource(er);
+        transform(source, xml);
+    }
+
+    private void transform(Source source, String sourceXml) throws Exception{
+        StringWriter sw = new StringWriter();
+        Result result = new StreamResult(sw);
+        TransformerFactory tf = TransformerFactory.newInstance();
+        tf.newTransformer().transform(source, result);
+        System.out.printf("%n%s:%nSource: %s%nResult: %s%n", source.getClass().getSimpleName(), sourceXml, sw);
+    }
+
     /**
      * @bug 8202426
      * Verifies that a null Attribute type is handled. NPE was thrown before the fix.