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/11 14:08:10 UTC
svn commit: r1873911 - in /santuario/xml-security-java/trunk/src:
main/java/org/apache/xml/security/stax/impl/
test/java/org/apache/xml/security/test/stax/
test/java/org/apache/xml/security/test/stax/utils/
Author: coheigea
Date: Tue Feb 11 14:08:10 2020
New Revision: 1873911
URL: http://svn.apache.org/viewvc?rev=1873911&view=rev
Log:
SANTUARIO--523 XMLSecurityStreamReader now correctly reads info from XML declaration. Thanks to Peter De Maeyer for the patch. This closes #18.
Modified:
santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java
santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java
Modified: santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java?rev=1873911&r1=1873910&r2=1873911&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java (original)
+++ santuario/xml-security-java/trunk/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java Tue Feb 11 14:08:10 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,18 @@ 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();
+ 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 +606,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/trunk/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java?rev=1873911&r1=1873910&r2=1873911&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java Tue Feb 11 14:08:10 2020
@@ -19,6 +19,7 @@
package org.apache.xml.security.test.stax;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -51,6 +52,9 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.xmlunit.matchers.CompareMatcher;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -106,6 +110,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();
@@ -123,6 +191,9 @@ 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.
+ // 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 {
@@ -213,9 +284,9 @@ public class XMLSecurityStreamReaderTest
assertEquals(stdXmlStreamReader.getTextLength(), xmlSecurityStreamReader.getTextLength());
break;
case XMLStreamConstants.START_DOCUMENT:
- assertEquals(stdXmlStreamReader.getCharacterEncodingScheme(), xmlSecurityStreamReader.getCharacterEncodingScheme());
+ assertEquals(StandardCharsets.UTF_8.name(), xmlSecurityStreamReader.getCharacterEncodingScheme());
assertEquals(stdXmlStreamReader.getEncoding(), xmlSecurityStreamReader.getEncoding());
- //assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
+ assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
break;
case XMLStreamConstants.END_DOCUMENT:
break;
@@ -269,17 +340,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/trunk/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java
URL: http://svn.apache.org/viewvc/santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java?rev=1873911&r1=1873910&r2=1873911&view=diff
==============================================================================
--- santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java (original)
+++ santuario/xml-security-java/trunk/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java Tue Feb 11 14:08:10 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);