You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@santuario.apache.org by co...@apache.org on 2020/02/14 16:52:47 UTC
svn commit: r1874026 - in /santuario/xml-security-java/branches/2.1.x-fixes:
./ src/main/java/org/apache/xml/security/stax/impl/
src/test/java/org/apache/xml/security/test/stax/
src/test/java/org/apache/xml/security/test/stax/utils/
Author: coheigea
Date: Fri Feb 14 16:52:46 2020
New Revision: 1874026
URL: http://svn.apache.org/viewvc?rev=1874026&view=rev
Log:
SANTUARIO--523 XMLSecurityStreamReader now correctly reads info from XML declara
tion. Thanks to Peter De Maeyer for the patch.
Modified:
santuario/xml-security-java/branches/2.1.x-fixes/pom.xml
santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java
santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java
Modified: santuario/xml-security-java/branches/2.1.x-fixes/pom.xml
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/branches/2.1.x-fixes/pom.xml?rev=1874026&r1=1874025&r2=1874026&view=diff
==============================================================================
--- santuario/xml-security-java/branches/2.1.x-fixes/pom.xml (original)
+++ santuario/xml-security-java/branches/2.1.x-fixes/pom.xml Fri Feb 14 16:52:46 2020
@@ -531,6 +531,7 @@
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<bcprov.version>1.64</bcprov.version>
+ <hamcrest.version>2.2</hamcrest.version>
<xmlunit.version>1.6</xmlunit.version>
<commons.codec.version>1.13</commons.codec.version>
<woodstox.core.version>5.0.3</woodstox.core.version>
@@ -582,6 +583,12 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest</artifactId>
+ <version>${hamcrest.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
Modified: santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java?rev=1874026&r1=1874025&r2=1874026&view=diff
==============================================================================
--- santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java (original)
+++ santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java Fri Feb 14 16:52:46 2020
@@ -33,6 +33,7 @@ import javax.xml.stream.events.DTD;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.StartDocument;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.stax.ext.InputProcessorChain;
@@ -49,7 +50,11 @@ public class XMLSecurityStreamReader imp
private final InputProcessorChain inputProcessorChain;
private XMLSecEvent currentXMLSecEvent;
- private boolean skipDocumentEvents = false;
+ private final boolean skipDocumentEvents;
+ private String version;
+ private boolean standalone;
+ private boolean standaloneSet;
+ private String characterEncodingScheme;
private static final String ERR_STATE_NOT_ELEM = "Current state not START_ELEMENT or END_ELEMENT";
private static final String ERR_STATE_NOT_STELEM = "Current state not START_ELEMENT";
@@ -75,9 +80,20 @@ public class XMLSecurityStreamReader imp
inputProcessorChain.reset();
currentXMLSecEvent = inputProcessorChain.processEvent();
eventType = currentXMLSecEvent.getEventType();
- if (eventType == START_DOCUMENT && this.skipDocumentEvents) {
- currentXMLSecEvent = inputProcessorChain.processEvent();
- eventType = currentXMLSecEvent.getEventType();
+ if (eventType == START_DOCUMENT) {
+ // Even when skipDocumentEvents is true, we still want to get the information out of the event.
+ // We only skip the event itself.
+ StartDocument startDocument = (StartDocument) currentXMLSecEvent;
+ version = startDocument.getVersion();
+ if (startDocument.encodingSet()) {
+ characterEncodingScheme = startDocument.getCharacterEncodingScheme();
+ }
+ standalone = startDocument.isStandalone();
+ standaloneSet = startDocument.standaloneSet();
+ if (skipDocumentEvents) {
+ currentXMLSecEvent = inputProcessorChain.processEvent();
+ eventType = currentXMLSecEvent.getEventType();
+ }
}
} catch (XMLSecurityException e) {
throw new XMLStreamException(e);
@@ -592,22 +608,22 @@ public class XMLSecurityStreamReader imp
@Override
public String getVersion() {
- return null;
+ return version;
}
@Override
public boolean isStandalone() {
- return false;
+ return standalone;
}
@Override
public boolean standaloneSet() {
- return false;
+ return standaloneSet;
}
@Override
public String getCharacterEncodingScheme() {
- return null;
+ return characterEncodingScheme;
}
@Override
Modified: santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java?rev=1874026&r1=1874025&r2=1874026&view=diff
==============================================================================
--- santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java (original)
+++ santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java Fri Feb 14 16:52:46 2020
@@ -41,6 +41,7 @@ import javax.xml.transform.TransformerFa
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -48,6 +49,9 @@ import java.nio.charset.StandardCharsets
import java.util.HashSet;
import java.util.Set;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+
/**
*/
public class XMLSecurityStreamReaderTest extends Assert {
@@ -98,6 +102,70 @@ public class XMLSecurityStreamReaderTest
}
@Test
+ public void testDocumentDeclaration() throws Exception {
+ String xml = "<?xml version='1.1' encoding='ISO-8859-1' standalone='yes'?>\n"
+ + "<Document/>";
+ ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
+ inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
+ XMLSecurityProperties securityProperties = new XMLSecurityProperties();
+ securityProperties.setSkipDocumentEvents(false);
+ XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
+ advanceToFirstEvent(xmlSecurityStreamReader);
+ assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_DOCUMENT));
+ assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
+ assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
+ assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
+ assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
+
+ assertThat(xmlSecurityStreamReader.hasNext(), is(true));
+ assertThat(xmlSecurityStreamReader.next(), is(XMLStreamConstants.START_ELEMENT));
+ // Strictly speaking, we should assert that getVersion() etc. throw when not on a START_DOCUMENT event.
+ // However, we have to be lenient to compensate for XML reader implementations such as Xalan,
+ // which access getVersion() etc. when they're positioned on START_ELEMENT, _beyond_ START_DOCUMENT.
+ assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
+ assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
+ assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
+ assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
+ }
+
+ @Test
+ public void testDocumentDeclarationWhenSkipDocumentEvents() throws Exception {
+ String xml = "<?xml version='1.1' encoding='ISO-8859-1' standalone='yes'?>\n"
+ + "<Document/>";
+ ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
+ InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
+ InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
+ inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
+ XMLSecurityProperties securityProperties = new XMLSecurityProperties();
+ securityProperties.setSkipDocumentEvents(true);
+ XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
+ advanceToFirstEvent(xmlSecurityStreamReader);
+ assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_ELEMENT));
+ assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
+ assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
+ assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
+ assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
+ }
+
+ /**
+ * This method advances the reader until it's <i>on</i> the first event, if that's not already the case.
+ * Depending on the implementation, the {@code xmlStreamReader} may be positioned <i>before</i> or <i>on</i>
+ * the first event upon creation.
+ */
+ private static void advanceToFirstEvent(XMLStreamReader xmlStreamReader) throws XMLStreamException {
+ if (xmlStreamReader.getEventType() <= 0) {
+ assertThat(xmlStreamReader.hasNext(), is(true));
+ xmlStreamReader.next();
+ }
+ }
+
+ @Test
public void testCorrectness() throws Exception {
XMLSecurityProperties securityProperties = new XMLSecurityProperties();
InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
@@ -115,6 +183,10 @@ public class XMLSecurityStreamReaderTest
"org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
//hmm why does a streamreader return a DOCUMENT_EVENT before we did call next() ??
+ // A: Because some implementations of XMLStreamReader are positioned _on_ the first event rather than before it
+ // upon construction.
+ // Woodstox is a typical example of such an implementation.
+ // We have to compensate for both types of implementation, see the method advanceToFirstEvent(XMLStreamReader).
int stdXMLEventType = stdXmlStreamReader.getEventType();
int secXMLEventType = xmlSecurityStreamReader.getEventType();
do {
@@ -207,7 +279,7 @@ public class XMLSecurityStreamReaderTest
case XMLStreamConstants.START_DOCUMENT:
Assert.assertEquals(stdXmlStreamReader.getCharacterEncodingScheme(), xmlSecurityStreamReader.getCharacterEncodingScheme());
Assert.assertEquals(stdXmlStreamReader.getEncoding(), xmlSecurityStreamReader.getEncoding());
- //Assert.assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
+ Assert.assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
break;
case XMLStreamConstants.END_DOCUMENT:
break;
@@ -261,17 +333,24 @@ public class XMLSecurityStreamReaderTest
return stringBuilder.toString();
}
+ private static XMLStreamReader createXmlStreamReader() throws XMLStreamException {
+ XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
+ xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
+ xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
+ return xmlInputFactory.createXMLStreamReader(InputProcessor.class.getClassLoader().getResourceAsStream(
+ "org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
+ }
+
class EventReaderProcessor implements InputProcessor {
private XMLStreamReader xmlStreamReader;
+ EventReaderProcessor(XMLStreamReader xmlStreamReader) {
+ this.xmlStreamReader = xmlStreamReader;
+ }
+
EventReaderProcessor() throws Exception {
- XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
- xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
- xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
- xmlStreamReader =
- xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream(
- "org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
+ this(createXmlStreamReader());
}
@Override
Modified: santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java?rev=1874026&r1=1874025&r2=1874026&view=diff
==============================================================================
--- santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java (original)
+++ santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java Fri Feb 14 16:52:46 2020
@@ -31,6 +31,13 @@ public final class XmlReaderToWriter {
public static void writeAll(XMLStreamReader xmlr, XMLStreamWriter writer)
throws XMLStreamException {
+ // Some implementations, Woodstox for example, already position their reader ON the first event, which is.
+ // typically a START_DOCUMENT event.
+ // If already positioned on an event, that is indicated by the event type.
+ // Make sure we don't miss the initial event.
+ if (xmlr.getEventType() > 0) {
+ write(xmlr, writer);
+ }
while (xmlr.hasNext()) {
xmlr.next();
write(xmlr, writer);