Author: ffang
Date: Thu Dec 30 07:44:06 2010
New Revision: 1053815
URL: http://svn.apache.org/viewvc?rev=1053815&view=rev
Log:
[CXF-3223]introduce a threshold system property for staxutils to avoid parsing
message with unreasonable inner element level
Added:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/DispatchClientServerWithHugeResponseTest.java
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/HugeResponseInterceptor.java
Modified:
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=1053815&r1=1053814&r2=1053815&view=diff
==============================================================================
---
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
(original)
+++
cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java
Thu Dec 30 07:44:06 2010
@@ -94,6 +94,8 @@ public final class StaxUtils {
"ns7".intern(), "ns8".intern(), "ns9".intern()
};
+ private static int innerElementLevelThreshold = -1;
+
static {
int i = 20;
@@ -110,6 +112,17 @@ public final class StaxUtils {
}
NS_AWARE_INPUT_FACTORY_POOL = new
LinkedBlockingQueue<XMLInputFactory>(i);
OUTPUT_FACTORY_POOL = new LinkedBlockingQueue<XMLOutputFactory>(i);
+ try {
+ String s =
System.getProperty("org.apache.cxf.staxutils.innerElementLevelThreshold",
+ "-1");
+ innerElementLevelThreshold = Integer.parseInt(s);
+ } catch (Throwable t) {
+ innerElementLevelThreshold = -1;
+ }
+ if (innerElementLevelThreshold <= 0) {
+ innerElementLevelThreshold = -1;
+ }
+
}
private StaxUtils() {
@@ -501,8 +514,6 @@ public final class StaxUtils {
prefix = "";
}
-
-// System.out.println("STAXUTILS:writeStartElement : node name : " +
local + " namespace URI" + uri);
boolean writeElementNS = false;
if (uri != null) {
@@ -655,8 +666,6 @@ public final class StaxUtils {
String ns = e.getNamespaceURI();
String localName = e.getLocalName();
-
-// System.out.println("local name : " + localName + " URI: " + ns + "
Prefix :" + prefix);
if (prefix == null) {
prefix = "";
}
@@ -677,8 +686,6 @@ public final class StaxUtils {
declareNamespace = false;
}
} else {
-// System.out.println("Calling writeStartElement for local name : "
-// + localName + " URI: " + ns + " Prefix :" + prefix);
writer.writeStartElement(prefix, localName, ns);
}
@@ -696,8 +703,6 @@ public final class StaxUtils {
}
if ("xmlns".equals(attrPrefix)) {
-// System.out.println("WriteNamespace is called for prefix : "
-// + name + " namespace :" + attr.getNodeValue());
writer.writeNamespace(name, attr.getNodeValue());
writer.setPrefix(name, attr.getNodeValue());
if (name.equals(prefix) && attr.getNodeValue().equals(ns)) {
@@ -897,12 +902,20 @@ public final class StaxUtils {
}
return false;
}
+
public static void readDocElements(Node parent, XMLStreamReader reader,
boolean repairing)
throws XMLStreamException {
Document doc = getDocument(parent);
readDocElements(doc, parent, reader, repairing, false);
}
+ public static void readDocElements(Node parent, XMLStreamReader reader,
boolean repairing,
+ boolean isThreshold)
+ throws XMLStreamException {
+ Document doc = getDocument(parent);
+ readDocElements(doc, parent, reader, repairing, false, isThreshold);
+ }
+
/**
* @param parent
* @param reader
@@ -911,7 +924,18 @@ public final class StaxUtils {
public static void readDocElements(Document doc, Node parent,
XMLStreamReader reader, boolean
repairing, boolean recordLoc)
throws XMLStreamException {
-
+ readDocElements(doc, parent, reader, repairing, recordLoc, false);
+ }
+
+ /**
+ * @param parent
+ * @param reader
+ * @throws XMLStreamException
+ */
+ public static void readDocElements(Document doc, Node parent,
+ XMLStreamReader reader, boolean
repairing, boolean recordLoc,
+ boolean isThreshold)
+ throws XMLStreamException {
Stack<Node> stack = new Stack<Node>();
int event = reader.getEventType();
while (reader.hasNext()) {
@@ -947,11 +971,12 @@ public final class StaxUtils {
declare(e, reader.getNamespaceURI(), reader.getPrefix());
}
stack.push(parent);
+ if (isThreshold && innerElementLevelThreshold != -1
+ && stack.size() >= innerElementLevelThreshold) {
+ throw new RuntimeException("reach the
innerElementLevelThreshold:"
+ + innerElementLevelThreshold);
+ }
parent = e;
-
- //event = reader.next();
- //readDocElements(doc, e, reader, repairing, recordLoc);
-
break;
}
case XMLStreamConstants.END_ELEMENT:
Modified:
cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java?rev=1053815&r1=1053814&r2=1053815&view=diff
==============================================================================
---
cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
(original)
+++
cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
Thu Dec 30 07:44:06 2010
@@ -182,7 +182,7 @@ public class SAAJInInterceptor extends A
DOMSource bodySource = new DOMSource(soapFault);
xmlReader = StaxUtils.createXMLStreamReader(bodySource);
} else {
- StaxUtils.readDocElements(soapMessage.getSOAPBody(),
xmlReader, true);
+ StaxUtils.readDocElements(soapMessage.getSOAPBody(),
xmlReader, true, true);
DOMSource bodySource = new
DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
xmlReader = StaxUtils.createXMLStreamReader(bodySource);
xmlReader.nextTag();
Modified:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/DispatchClientServerWithHugeResponseTest.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/DispatchClientServerWithHugeResponseTest.java?rev=1053815&r1=1053814&r2=1053815&view=diff
==============================================================================
---
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/DispatchClientServerWithHugeResponseTest.java
(original)
+++
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/DispatchClientServerWithHugeResponseTest.java
Thu Dec 30 07:44:06 2010
@@ -87,16 +87,17 @@ public class DispatchClientServerWithHug
@org.junit.Before
public void setUp() {
+
System.setProperty("org.apache.cxf.staxutils.innerElementLevelThreshold", "12");
BusFactory.getDefaultBus().getOutInterceptors().add(new
LoggingOutInterceptor());
BusFactory.getDefaultBus().getInInterceptors().add(new
LoggingInInterceptor());
- BusFactory.getDefaultBus().getInInterceptors().add(new
HugeResponseInterceptor());
}
@Test
- public void testSOAPMessageWithHugeResponse() throws Exception {
-
+ public void testStackOverflowErrorForSOAPMessageWithHugeResponse() throws
Exception {
+ HugeResponseInterceptor hugeResponseInterceptor = new
HugeResponseInterceptor(true);
+
BusFactory.getDefaultBus().getInInterceptors().add(hugeResponseInterceptor);
URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
assertNotNull(wsdl);
@@ -123,9 +124,46 @@ public class DispatchClientServerWithHug
+ "should get some exception tell me stackoverflow");
} catch (Throwable e) {
assertTrue(e.getCause() instanceof StackOverflowError);
+ } finally {
+
BusFactory.getDefaultBus().getInInterceptors().remove(hugeResponseInterceptor);
}
}
+ @Test
+ public void testThresholdfForSOAPMessageWithHugeResponse() throws
Exception {
+ HugeResponseInterceptor hugeResponseInterceptor = new
HugeResponseInterceptor(false);
+
BusFactory.getDefaultBus().getInInterceptors().add(hugeResponseInterceptor);
+ URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
+ assertNotNull(wsdl);
+
+ SOAPService service = new SOAPService(wsdl, SERVICE_NAME);
+ assertNotNull(service);
+
+ Dispatch<SOAPMessage> disp = service
+ .createDispatch(PORT_NAME, SOAPMessage.class,
Service.Mode.MESSAGE);
+ disp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
+ "http://localhost:"
+ + greeterPort
+ +
"/SOAPDispatchService/SoapDispatchPort");
+
+
+
+ InputStream is3 =
getClass().getResourceAsStream("resources/GreetMeDocLiteralReq3.xml");
+ SOAPMessage soapReqMsg3 =
MessageFactory.newInstance().createMessage(null, is3);
+ assertNotNull(soapReqMsg3);
+ Response<SOAPMessage> response = disp.invokeAsync(soapReqMsg3);
+ try {
+ response.get(300, TimeUnit.SECONDS);
+ } catch (TimeoutException te) {
+ fail("We should not have encountered a timeout, "
+ + "should get some exception tell me stackoverflow");
+ } catch (Throwable e) {
+ assertTrue(e.getCause().getMessage().startsWith("reach the
innerElementLevelThreshold"));
+ } finally {
+
BusFactory.getDefaultBus().getInInterceptors().remove(hugeResponseInterceptor);
+ }
+
+ }
}
Modified:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/HugeResponseInterceptor.java
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/HugeResponseInterceptor.java?rev=1053815&r1=1053814&r2=1053815&view=diff
==============================================================================
---
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/HugeResponseInterceptor.java
(original)
+++
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/HugeResponseInterceptor.java
Thu Dec 30 07:44:06 2010
@@ -19,21 +19,47 @@
package org.apache.cxf.systest.dispatch;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.interceptor.LoggingInInterceptor;
+import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
public class HugeResponseInterceptor extends AbstractPhaseInterceptor<Message>
{
+ private boolean isStackOverFlow;
- public HugeResponseInterceptor() {
+ public HugeResponseInterceptor(boolean isStackOverFlow) {
super(Phase.RECEIVE);
addAfter(LoggingInInterceptor.class.getName());
+ this.isStackOverFlow = isStackOverFlow;
}
public void handleMessage(Message message) throws Fault {
- throw new StackOverflowError();
+ if (isStackOverFlow) {
+ throw new StackOverflowError();
+ } else {
+ InputStream is = message.getContent(InputStream.class);
+ if (is != null) {
+ CachedOutputStream bos = new CachedOutputStream();
+ try {
+ is = getClass().getClassLoader().getResourceAsStream(
+
"org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml");
+ IOUtils.copy(is, bos);
+ bos.flush();
+ is.close();
+ message.setContent(InputStream.class,
bos.getInputStream());
+ bos.close();
+ message.setContent(InputStream.class,
bos.getInputStream());
+ } catch (IOException e) {
+ throw new Fault(e);
+ }
+ }
+ }
}
}
Added:
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml
URL:
http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml?rev=1053815&view=auto
==============================================================================
---
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml
(added)
+++
cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakThreshold.xml
Thu Dec 30 07:44:06 2010
@@ -0,0 +1 @@
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><a
xmlns="http://apache.org/hello_world_soap_http/types"><a0><a1><a2><a3><a4><a5><a6><a7><a8><a9><a10><a11><a12></a12></a11></a10></a9></a8></a7></a6></a5></a4></a3></a2></a1></a0></a></SOAP-ENV:Body></SOAP-ENV:Envelope>