mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 18:44:38 +02:00
8069098: StAX produces the wrong event stream
Reviewed-by: lancea
This commit is contained in:
parent
140d4deeda
commit
361d60ce7d
4 changed files with 118 additions and 52 deletions
|
@ -746,42 +746,18 @@ public class XMLDocumentScannerImpl
|
||||||
// scan XMLDecl
|
// scan XMLDecl
|
||||||
try {
|
try {
|
||||||
if (fEntityScanner.skipString(xmlDecl)) {
|
if (fEntityScanner.skipString(xmlDecl)) {
|
||||||
fMarkupDepth++;
|
if (fEntityScanner.peekChar() == ' ') {
|
||||||
// NOTE: special case where document starts with a PI
|
fMarkupDepth++;
|
||||||
// whose name starts with "xml" (e.g. "xmlfoo")
|
|
||||||
if (XMLChar.isName(fEntityScanner.peekChar())) {
|
|
||||||
fStringBuffer.clear();
|
|
||||||
fStringBuffer.append("xml");
|
|
||||||
while (XMLChar.isName(fEntityScanner.peekChar())) {
|
|
||||||
fStringBuffer.append((char)fEntityScanner.scanChar(null));
|
|
||||||
}
|
|
||||||
String target = fSymbolTable.addSymbol(fStringBuffer.ch, fStringBuffer.offset, fStringBuffer.length);
|
|
||||||
//this function should fill the data.. and set the fEvent object to this event.
|
|
||||||
fContentBuffer.clear() ;
|
|
||||||
scanPIData(target, fContentBuffer);
|
|
||||||
//REVISIT:where else we can set this value to 'true'
|
|
||||||
fEntityManager.fCurrentEntity.mayReadChunks = true;
|
|
||||||
//return PI event since PI was encountered
|
|
||||||
return XMLEvent.PROCESSING_INSTRUCTION ;
|
|
||||||
}
|
|
||||||
// standard XML declaration
|
|
||||||
else {
|
|
||||||
scanXMLDeclOrTextDecl(false);
|
scanXMLDeclOrTextDecl(false);
|
||||||
//REVISIT:where else we can set this value to 'true'
|
} else {
|
||||||
fEntityManager.fCurrentEntity.mayReadChunks = true;
|
// PI, reset position
|
||||||
return XMLEvent.START_DOCUMENT;
|
fEntityManager.fCurrentEntity.position = 0;
|
||||||
}
|
}
|
||||||
} else{
|
|
||||||
//REVISIT:where else we can set this value to 'true'
|
|
||||||
fEntityManager.fCurrentEntity.mayReadChunks = true;
|
|
||||||
//In both case return the START_DOCUMENT. ony difference is that first block will
|
|
||||||
//cosume the XML declaration if any.
|
|
||||||
return XMLEvent.START_DOCUMENT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//START_OF_THE_DOCUMENT
|
//START_OF_THE_DOCUMENT
|
||||||
|
fEntityManager.fCurrentEntity.mayReadChunks = true;
|
||||||
|
return XMLEvent.START_DOCUMENT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,10 @@ import java.util.Iterator;
|
||||||
*/
|
*/
|
||||||
public interface XMLEventReader extends Iterator {
|
public interface XMLEventReader extends Iterator {
|
||||||
/**
|
/**
|
||||||
* Get the next XMLEvent
|
* Gets the next XMLEvent. The initial event is
|
||||||
|
* {@link javax.xml.stream.events.StartDocument StartDocument}.
|
||||||
|
*
|
||||||
|
* @return the next XMLEvent
|
||||||
* @see XMLEvent
|
* @see XMLEvent
|
||||||
* @throws XMLStreamException if there is an error with the underlying XML.
|
* @throws XMLStreamException if there is an error with the underlying XML.
|
||||||
* @throws java.util.NoSuchElementException iteration has no more elements.
|
* @throws java.util.NoSuchElementException iteration has no more elements.
|
||||||
|
@ -58,12 +61,15 @@ public interface XMLEventReader extends Iterator {
|
||||||
* Returns true if there are more events and false otherwise.
|
* Returns true if there are more events and false otherwise.
|
||||||
* @return true if the event reader has more events, false otherwise
|
* @return true if the event reader has more events, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public boolean hasNext();
|
public boolean hasNext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the next XMLEvent without reading it from the stream.
|
* Check the next XMLEvent without reading it from the stream.
|
||||||
* Returns null if the stream is at EOF or has no more XMLEvents.
|
* Returns null if the stream is at EOF or has no more XMLEvents.
|
||||||
* A call to peek() will be equal to the next return of next().
|
* A call to peek() will be equal to the next return of next().
|
||||||
|
*
|
||||||
|
* @return the next XMLEvent
|
||||||
* @see XMLEvent
|
* @see XMLEvent
|
||||||
* @throws XMLStreamException
|
* @throws XMLStreamException
|
||||||
*/
|
*/
|
||||||
|
@ -73,6 +79,8 @@ public interface XMLEventReader extends Iterator {
|
||||||
* Reads the content of a text-only element. Precondition:
|
* Reads the content of a text-only element. Precondition:
|
||||||
* the current event is START_ELEMENT. Postcondition:
|
* the current event is START_ELEMENT. Postcondition:
|
||||||
* The current event is the corresponding END_ELEMENT.
|
* The current event is the corresponding END_ELEMENT.
|
||||||
|
*
|
||||||
|
* @return the text of the element
|
||||||
* @throws XMLStreamException if the current event is not a START_ELEMENT
|
* @throws XMLStreamException if the current event is not a START_ELEMENT
|
||||||
* or if a non text element is encountered
|
* or if a non text element is encountered
|
||||||
*/
|
*/
|
||||||
|
@ -85,6 +93,8 @@ public interface XMLEventReader extends Iterator {
|
||||||
* be used when processing element-only content because
|
* be used when processing element-only content because
|
||||||
* the parser is not able to recognize ignorable whitespace if
|
* the parser is not able to recognize ignorable whitespace if
|
||||||
* the DTD is missing or not interpreted.
|
* the DTD is missing or not interpreted.
|
||||||
|
*
|
||||||
|
* @return a START_ELEMENT or END_ELEMENT
|
||||||
* @throws XMLStreamException if anything other than space characters are encountered
|
* @throws XMLStreamException if anything other than space characters are encountered
|
||||||
*/
|
*/
|
||||||
public XMLEvent nextTag() throws XMLStreamException;
|
public XMLEvent nextTag() throws XMLStreamException;
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
|
|
||||||
package javax.xml.stream;
|
package javax.xml.stream;
|
||||||
|
|
||||||
import java.io.Reader;
|
|
||||||
import javax.xml.namespace.NamespaceContext;
|
import javax.xml.namespace.NamespaceContext;
|
||||||
import javax.xml.namespace.QName;
|
import javax.xml.namespace.QName;
|
||||||
|
|
||||||
|
@ -37,19 +36,26 @@ import javax.xml.namespace.QName;
|
||||||
* It is designed to be the lowest level and most efficient way to
|
* It is designed to be the lowest level and most efficient way to
|
||||||
* read XML data.
|
* read XML data.
|
||||||
*
|
*
|
||||||
* <p> The XMLStreamReader is designed to iterate over XML using
|
* <p>
|
||||||
|
* The XMLStreamReader is designed to iterate over XML using
|
||||||
* next() and hasNext(). The data can be accessed using methods such as getEventType(),
|
* next() and hasNext(). The data can be accessed using methods such as getEventType(),
|
||||||
* getNamespaceURI(), getLocalName() and getText();
|
* getNamespaceURI(), getLocalName() and getText();
|
||||||
*
|
*
|
||||||
* <p> The <a href="#next()">next()</a> method causes the reader to read the next parse event.
|
* <p>
|
||||||
* The next() method returns an integer which identifies the type of event just read.
|
* An XMLStreamReader instance is created with an initial event type START_DOCUMENT.
|
||||||
* <p> The event type can be determined using <a href="#getEventType()">getEventType()</a>.
|
* At any moment in time, it has a current event that the methods of the interface
|
||||||
* <p> Parsing events are defined as the XML Declaration, a DTD,
|
* access and may load the next event through the {@link #next() next()} method.
|
||||||
|
* The current event type can be determined by {@link #getEventType getEventType()}, and
|
||||||
|
* the next returned by the {@link #next() next()} method.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Parsing events are defined as the XML Declaration, a DTD,
|
||||||
* start tag, character data, white space, end tag, comment,
|
* start tag, character data, white space, end tag, comment,
|
||||||
* or processing instruction. An attribute or namespace event may be encountered
|
* or processing instruction. An attribute or namespace event may be encountered
|
||||||
* at the root level of a document as the result of a query operation.
|
* at the root level of a document as the result of a query operation.
|
||||||
*
|
*
|
||||||
* <p>For XML 1.0 compliance an XML processor must pass the
|
* <p>
|
||||||
|
* For XML 1.0 compliance an XML processor must pass the
|
||||||
* identifiers of declared unparsed entities, notation declarations and their
|
* identifiers of declared unparsed entities, notation declarations and their
|
||||||
* associated identifiers to the application. This information is
|
* associated identifiers to the application. This information is
|
||||||
* provided through the property API on this interface.
|
* provided through the property API on this interface.
|
||||||
|
@ -63,7 +69,8 @@ import javax.xml.namespace.QName;
|
||||||
* These properties can only be accessed during a DTD event and
|
* These properties can only be accessed during a DTD event and
|
||||||
* are defined to return null if the information is not available.
|
* are defined to return null if the information is not available.
|
||||||
*
|
*
|
||||||
* <p>The following table describes which methods are valid in what state.
|
* <p>
|
||||||
|
* The following table describes which methods are valid in what state.
|
||||||
* If a method is called in an invalid state the method will throw a
|
* If a method is called in an invalid state the method will throw a
|
||||||
* java.lang.IllegalStateException.
|
* java.lang.IllegalStateException.
|
||||||
*
|
*
|
||||||
|
@ -502,8 +509,10 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
// public void recycle() throws XMLStreamException;
|
// public void recycle() throws XMLStreamException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an integer code that indicates the type
|
* Returns an integer code that indicates the type of the event the cursor is
|
||||||
* of the event the cursor is pointing to.
|
* pointing to. The initial event type is {@link #START_DOCUMENT}.
|
||||||
|
*
|
||||||
|
* @return the type of the current event
|
||||||
*/
|
*/
|
||||||
public int getEventType();
|
public int getEventType();
|
||||||
|
|
||||||
|
@ -590,6 +599,8 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
/**
|
/**
|
||||||
* Returns the offset into the text character array where the first
|
* Returns the offset into the text character array where the first
|
||||||
* character (of this text event) is stored.
|
* character (of this text event) is stored.
|
||||||
|
*
|
||||||
|
* @return the starting position of the text in the character array
|
||||||
* @throws java.lang.IllegalStateException if this state is not
|
* @throws java.lang.IllegalStateException if this state is not
|
||||||
* a valid text state.
|
* a valid text state.
|
||||||
*/
|
*/
|
||||||
|
@ -598,6 +609,8 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
/**
|
/**
|
||||||
* Returns the length of the sequence of characters for this
|
* Returns the length of the sequence of characters for this
|
||||||
* Text event within the text character array.
|
* Text event within the text character array.
|
||||||
|
*
|
||||||
|
* @return the length of the text
|
||||||
* @throws java.lang.IllegalStateException if this state is not
|
* @throws java.lang.IllegalStateException if this state is not
|
||||||
* a valid text state.
|
* a valid text state.
|
||||||
*/
|
*/
|
||||||
|
@ -610,9 +623,11 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
public String getEncoding();
|
public String getEncoding();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the current event has text, false otherwise
|
* Return a boolean indicating whether the current event has text.
|
||||||
* The following events have text:
|
* The following events have text:
|
||||||
* CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
|
* CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE
|
||||||
|
*
|
||||||
|
* @return true if the event has text, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean hasText();
|
public boolean hasText();
|
||||||
|
|
||||||
|
@ -623,6 +638,7 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
* location and null for the publicId and systemId.
|
* location and null for the publicId and systemId.
|
||||||
* The location information is only valid until next() is
|
* The location information is only valid until next() is
|
||||||
* called.
|
* called.
|
||||||
|
* @return the location of the cursor
|
||||||
*/
|
*/
|
||||||
public Location getLocation();
|
public Location getLocation();
|
||||||
|
|
||||||
|
@ -647,8 +663,10 @@ public interface XMLStreamReader extends XMLStreamConstants {
|
||||||
public String getLocalName();
|
public String getLocalName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT)
|
* returns a boolean indicating whether the current event has a name
|
||||||
* returns false otherwise
|
* (is a START_ELEMENT or END_ELEMENT).
|
||||||
|
*
|
||||||
|
* @return true if the event has a name, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean hasName();
|
public boolean hasName();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -24,17 +24,20 @@
|
||||||
package stream.XMLStreamReaderTest;
|
package stream.XMLStreamReaderTest;
|
||||||
|
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
|
||||||
import javax.xml.stream.XMLInputFactory;
|
import javax.xml.stream.XMLInputFactory;
|
||||||
import javax.xml.stream.XMLStreamConstants;
|
import javax.xml.stream.XMLStreamConstants;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import javax.xml.stream.XMLStreamReader;
|
||||||
|
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Listeners;
|
import org.testng.annotations.Listeners;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
|
* @bug 8069098
|
||||||
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
|
||||||
* @run testng/othervm -DrunSecMngr=true stream.XMLStreamReaderTest.BugTest
|
* @run testng/othervm -DrunSecMngr=true stream.XMLStreamReaderTest.BugTest
|
||||||
* @run testng/othervm stream.XMLStreamReaderTest.BugTest
|
* @run testng/othervm stream.XMLStreamReaderTest.BugTest
|
||||||
|
@ -43,11 +46,70 @@ import org.testng.annotations.Test;
|
||||||
@Listeners({jaxp.library.BasePolicy.class})
|
@Listeners({jaxp.library.BasePolicy.class})
|
||||||
public class BugTest {
|
public class BugTest {
|
||||||
|
|
||||||
@Test
|
/**
|
||||||
public static void test1() throws Exception {
|
* Verifies that the initial event of an XMLStreamReader instance is
|
||||||
XMLInputFactory xif = XMLInputFactory.newInstance(); // new
|
* START_DOCUMENT.
|
||||||
// com.sun.xml.stream.ZephyrParserFactory();
|
*
|
||||||
XMLStreamReader r = xif.createXMLStreamReader(new StringReader("<foo/>"));
|
* @param xml the xml input
|
||||||
Assert.assertEquals(XMLStreamConstants.START_DOCUMENT, r.getEventType());
|
* @param type1 the type of the 1st event
|
||||||
|
* @param type2 the type of the 2nd event
|
||||||
|
* @throws Exception if the test fails to run properly
|
||||||
|
*/
|
||||||
|
@Test(dataProvider = "xmls")
|
||||||
|
public static void test1(String xml, int type1, int type2) throws Exception {
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newFactory();
|
||||||
|
|
||||||
|
XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(xml));
|
||||||
|
int type1stEvent = reader.getEventType();
|
||||||
|
int type2ndEvent = reader.next();
|
||||||
|
System.out.println("First event: " + type1stEvent);
|
||||||
|
System.out.println("2nd event: " + type2ndEvent);
|
||||||
|
Assert.assertEquals(type1, type1stEvent);
|
||||||
|
Assert.assertEquals(type2, type2ndEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verifies that the initial event of an XMLEventReader instance is
|
||||||
|
* START_DOCUMENT. XMLEventReader depends on XMLStreamReader.
|
||||||
|
*
|
||||||
|
* @param xml the xml input
|
||||||
|
* @param type1 the type of the 1st event
|
||||||
|
* @param type2 the type of the 2nd event
|
||||||
|
* @throws Exception if the test fails to run properly
|
||||||
|
*/
|
||||||
|
@Test(dataProvider = "xmls")
|
||||||
|
public static void test2(String xml, int type1, int type2) throws Exception {
|
||||||
|
XMLInputFactory factory = XMLInputFactory.newFactory();
|
||||||
|
|
||||||
|
XMLEventReader reader = factory.createXMLEventReader(new StringReader(xml));
|
||||||
|
int type1stEvent = reader.nextEvent().getEventType();
|
||||||
|
int type2ndEvent = reader.nextEvent().getEventType();
|
||||||
|
System.out.println("First event: " + type1stEvent);
|
||||||
|
System.out.println("2nd event: " + type2ndEvent);
|
||||||
|
Assert.assertEquals(type1, type1stEvent);
|
||||||
|
Assert.assertEquals(type2, type2ndEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DataProvider: for testing beginning event type
|
||||||
|
Data: xml, 1st event type, 2nd event type
|
||||||
|
*/
|
||||||
|
@DataProvider(name = "xmls")
|
||||||
|
public Object[][] getXMLs() {
|
||||||
|
|
||||||
|
return new Object[][]{
|
||||||
|
{"<?xml version='1.0'?><foo/>",
|
||||||
|
XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.START_ELEMENT},
|
||||||
|
{"<foo/>",
|
||||||
|
XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.START_ELEMENT},
|
||||||
|
{"<?xml version='1.0'?>"
|
||||||
|
+ "<?xml-stylesheet href=\"bar.xsl\" type=\"text/xsl\"?>" +
|
||||||
|
"<foo/>",
|
||||||
|
XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.PROCESSING_INSTRUCTION},
|
||||||
|
{"<?xml-stylesheet href=\"bar.xsl\" type=\"text/xsl\"?>" +
|
||||||
|
"<foo/>",
|
||||||
|
XMLStreamConstants.START_DOCUMENT, XMLStreamConstants.PROCESSING_INSTRUCTION},
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue