JDK-7148925 : StAXSource causes exceptions to be thrown with certain wellformed XML instances
  • Type: Bug
  • Component: xml
  • Sub-Component: javax.xml.stream
  • Affected Version: 6u20
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux_ubuntu
  • CPU: x86
  • Submitted: 2012-02-26
  • Updated: 2019-07-17
  • Resolved: 2019-07-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 14
14 b06Fixed
Related Reports
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
1.6.0_20
1.6.0_29
1.7.0_04_ea


ADDITIONAL OS VERSION INFORMATION :
Ubuntu Linux 10.04 - kernel 2.6.0.32
Mac OS-X, 7.0.2 - Darwin Kernel Version 11.2.0

A DESCRIPTION OF THE PROBLEM :
The following well formed XML instances cause XML transformation to throw exceptions when using javax.xml.transform.stax.StAXSource as a source (but not when using StreamSource).

Causes java.lang.IllegalStateException("StAXSource(XMLStreamReader) with XMLStreamReader not in XMLStreamConstants.START_DOCUMENT or XMLStreamConstants.START_ELEMENT state"):
<?xml-stylesheet href='show.xsl' type='text/html'?>
<root/>

Causes javax.xml.transform.TransformerException("ParseError at [row,col]:[1,105] Message: found: DTD, expected START_ELEMENT or END_ELEMENT"):
<?xml version='1.0'?>
<?xml-stylesheet href='show.xsl' type='text/html'?>
<!DOCTYPE root>
<root/>

Causes javax.xml.transform.TransformerException("ParseError at [row,col]:[1,105] Message: found: DTD, expected START_ELEMENT or END_ELEMENT"):
<?xml version='1.0'?>
<?xml-stylesheet href='show.xsl' type='text/html'?>
<!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]>
<root/>

Similar bug reported as Bug ID 6715417, but further details, and more failures are uncovered by the attached unit test.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached (self contained) JUnit tests: StaxSourceParsingBug.java
also available here: https://xml-extractor.googlecode.com/svn/trunk/src/test/java/org/softee/extractor/transform/StaxSourceParsingBug.java

Unit tests have also been included, that show that the same XML instances that cause execptions when using StAXSource all succeed when using StreamSource.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Attached JUnit tests should all pass
ACTUAL -
Attached JUnit tests fails:
org.softee.extractor.transform.StaxSourceParsingBug.testParseStaxSource3()
org.softee.extractor.transform.StaxSourceParsingBug.testParseStaxSource5()
org.softee.extractor.transform.StaxSourceParsingBug.testParseStaxSource7()

ERROR MESSAGES/STACK TRACES THAT OCCUR :
StaxSourceParsingBug.testParseStaxSource3():
java.lang.IllegalStateException: StAXSource(XMLStreamReader) with XMLStreamReadernot in XMLStreamConstants.START_DOCUMENT or XMLStreamConstants.START_ELEMENT state
	at javax.xml.transform.stax.StAXSource.<init>(StAXSource.java:155)
	at org.softee.extractor.transform.StaxSourceParsingBug.parseStaxSource(StaxSourceParsingBug.java:134)
	at org.softee.extractor.transform.StaxSourceParsingBug.testParseStaxSource3(StaxSourceParsingBug.java:93)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)


StaxSourceParsingBug.testParseStaxSource5():
javax.xml.transform.TransformerException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,88]
Message: found: DTD, expected START_ELEMENT or END_ELEMENT
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:739)
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:340)
	at org.softee.extractor.transform.StaxSourceParsingBug.unityTransform(StaxSourceParsingBug.java:141)
	at org.softee.extractor.transform.StaxSourceParsingBug.parseStaxSource(StaxSourceParsingBug.java:135)
	at org.softee.extractor.transform.StaxSourceParsingBug.testParseStaxSource5(StaxSourceParsingBug.java:108)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,88]
Message: found: DTD, expected START_ELEMENT or END_ELEMENT
	at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.nextTag(XMLStreamReaderImpl.java:1250)
	at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.bridge(StAXStream2SAX.java:145)
	at com.sun.org.apache.xalan.internal.xsltc.trax.StAXStream2SAX.parse(StAXStream2SAX.java:118)
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transformIdentity(TransformerImpl.java:678)
	at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl.transform(TransformerImpl.java:727)
	... 28 more



REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package org.softee.extractor.transform;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.junit.BeforeClass;
import org.junit.Test;

/**
 * This test was written to reproduce a bug that exists in Java SE, where exceptions are thrown when using a StaxSource
 * to parse certain wellformed XML instances.
 *
 * Bug has been reproduced with the following Java versions:
 * - 1.6.0_29-b11-402-11M3527 (Mac OS X, 10.7.2)
 * - 1.7.0_04-ea-b13 (Mac OS X, 10.7.2)
 *
 * The bug has been previously reported http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=8315aa2186353a67f7fb0db73f510?bug_id=6715417
 */
