You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ff...@apache.org on 2011/02/23 09:14:54 UTC

svn commit: r1073631 - in /cxf/trunk: common/common/src/main/java/org/apache/cxf/staxutils/ systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/ systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/

Author: ffang
Date: Wed Feb 23 08:14:53 2011
New Revision: 1073631

URL: http://svn.apache.org/viewvc?rev=1073631&view=rev
Log:
[CXF-3359]introduce a threshold system property for staxutils to avoid parsing message with unreasonable element count

Added:
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/ResponseInterceptorType.java
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakElementCountThreshold.xml
Modified:
    cxf/trunk/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.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=1073631&r1=1073630&r2=1073631&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 Wed Feb 23 08:14:53 2011
@@ -95,6 +95,7 @@ public final class StaxUtils {
     };
     
     private static int innerElementLevelThreshold = -1;
+    private static int innerElementCountThreshold = -1;
     
     static {
         int i = 20;
@@ -122,6 +123,17 @@ public final class StaxUtils {
         if (innerElementLevelThreshold <= 0) {
             innerElementLevelThreshold = -1;
         }
+        try {
+            String s =  System.getProperty("org.apache.cxf.staxutils.innerElementCountThreshold",
+                                    "-1");
+            innerElementCountThreshold = Integer.parseInt(s);
+        } catch (Throwable t) {
+            innerElementCountThreshold = -1;
+        }
+        if (innerElementCountThreshold <= 0) {
+            innerElementCountThreshold = -1;
+        }
+        
         
     }
     
@@ -938,9 +950,11 @@ public final class StaxUtils {
         throws XMLStreamException {
         Stack<Node> stack = new Stack<Node>();
         int event = reader.getEventType();
+        int elementCount = 0;
         while (reader.hasNext()) {
             switch (event) {
             case XMLStreamConstants.START_ELEMENT: {
+                elementCount++;
                 Element e = doc.createElementNS(reader.getNamespaceURI(), reader.getLocalName());
                 if (reader.getPrefix() != null) {
                     e.setPrefix(reader.getPrefix());
@@ -976,6 +990,11 @@ public final class StaxUtils {
                     throw new RuntimeException("reach the innerElementLevelThreshold:" 
                                                + innerElementLevelThreshold);
                 }
+                if (isThreshold && innerElementCountThreshold != -1 
+                    && elementCount >= innerElementCountThreshold) {
+                    throw new RuntimeException("reach the innerElementCountThreshold:" 
+                                               + innerElementCountThreshold);
+                }
                 parent = e;
                 break;
             }

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=1073631&r1=1073630&r2=1073631&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 Wed Feb 23 08:14:53 2011
@@ -88,6 +88,7 @@ public class DispatchClientServerWithHug
     @org.junit.Before
     public void setUp() {
         System.setProperty("org.apache.cxf.staxutils.innerElementLevelThreshold", "12");
+        System.setProperty("org.apache.cxf.staxutils.innerElementCountThreshold", "12");
         BusFactory.getDefaultBus().getOutInterceptors().add(new LoggingOutInterceptor());
         BusFactory.getDefaultBus().getInInterceptors().add(new LoggingInInterceptor());
     }
@@ -96,7 +97,8 @@ public class DispatchClientServerWithHug
    
     @Test
     public void testStackOverflowErrorForSOAPMessageWithHugeResponse() throws Exception {
-        HugeResponseInterceptor hugeResponseInterceptor = new HugeResponseInterceptor(true);
+        HugeResponseInterceptor hugeResponseInterceptor = 
+            new HugeResponseInterceptor(ResponseInterceptorType.overflow);
         BusFactory.getDefaultBus().getInInterceptors().add(hugeResponseInterceptor);
         URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
         assertNotNull(wsdl);
@@ -132,7 +134,8 @@ public class DispatchClientServerWithHug
      
     @Test
     public void testThresholdfForSOAPMessageWithHugeResponse() throws Exception {
-        HugeResponseInterceptor hugeResponseInterceptor = new HugeResponseInterceptor(false);
+        HugeResponseInterceptor hugeResponseInterceptor = 
+            new HugeResponseInterceptor(ResponseInterceptorType.ElementLevelThreshold);
         BusFactory.getDefaultBus().getInInterceptors().add(hugeResponseInterceptor);
         URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
         assertNotNull(wsdl);
@@ -166,4 +169,41 @@ public class DispatchClientServerWithHug
         
     }
 
+    @Test
+    public void testElementCountThresholdfForSOAPMessageWithHugeResponse() throws Exception {
+        HugeResponseInterceptor hugeResponseInterceptor = 
+            new HugeResponseInterceptor(ResponseInterceptorType.ElementCountThreshold);
+        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);
+            fail("should catch exception");
+        } 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 innerElementCountThreshold"));
+        } 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=1073631&r1=1073630&r2=1073631&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 Wed Feb 23 08:14:53 2011
@@ -31,18 +31,18 @@ import org.apache.cxf.phase.AbstractPhas
 import org.apache.cxf.phase.Phase;
 
 public class HugeResponseInterceptor extends AbstractPhaseInterceptor<Message> {
-    private boolean isStackOverFlow;
+    private ResponseInterceptorType type;
 
-    public HugeResponseInterceptor(boolean isStackOverFlow) {
+    public HugeResponseInterceptor(ResponseInterceptorType type) {
         super(Phase.RECEIVE);
         addAfter(LoggingInInterceptor.class.getName());
-        this.isStackOverFlow = isStackOverFlow;
+        this.type = type;
     }
 
     public void handleMessage(Message message) throws Fault {
-        if (isStackOverFlow) {
+        if (type.equals(ResponseInterceptorType.overflow)) {
             throw new StackOverflowError();
-        } else {
+        } else  if (type.equals(ResponseInterceptorType.ElementLevelThreshold)) {
             InputStream is = message.getContent(InputStream.class);
             if (is != null) {
                 CachedOutputStream bos = new CachedOutputStream();
@@ -59,6 +59,24 @@ public class HugeResponseInterceptor ext
                     throw new Fault(e);
                 }
             }
+        } else  if (type.equals(ResponseInterceptorType.ElementCountThreshold)) {
+            InputStream is = message.getContent(InputStream.class);
+            if (is != null) {
+                CachedOutputStream bos = new CachedOutputStream();
+                try {
+                    is = getClass().getClassLoader().getResourceAsStream(
+                        "org/apache/cxf/systest/dispatch/resources/" 
+                        + "GreetMeDocLiteralRespBreakElementCountThreshold.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/ResponseInterceptorType.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/ResponseInterceptorType.java?rev=1073631&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/ResponseInterceptorType.java (added)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/ResponseInterceptorType.java Wed Feb 23 08:14:53 2011
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.dispatch;
+
+public enum ResponseInterceptorType {
+    overflow,
+    ElementLevelThreshold,
+    ElementCountThreshold
+}

Added: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakElementCountThreshold.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakElementCountThreshold.xml?rev=1073631&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakElementCountThreshold.xml (added)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/dispatch/resources/GreetMeDocLiteralRespBreakElementCountThreshold.xml Wed Feb 23 08:14:53 2011
@@ -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/></a></SOAP-ENV:Body></SOAP-ENV:Envelope>