unstick r1874026

Revision 1874026

Date:
2020/02/14 16:52:46
Author:
coheigea
Revision Log:
SANTUARIO--523 XMLSecurityStreamReader now correctly reads info from XML declara
tion. Thanks to Peter De Maeyer for the patch.
Files:

Legend:

 
Added
 
Removed
 
Modified
  • santuario/xml-security-java/branches/2.1.x-fixes/pom.xml

     
    531 531 <junit.version>4.12</junit.version>
    532 532 <log4j.version>1.2.17</log4j.version>
    533 533 <bcprov.version>1.64</bcprov.version>
    534 <hamcrest.version>2.2</hamcrest.version>
    534 535 <xmlunit.version>1.6</xmlunit.version>
    535 536 <commons.codec.version>1.13</commons.codec.version>
    536 537 <woodstox.core.version>5.0.3</woodstox.core.version>
     
    582 583 <scope>test</scope>
    583 584 </dependency>
    584 585 <dependency>
    586 <groupId>org.hamcrest</groupId>
    587 <artifactId>hamcrest</artifactId>
    588 <version>${hamcrest.version}</version>
    589 <scope>test</scope>
    590 </dependency>
    591 <dependency>
    585 592 <groupId>org.eclipse.jetty</groupId>
    586 593 <artifactId>jetty-server</artifactId>
    587 594 <version>${jetty.version}</version>
  • santuario/xml-security-java/branches/2.1.x-fixes/src/main/java/org/apache/xml/security/stax/impl/XMLSecurityStreamReader.java

     
    33 33 import javax.xml.stream.events.EntityReference;
    34 34 import javax.xml.stream.events.Namespace;
    35 35 import javax.xml.stream.events.ProcessingInstruction;
    36 import javax.xml.stream.events.StartDocument;
    36 37
    37 38 import org.apache.xml.security.exceptions.XMLSecurityException;
    38 39 import org.apache.xml.security.stax.ext.InputProcessorChain;
     
    49 50
    50 51 private final InputProcessorChain inputProcessorChain;
    51 52 private XMLSecEvent currentXMLSecEvent;
    52 private boolean skipDocumentEvents = false;
    53 private final boolean skipDocumentEvents;
    54 private String version;
    55 private boolean standalone;
    56 private boolean standaloneSet;
    57 private String characterEncodingScheme;
    53 58
    54 59 private static final String ERR_STATE_NOT_ELEM = "Current state not START_ELEMENT or END_ELEMENT";
    55 60 private static final String ERR_STATE_NOT_STELEM = "Current state not START_ELEMENT";
     
    75 80 inputProcessorChain.reset();
    76 81 currentXMLSecEvent = inputProcessorChain.processEvent();
    77 82 eventType = currentXMLSecEvent.getEventType();
    78 if (eventType == START_DOCUMENT && this.skipDocumentEvents) {
    79 currentXMLSecEvent = inputProcessorChain.processEvent();
    80 eventType = currentXMLSecEvent.getEventType();
    83 if (eventType == START_DOCUMENT) {
    84 // Even when skipDocumentEvents is true, we still want to get the information out of the event.
    85 // We only skip the event itself.
    86 StartDocument startDocument = (StartDocument) currentXMLSecEvent;
    87 version = startDocument.getVersion();
    88 if (startDocument.encodingSet()) {
    89 characterEncodingScheme = startDocument.getCharacterEncodingScheme();
    90 }
    91 standalone = startDocument.isStandalone();
    92 standaloneSet = startDocument.standaloneSet();
    93 if (skipDocumentEvents) {
    94 currentXMLSecEvent = inputProcessorChain.processEvent();
    95 eventType = currentXMLSecEvent.getEventType();
    96 }
    81 97 }
    82 98 } catch (XMLSecurityException e) {
    83 99 throw new XMLStreamException(e);
     
    592 608
    593 609 @Override
    594 610 public String getVersion() {
    595 return null;
    611 return version;
    596 612 }
    597 613
    598 614 @Override
    599 615 public boolean isStandalone() {
    600 return false;
    616 return standalone;
    601 617 }
    602 618
    603 619 @Override
    604 620 public boolean standaloneSet() {
    605 return false;
    621 return standaloneSet;
    606 622 }
    607 623
    608 624 @Override
    609 625 public String getCharacterEncodingScheme() {
    610 return null;
    626 return characterEncodingScheme;
    611 627 }
    612 628
    613 629 @Override
  • santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/utils/XmlReaderToWriter.java

     
    31 31
    32 32 public static void writeAll(XMLStreamReader xmlr, XMLStreamWriter writer)
    33 33 throws XMLStreamException {
    34 // Some implementations, Woodstox for example, already position their reader ON the first event, which is.
    35 // typically a START_DOCUMENT event.
    36 // If already positioned on an event, that is indicated by the event type.
    37 // Make sure we don't miss the initial event.
    38 if (xmlr.getEventType() > 0) {
    39 write(xmlr, writer);
    40 }
    34 41 while (xmlr.hasNext()) {
    35 42 xmlr.next();
    36 43 write(xmlr, writer);
  • santuario/xml-security-java/branches/2.1.x-fixes/src/test/java/org/apache/xml/security/test/stax/XMLSecurityStreamReaderTest.java

     
    41 41 import javax.xml.transform.stax.StAXSource;
    42 42 import javax.xml.transform.stream.StreamResult;
    43 43 import java.io.BufferedReader;
    44 import java.io.ByteArrayInputStream;
    44 45 import java.io.ByteArrayOutputStream;
    45 46 import java.io.InputStream;
    46 47 import java.io.InputStreamReader;
     
    48 49 import java.util.HashSet;
    49 50 import java.util.Set;
    50 51
    52 import static org.hamcrest.Matchers.equalTo;
    53 import static org.hamcrest.Matchers.is;
    54
    51 55 /**
    52 56 */
    53 57 public class XMLSecurityStreamReaderTest extends Assert {
     
    98 102 }
    99 103
    100 104 @Test
    105 public void testDocumentDeclaration() throws Exception {
    106 String xml = "<?xml version='1.1' encoding='ISO-8859-1' standalone='yes'?>\n"
    107 + "<Document/>";
    108 ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
    109 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
    110 XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
    111 InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
    112 InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
    113 inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
    114 XMLSecurityProperties securityProperties = new XMLSecurityProperties();
    115 securityProperties.setSkipDocumentEvents(false);
    116 XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
    117 advanceToFirstEvent(xmlSecurityStreamReader);
    118 assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_DOCUMENT));
    119 assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
    120 assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
    121 assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
    122 assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
    123
    124 assertThat(xmlSecurityStreamReader.hasNext(), is(true));
    125 assertThat(xmlSecurityStreamReader.next(), is(XMLStreamConstants.START_ELEMENT));
    126 // Strictly speaking, we should assert that getVersion() etc. throw when not on a START_DOCUMENT event.
    127 // However, we have to be lenient to compensate for XML reader implementations such as Xalan,
    128 // which access getVersion() etc. when they're positioned on START_ELEMENT, _beyond_ START_DOCUMENT.
    129 assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
    130 assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
    131 assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
    132 assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
    133 }
    134
    135 @Test
    136 public void testDocumentDeclarationWhenSkipDocumentEvents() throws Exception {
    137 String xml = "<?xml version='1.1' encoding='ISO-8859-1' standalone='yes'?>\n"
    138 + "<Document/>";
    139 ByteArrayInputStream xmlInput = new ByteArrayInputStream(xml.getBytes(StandardCharsets.ISO_8859_1));
    140 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
    141 XMLStreamReader stdXmlStreamReader = xmlInputFactory.createXMLStreamReader(xmlInput);
    142 InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
    143 InputProcessorChainImpl inputProcessorChain = new InputProcessorChainImpl(securityContext);
    144 inputProcessorChain.addProcessor(new EventReaderProcessor(stdXmlStreamReader));
    145 XMLSecurityProperties securityProperties = new XMLSecurityProperties();
    146 securityProperties.setSkipDocumentEvents(true);
    147 XMLSecurityStreamReader xmlSecurityStreamReader = new XMLSecurityStreamReader(inputProcessorChain, securityProperties);
    148 advanceToFirstEvent(xmlSecurityStreamReader);
    149 assertThat(xmlSecurityStreamReader.getEventType(), is(XMLStreamConstants.START_ELEMENT));
    150 assertThat(xmlSecurityStreamReader.getVersion(), is(equalTo("1.1")));
    151 assertThat(xmlSecurityStreamReader.getCharacterEncodingScheme(), is(equalTo("ISO-8859-1")));
    152 assertThat(xmlSecurityStreamReader.isStandalone(), is(true));
    153 assertThat(xmlSecurityStreamReader.standaloneSet(), is(true));
    154 }
    155
    156 /**
    157 * This method advances the reader until it's <i>on</i> the first event, if that's not already the case.
    158 * Depending on the implementation, the {@code xmlStreamReader} may be positioned <i>before</i> or <i>on</i>
    159 * the first event upon creation.
    160 */
    161 private static void advanceToFirstEvent(XMLStreamReader xmlStreamReader) throws XMLStreamException {
    162 if (xmlStreamReader.getEventType() <= 0) {
    163 assertThat(xmlStreamReader.hasNext(), is(true));
    164 xmlStreamReader.next();
    165 }
    166 }
    167
    168 @Test
    101 169 public void testCorrectness() throws Exception {
    102 170 XMLSecurityProperties securityProperties = new XMLSecurityProperties();
    103 171 InboundSecurityContextImpl securityContext = new InboundSecurityContextImpl();
     
    115 183 "org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
    116 184
    117 185 //hmm why does a streamreader return a DOCUMENT_EVENT before we did call next() ??
    186 // A: Because some implementations of XMLStreamReader are positioned _on_ the first event rather than before it
    187 // upon construction.
    188 // Woodstox is a typical example of such an implementation.
    189 // We have to compensate for both types of implementation, see the method advanceToFirstEvent(XMLStreamReader).
    118 190 int stdXMLEventType = stdXmlStreamReader.getEventType();
    119 191 int secXMLEventType = xmlSecurityStreamReader.getEventType();
    120 192 do {
     
    207 279 case XMLStreamConstants.START_DOCUMENT:
    208 280 Assert.assertEquals(stdXmlStreamReader.getCharacterEncodingScheme(), xmlSecurityStreamReader.getCharacterEncodingScheme());
    209 281 Assert.assertEquals(stdXmlStreamReader.getEncoding(), xmlSecurityStreamReader.getEncoding());
    210 //Assert.assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
    282 Assert.assertEquals(stdXmlStreamReader.getVersion(), xmlSecurityStreamReader.getVersion());
    211 283 break;
    212 284 case XMLStreamConstants.END_DOCUMENT:
    213 285 break;
     
    261 333 return stringBuilder.toString();
    262 334 }
    263 335
    336 private static XMLStreamReader createXmlStreamReader() throws XMLStreamException {
    337 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
    338 xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
    339 xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
    340 return xmlInputFactory.createXMLStreamReader(InputProcessor.class.getClassLoader().getResourceAsStream(
    341 "org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
    342 }
    343
    264 344 class EventReaderProcessor implements InputProcessor {
    265 345
    266 346 private XMLStreamReader xmlStreamReader;
    267 347
    348 EventReaderProcessor(XMLStreamReader xmlStreamReader) {
    349 this.xmlStreamReader = xmlStreamReader;
    350 }
    351
    268 352 EventReaderProcessor() throws Exception {
    269 XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
    270 xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, true);
    271 xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
    272 xmlStreamReader =
    273 xmlInputFactory.createXMLStreamReader(this.getClass().getClassLoader().getResourceAsStream(
    274 "org/apache/xml/security/c14n/inExcl/plain-soap-1.1.xml"));
    353 this(createXmlStreamReader());
    275 354 }
    276 355
    277 356 @Override