public class StaxSourceParsingBug {
    /** Succeeds StAXSource processing */
    private static final String XML_1 = "<root/>";

    /** Succeeds StAXSource processing */
    private static final String XML_2 = "<!DOCTYPE root [<!ENTITY et 'Come Home'>]><root et='&et;'/>";

    /** Fails StAXSource processing with java.lang.IllegalStateException */
    private static final String XML_3 = "<?xml-stylesheet href='show.xsl' type='text/html'?><root/>";

    /** Succeeds StAXSource processing */
    private static final String XML_4 = "<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?><root/>";

    /** Fails StAXSource processing with javax.xml.transform.TransformerException */
    private static final String XML_5 = "<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?><!DOCTYPE root><root/>";

    /** Succeeds StAXSource processing */
    private static final String XML_6 = "<?xml version='1.0'?><!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>";

    /** Fails StAXSource processing with javax.xml.transform.TransformerException */
    private static final String XML_7 = "<?xml version='1.0'?><?xml-stylesheet href='show.xsl' type='text/html'?><!DOCTYPE root [<!ELEMENT greeting (#PCDATA)>]><root/>";

    TransformerFactory tf = TransformerFactory.newInstance();

    @BeforeClass
    public static void beforeClass() {
        //System.getProperties().list(System.out);
        showProperty("java.version");
        showProperty("java.runtime.version");
        showProperty("os.name");
        showProperty("os.version");

    }

    private static void  showProperty(String name) {
        System.out.printf("%s = %s%n", name, System.getProperty(name));
    }
    @Test
    public void testParseStreamSource() throws Exception {
        parseStreamSource(XML_1);
        parseStreamSource(XML_2);
        parseStreamSource(XML_3);
        parseStreamSource(XML_4);
        parseStreamSource(XML_5);
        parseStreamSource(XML_6);
        parseStreamSource(XML_7);
    }

    @Test
    public void testParseStaxSource1() throws Exception {
        parseStaxSource(XML_1);
    }

    @Test
    public void testParseStaxSource2() throws Exception {
        parseStaxSource(XML_2);
    }

    /**
     * Fails with:
     * java.lang.IllegalStateException: StAXSource(XMLStreamReader) with XMLStreamReader not in
     *    XMLStreamConstants.START_DOCUMENT or XMLStreamConstants.START_ELEMENT state
     */
    @Test
    public void testParseStaxSource3() throws Exception {
        parseStaxSource(XML_3);
    }

    @Test
    public void testParseStaxSource4() throws Exception {
        parseStaxSource(XML_4);
    }

    /**
     * Fails with:
     * javax.xml.transform.TransformerException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,105]
     * Message: found: DTD, expected START_ELEMENT or END_ELEMENT
     */
    @Test
    public void testParseStaxSource5() throws Exception {
        parseStaxSource(XML_5);
    }

    @Test
    public void testParseStaxSource6() throws Exception {
        parseStaxSource(XML_6);
    }

    /**
     * Fails with:
     * javax.xml.transform.TransformerException: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,105]
     * Message: found: DTD, expected START_ELEMENT or END_ELEMENT
     */
    @Test
    public void testParseStaxSource7() throws Exception {
        parseStaxSource(XML_7);
    }

    private void parseStreamSource(String xml) throws Exception {
        Source source = new StreamSource(new StringReader(xml));
        unityTransform(source, xml);
    }

    private void parseStaxSource(String xml) throws Exception {
        XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
        XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new StringReader(xml));
        StAXSource source = new StAXSource(xmlStreamReader);
        unityTransform(source, xml);
    }

    private void unityTransform(Source source, String sourceXml) throws Exception{
        StringWriter sw = new StringWriter();
        Result result = new StreamResult(sw);
        tf.newTransformer().transform(source, result);
        System.out.printf("%n%s:%nSource: %s%nResult: %s%n", source.getClass().getSimpleName(), sourceXml, sw);
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Replacing the StAXSource with another Source implementation, such as StreamSource, SAXSource, DOMSource fixes the problem.

This, however is NOT possible when using frameworks (CXF) that expose a Source of type StAXSource

Comments
URL: https://hg.openjdk.java.net/jdk/jdk/rev/ba72dac556c3 User: joehw Date: 2019-07-10 16:46:11 +0000
10-07-2019

I will create a patch to fix the exception. But note that the patch will not include any improvement beyond the current implementation that for example, does not handle DTDs and etc.
09-07-2019