KEYCLOAK-8109 Fix getDOMElement

This commit is contained in:
Hynek Mlnarik 2018-08-21 19:22:00 +02:00 committed by Hynek Mlnařík
parent 694966b613
commit 1f840b1fbc
2 changed files with 50 additions and 14 deletions

View file

@ -209,8 +209,6 @@ public class TransformerUtil {
if (!(outputTarget instanceof DOMResult)) if (!(outputTarget instanceof DOMResult))
throw logger.wrongTypeError("outputTarget should be a dom result"); throw logger.wrongTypeError("outputTarget should be a dom result");
String rootTag = null;
StAXSource staxSource = (StAXSource) xmlSource; StAXSource staxSource = (StAXSource) xmlSource;
XMLEventReader xmlEventReader = staxSource.getXMLEventReader(); XMLEventReader xmlEventReader = staxSource.getXMLEventReader();
if (xmlEventReader == null) if (xmlEventReader == null)
@ -227,7 +225,6 @@ public class TransformerUtil {
throw new TransformerException(ErrorCodes.WRITER_SHOULD_START_ELEMENT); throw new TransformerException(ErrorCodes.WRITER_SHOULD_START_ELEMENT);
StartElement rootElement = (StartElement) xmlEvent; StartElement rootElement = (StartElement) xmlEvent;
rootTag = StaxParserUtil.getElementName(rootElement);
CustomHolder holder = new CustomHolder(doc, false); CustomHolder holder = new CustomHolder(doc, false);
Element docRoot = handleStartElement(xmlEventReader, rootElement, holder); Element docRoot = handleStartElement(xmlEventReader, rootElement, holder);
Node parent = doc.importNode(docRoot, true); Node parent = doc.importNode(docRoot, true);
@ -243,6 +240,8 @@ public class TransformerUtil {
while (xmlEventReader.hasNext()) { while (xmlEventReader.hasNext()) {
xmlEvent = StaxParserUtil.getNextEvent(xmlEventReader); xmlEvent = StaxParserUtil.getNextEvent(xmlEventReader);
int type = xmlEvent.getEventType(); int type = xmlEvent.getEventType();
Node top = null;
switch (type) { switch (type) {
case XMLEvent.START_ELEMENT: case XMLEvent.START_ELEMENT:
StartElement startElement = (StartElement) xmlEvent; StartElement startElement = (StartElement) xmlEvent;
@ -250,13 +249,11 @@ public class TransformerUtil {
Element docStartElement = handleStartElement(xmlEventReader, startElement, holder); Element docStartElement = handleStartElement(xmlEventReader, startElement, holder);
Node el = doc.importNode(docStartElement, true); Node el = doc.importNode(docStartElement, true);
Node top = null; if (! stack.isEmpty()) {
if (!stack.isEmpty()) {
top = stack.peek(); top = stack.peek();
} }
if (!holder.encounteredTextNode) { if (! holder.encounteredTextNode) {
stack.push(el); stack.push(el);
} }
@ -265,15 +262,15 @@ public class TransformerUtil {
else else
top.appendChild(el); top.appendChild(el);
break; break;
case XMLEvent.END_ELEMENT: case XMLEvent.END_ELEMENT:
EndElement endElement = (EndElement) xmlEvent; top = stack.pop();
String endTag = StaxParserUtil.getElementName(endElement);
if (rootTag.equals(endTag)) if (! (top instanceof Element)) {
return; // We are done with the dom parsing throw new TransformerException(ErrorCodes.UNKNOWN_END_ELEMENT);
else {
if (!stack.isEmpty())
stack.pop();
} }
if (stack.isEmpty())
return; // We are done with the dom parsing
break; break;
} }
} }

View file

@ -18,18 +18,23 @@ package org.keycloak.saml.common.util;
import org.keycloak.saml.common.exceptions.ParsingException; import org.keycloak.saml.common.exceptions.ParsingException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.NoSuchElementException;
import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Characters; import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndDocument;
import javax.xml.stream.events.EndElement; import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartDocument; import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement; import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.junit.Assert;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.CoreMatchers.*;
@ -175,4 +180,38 @@ public class StaxParserUtilTest {
reader.nextEvent(); reader.nextEvent();
} }
@Test
public void testGetDOMElementSameElements() throws XMLStreamException, ParsingException {
String xml = "<root><test><test><a>b</a></test></test></root>";
XMLEventReader reader = StaxParserUtil.getXMLEventReader(IOUtils.toInputStream(xml, Charset.defaultCharset()));
assertThat(reader.nextEvent(), instanceOf(StartDocument.class));
assertStartTag(reader.nextEvent(), "root");
Element element = StaxParserUtil.getDOMElement(reader);
assertThat(element.getNodeName(), is("test"));
assertThat(element.getChildNodes().getLength(), is(1));
assertThat(element.getChildNodes().item(0), instanceOf(Element.class));
Element e = (Element) element.getChildNodes().item(0);
assertThat(e.getNodeName(), is("test"));
assertThat(e.getChildNodes().getLength(), is(1));
assertThat(e.getChildNodes().item(0), instanceOf(Element.class));
Element e1 = (Element) e.getChildNodes().item(0);
assertThat(e1.getNodeName(), is("a"));
assertThat(e1.getChildNodes().getLength(), is(1));
assertThat(e1.getChildNodes().item(0), instanceOf(Text.class));
assertThat(((Text) e1.getChildNodes().item(0)).getWholeText(), is("b"));
assertEndTag(reader.nextEvent(), "root");
assertThat(reader.nextEvent(), instanceOf(EndDocument.class));
expectedException.expect(NoSuchElementException.class);
Assert.fail(String.valueOf(reader.nextEvent()));
}
} }