Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8915292D1 for ; Tue, 13 Mar 2012 23:24:15 +0000 (UTC) Received: (qmail 36333 invoked by uid 500); 13 Mar 2012 23:24:15 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 36283 invoked by uid 500); 13 Mar 2012 23:24:15 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 36276 invoked by uid 99); 13 Mar 2012 23:24:15 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Mar 2012 23:24:15 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 13 Mar 2012 23:24:12 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id EDA8A23889D5; Tue, 13 Mar 2012 23:23:51 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1300407 - in /cxf/branches/2.5.x-fixes: ./ common/common/src/main/java/org/apache/cxf/staxutils/ rt/core/src/main/java/org/apache/cxf/interceptor/security/ rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/ rt/frontend/jaxrs/src/... Date: Tue, 13 Mar 2012 23:23:50 -0000 To: commits@cxf.apache.org From: sergeyb@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20120313232351.EDA8A23889D5@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sergeyb Date: Tue Mar 13 23:23:50 2012 New Revision: 1300407 URL: http://svn.apache.org/viewvc?rev=1300407&view=rev Log: Merged revisions 1298470 via svnmerge from https://svn.apache.org/repos/asf/cxf/trunk ........ r1298470 | sergeyb | 2012-03-08 16:57:36 +0000 (Thu, 08 Mar 2012) | 1 line Initial commit for addressing the collision issue ........ Added: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java (with props) cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java (with props) cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java (with props) Modified: cxf/branches/2.5.x-fixes/ (props changed) cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java cxf/branches/2.5.x-fixes/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthUtils.java cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Propchange: cxf/branches/2.5.x-fixes/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Mar 13 23:23:50 2012 @@ -1 +1 @@ -/cxf/trunk:1236902,1297296,1298601-1298624,1298830,1299635,1299682,1299707,1300342 +/cxf/trunk:1236902,1297296,1298470,1298601-1298624,1298830,1299635,1299682,1299707,1300342 Propchange: cxf/branches/2.5.x-fixes/ ------------------------------------------------------------------------------ Binary property 'svnmerge-integrated' - no diff available. Added: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java?rev=1300407&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java (added) +++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java Tue Mar 13 23:23:50 2012 @@ -0,0 +1,33 @@ +/** + * 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.staxutils; + +public class DepthExceededStaxException extends RuntimeException { + + private static final long serialVersionUID = 4750070687283463619L; + + public DepthExceededStaxException() { + + } + + public DepthExceededStaxException(String message) { + super(message); + } + +} Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthExceededStaxException.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java?rev=1300407&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java (added) +++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java Tue Mar 13 23:23:50 2012 @@ -0,0 +1,73 @@ +/** + * 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.staxutils; + +import java.util.Stack; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +public class DepthRestrictingStreamReader extends DepthXMLStreamReader { + private int elementCountThreshold = -1; + private int innerElementLevelThreshold = -1; + private int innerElementCountThreshold = -1; + + private int totalElementCount; + private Stack stack = new Stack(); + + public DepthRestrictingStreamReader(XMLStreamReader reader, + int elementCountThreshold, + int innerElementLevelThreshold, + int innerElementCountThreshold) { + super(reader); + this.elementCountThreshold = elementCountThreshold; + this.innerElementLevelThreshold = innerElementLevelThreshold; + this.innerElementCountThreshold = innerElementCountThreshold; + } + + @Override + public int next() throws XMLStreamException { + int next = super.next(); + if (next == START_ELEMENT) { + if (innerElementLevelThreshold != -1 && getDepth() >= innerElementLevelThreshold) { + throw new DepthExceededStaxException(); + } + if (elementCountThreshold != -1 && ++totalElementCount >= elementCountThreshold) { + throw new DepthExceededStaxException(); + } + if (innerElementCountThreshold != -1) { + if (!stack.empty()) { + int currentCount = stack.pop(); + if (++currentCount >= innerElementCountThreshold) { + throw new DepthExceededStaxException(); + } else { + stack.push(currentCount); + } + } + stack.push(0); + } + + } else if (next == END_ELEMENT && innerElementCountThreshold != -1) { + stack.pop(); + } + return next; + } + + +} Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/DepthRestrictingStreamReader.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java (original) +++ cxf/branches/2.5.x-fixes/common/common/src/main/java/org/apache/cxf/staxutils/StaxUtils.java Tue Mar 13 23:23:50 2012 @@ -82,7 +82,9 @@ import org.apache.cxf.helpers.DOMUtils; import org.apache.cxf.helpers.XMLUtils; public final class StaxUtils { - + public static final String INNER_ELEMENT_COUNT = "org.apache.cxf.staxutils.innerElementCountThreshold"; + public static final String INNER_ELEMENT_LEVEL = "org.apache.cxf.staxutils.innerElementLevelThreshold"; + private static final Logger LOG = LogUtils.getL7dLogger(StaxUtils.class); private static final BlockingQueue NS_AWARE_INPUT_FACTORY_POOL; @@ -115,9 +117,7 @@ public final class StaxUtils { NS_AWARE_INPUT_FACTORY_POOL = new LinkedBlockingQueue(i); OUTPUT_FACTORY_POOL = new LinkedBlockingQueue(i); try { - String s = SystemPropertyAction - .getProperty("org.apache.cxf.staxutils.innerElementLevelThreshold", - "-1"); + String s = SystemPropertyAction.getProperty(INNER_ELEMENT_LEVEL, "-1"); innerElementLevelThreshold = Integer.parseInt(s); } catch (Throwable t) { innerElementLevelThreshold = -1; @@ -126,9 +126,7 @@ public final class StaxUtils { innerElementLevelThreshold = -1; } try { - String s = SystemPropertyAction - .getProperty("org.apache.cxf.staxutils.innerElementCountThreshold", - "-1"); + String s = SystemPropertyAction.getProperty(INNER_ELEMENT_COUNT, "-1"); innerElementCountThreshold = Integer.parseInt(s); } catch (Throwable t) { innerElementCountThreshold = -1; @@ -613,7 +611,7 @@ public final class StaxUtils { // We need this check because namespace writing works // different on Woodstox and the RI. if (writeElementNS) { - if (prefix == null || prefix.length() == 0) { + if (prefix.length() == 0) { writer.writeDefaultNamespace(uri); writer.setDefaultNamespace(uri); } else { @@ -770,7 +768,7 @@ public final class StaxUtils { String value = attr.getNodeValue(); if (attns == null || attns.length() == 0) { writer.writeAttribute(name, value); - } else if (attrPrefix == null || attrPrefix.length() == 0) { + } else if (attrPrefix.length() == 0) { writer.writeAttribute(attns, name, value); } else { writer.writeAttribute(attrPrefix, attns, name, value); @@ -1025,12 +1023,12 @@ public final class StaxUtils { stack.push(parent); if (isThreshold && innerElementLevelThreshold != -1 && stack.size() >= innerElementLevelThreshold) { - throw new RuntimeException("reach the innerElementLevelThreshold:" + throw new DepthExceededStaxException("reach the innerElementLevelThreshold:" + innerElementLevelThreshold); } if (isThreshold && innerElementCountThreshold != -1 && elementCount >= innerElementCountThreshold) { - throw new RuntimeException("reach the innerElementCountThreshold:" + throw new DepthExceededStaxException("reach the innerElementCountThreshold:" + innerElementCountThreshold); } parent = e; @@ -1398,14 +1396,14 @@ public final class StaxUtils { } else { writer.writeStartElement(localName); } - Iterator it = start.getNamespaces(); + Iterator it = CastUtils.cast(start.getNamespaces()); while (it != null && it.hasNext()) { - writeEvent((XMLEvent)it.next(), writer); + writeEvent(it.next(), writer); } - it = start.getAttributes(); + it = CastUtils.cast(start.getAttributes()); while (it != null && it.hasNext()) { - writeAttributeEvent((Attribute)it.next(), writer); + writeAttributeEvent(it.next(), writer); } } private static void writeAttributeEvent(XMLEvent event, XMLStreamWriter writer) Added: cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java?rev=1300407&view=auto ============================================================================== --- cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java (added) +++ cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java Tue Mar 13 23:23:50 2012 @@ -0,0 +1,134 @@ +/** + * 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.interceptor.security; + + +import java.io.InputStream; +import java.util.List; + +import javax.xml.stream.XMLStreamReader; + +import org.apache.cxf.message.Message; +import org.apache.cxf.phase.AbstractPhaseInterceptor; +import org.apache.cxf.phase.Phase; +import org.apache.cxf.staxutils.DepthRestrictingStreamReader; +import org.apache.cxf.staxutils.StaxUtils; + + +/** + * Creates an XMLStreamReader from the InputStream on the Message. + */ +public class DepthRestrictingStreamInterceptor extends AbstractPhaseInterceptor { + private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; + private static final String JSON_CONTENT_TYPE = "application/json"; + private int elementCountThreshold = 2000; + private int innerElementLevelThreshold = 20; + private int innerElementCountThreshold = 50; + + public DepthRestrictingStreamInterceptor() { + this(Phase.POST_STREAM); + } + + public DepthRestrictingStreamInterceptor(String phase) { + super(phase); + } + + public DepthRestrictingStreamInterceptor(String phase, List after) { + super(phase); + if (after != null) { + addAfter(after); + } + } + + public DepthRestrictingStreamInterceptor(String phase, List before, List after) { + this(phase, after); + if (before != null) { + addBefore(before); + } + } + + public void handleMessage(Message message) { + + if (canBeIgnored(message)) { + return; + } + + XMLStreamReader reader = null; + InputStream is = message.getContent(InputStream.class); + if (is != null) { + reader = StaxUtils.createXMLStreamReader(is); + message.setContent(InputStream.class, null); + } else { + reader = message.getContent(XMLStreamReader.class); + } + if (reader == null) { + return; + } + DepthRestrictingStreamReader dr = + new DepthRestrictingStreamReader(reader, + elementCountThreshold, + innerElementLevelThreshold, + innerElementCountThreshold); + message.setContent(XMLStreamReader.class, dr); + } + + // custom subclasses can further customize it + protected boolean canBeIgnored(Message message) { + String ct = (String)message.get(Message.CONTENT_TYPE); + return ct != null && (FORM_CONTENT_TYPE.equals(ct) || JSON_CONTENT_TYPE.equals(ct)); + } + + /** + * Sets the acceptable total number of elements in the XML payload + * @param elementCountThreshold + */ + public void setElementCountThreshold(int elementCountThreshold) { + this.elementCountThreshold = elementCountThreshold; + } + + public int getElementCountThreshold() { + return elementCountThreshold; + } + + /** + * Sets the acceptable total stack depth in the XML payload + * @param elementLevelThreshold + */ + public void setInnerElementLevelThreshold(int elementLevelThreshold) { + this.innerElementLevelThreshold = elementLevelThreshold; + } + + public int getInnerElementLevelThreshold() { + return innerElementLevelThreshold; + } + + /** + * Sets the acceptable total number of child elements for the current XML element + * @param innerElementCountThreshold + */ + public void setInnerElementCountThreshold(int innerElementCountThreshold) { + this.innerElementCountThreshold = innerElementCountThreshold; + } + + public int getInnerElementCountThreshold() { + return innerElementCountThreshold; + } + +} Propchange: cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: cxf/branches/2.5.x-fixes/rt/core/src/main/java/org/apache/cxf/interceptor/security/DepthRestrictingStreamInterceptor.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/client/WebClient.java Tue Mar 13 23:23:50 2012 @@ -18,7 +18,6 @@ */ package org.apache.cxf.jaxrs.client; -import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.Type; @@ -300,7 +299,7 @@ public class WebClient extends AbstractC */ public Response form(Map> values) { type(MediaType.APPLICATION_FORM_URLENCODED); - return doInvoke("POST", values, null, InputStream.class, InputStream.class); + return doInvoke("POST", values, null, Response.class, Response.class); } /** @@ -310,7 +309,7 @@ public class WebClient extends AbstractC */ public Response form(Form form) { type(MediaType.APPLICATION_FORM_URLENCODED); - return doInvoke("POST", form.getData(), null, InputStream.class, InputStream.class); + return doInvoke("POST", form.getData(), null, Response.class, Response.class); } /** @@ -675,7 +674,8 @@ public class WebClient extends AbstractC } headers.putSingle(HttpHeaders.CONTENT_TYPE, ct); } - if (responseClass != null && headers.getFirst(HttpHeaders.ACCEPT) == null) { + if (responseClass != null && responseClass != Response.class + && headers.getFirst(HttpHeaders.ACCEPT) == null) { headers.putSingle(HttpHeaders.ACCEPT, MediaType.APPLICATION_XML_TYPE.toString()); } resetResponse(); Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/AbstractJAXBProvider.java Tue Mar 13 23:23:50 2012 @@ -72,7 +72,9 @@ import org.apache.cxf.jaxrs.utils.Resour import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.Message; import org.apache.cxf.phase.PhaseInterceptorChain; +import org.apache.cxf.staxutils.DepthRestrictingStreamReader; import org.apache.cxf.staxutils.DepthXMLStreamReader; +import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.staxutils.transform.TransformUtils; public abstract class AbstractJAXBProvider extends AbstractConfigurableProvider @@ -607,6 +609,26 @@ public abstract class AbstractJAXBProvid true); } + protected XMLStreamReader createDepthReaderIfNeeded(XMLStreamReader reader, InputStream is) { + if (getContext() != null) { + String elementCountStr = (String)getContext().getContextualProperty( + StaxUtils.INNER_ELEMENT_COUNT); + String elementLevelStr = (String)getContext().getContextualProperty( + StaxUtils.INNER_ELEMENT_LEVEL); + if (elementCountStr != null || elementLevelStr != null) { + try { + int elementLevel = elementLevelStr != null ? Integer.valueOf(elementLevelStr) : -1; + int elementCount = elementCountStr != null ? Integer.valueOf(elementCountStr) : -1; + reader = TransformUtils.createNewReaderIfNeeded(reader, is); + reader = new DepthRestrictingStreamReader(reader, -1, elementLevel, elementCount); + } catch (Exception ex) { + throw new WebApplicationException(ex); + } + } + } + return reader; + } + public void setValidateBeforeWrite(boolean validateBeforeWrite) { this.validateBeforeWrite = validateBeforeWrite; } Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/FormEncodingProvider.java Tue Mar 13 23:23:50 2012 @@ -157,10 +157,12 @@ public class FormEncodingProvider implem if (mt.isCompatible(MediaType.MULTIPART_FORM_DATA_TYPE)) { MultipartBody body = AttachmentUtils.getMultipartBody(mc, attachmentDir, attachmentThreshold, attachmentMaxSize); - FormUtils.populateMapFromMultipart(params, body, decode); + FormUtils.populateMapFromMultipart(params, body, PhaseInterceptorChain.getCurrentMessage(), + decode); } else { String enc = HttpUtils.getEncoding(mt, "UTF-8"); - FormUtils.populateMapFromString(params, + FormUtils.populateMapFromString(params, + PhaseInterceptorChain.getCurrentMessage(), FormUtils.readBody(is, enc), enc, decode, Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JAXBElementProvider.java Tue Mar 13 23:23:50 2012 @@ -68,6 +68,7 @@ import org.apache.cxf.jaxrs.utils.JAXBUt import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.Attachment; import org.apache.cxf.message.Message; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.staxutils.transform.TransformUtils; @@ -184,6 +185,8 @@ public class JAXBElementProvider extends } catch (JAXBException e) { handleJAXBException(e, true); + } catch (DepthExceededStaxException e) { + throw new WebApplicationException(413); } catch (WebApplicationException e) { throw e; } catch (Exception e) { @@ -223,6 +226,7 @@ public class JAXBElementProvider extends } reader = createTransformReaderIfNeeded(reader, is); + reader = createDepthReaderIfNeeded(reader, is); if (InjectionUtils.isSupportedCollectionOrArray(type)) { return new JAXBCollectionWrapperReader(TransformUtils.createNewReaderIfNeeded(reader, is)); } else { Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/JSONProvider.java Tue Mar 13 23:23:50 2012 @@ -65,6 +65,7 @@ import org.apache.cxf.jaxrs.utils.Inject import org.apache.cxf.jaxrs.utils.JAXBUtils; import org.apache.cxf.jaxrs.utils.schemas.SchemaHandler; import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.staxutils.DepthExceededStaxException; import org.apache.cxf.staxutils.StaxUtils; import org.apache.cxf.staxutils.W3CDOMStreamWriter; import org.codehaus.jettison.mapped.Configuration; @@ -232,6 +233,8 @@ public class JSONProvider extends Abstra } catch (JAXBException e) { handleJAXBException(e, true); + } catch (DepthExceededStaxException e) { + throw new WebApplicationException(413); } catch (XMLStreamException e) { throw new WebApplicationException(e); } catch (WebApplicationException e) { @@ -251,12 +254,16 @@ public class JSONProvider extends Abstra protected XMLStreamReader createReader(Class type, InputStream is) throws Exception { + XMLStreamReader reader = null; if (BADGER_FISH_CONVENTION.equals(convention)) { - return JSONUtils.createBadgerFishReader(is); + reader = JSONUtils.createBadgerFishReader(is); } else { - XMLStreamReader reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap); - return createTransformReaderIfNeeded(reader, is); + reader = JSONUtils.createStreamReader(is, readXsiType, namespaceMap); } + reader = createTransformReaderIfNeeded(reader, is); + reader = createDepthReaderIfNeeded(reader, is); + + return reader; } protected InputStream getInputStream(Class cls, Type type, InputStream is) throws Exception { Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java Tue Mar 13 23:23:50 2012 @@ -41,6 +41,7 @@ import org.apache.cxf.interceptor.Loggin import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.apache.cxf.jaxrs.ext.multipart.ContentDisposition; import org.apache.cxf.jaxrs.ext.multipart.MultipartBody; +import org.apache.cxf.message.Message; import org.apache.cxf.phase.PhaseInterceptorChain; public final class FormUtils { @@ -48,6 +49,7 @@ public final class FormUtils { private static final Logger LOG = LogUtils.getL7dLogger(FormUtils.class); private static final String MULTIPART_FORM_DATA_TYPE = "form-data"; + private static final String MAX_FORM_PARAM_COUNT = "org.apache.cxf.form.maxParameterCount"; private FormUtils() { @@ -77,13 +79,15 @@ public final class FormUtils { } } - public static void populateMapFromString(MultivaluedMap params, + public static void populateMapFromString(MultivaluedMap params, + Message m, String postBody, String enc, boolean decode, HttpServletRequest request) { if (!StringUtils.isEmpty(postBody)) { List parts = Arrays.asList(postBody.split("&")); + checkNumberOfParts(m, parts.size()); for (String part : parts) { String[] keyValue = new String[2]; int index = part.indexOf("="); @@ -145,9 +149,11 @@ public final class FormUtils { } public static void populateMapFromMultipart(MultivaluedMap params, - MultipartBody body, + MultipartBody body, + Message m, boolean decode) { List atts = body.getAllAttachments(); + checkNumberOfParts(m, atts.size()); for (Attachment a : atts) { ContentDisposition cd = a.getContentDisposition(); if (cd != null && !MULTIPART_FORM_DATA_TYPE.equalsIgnoreCase(cd.getType())) { @@ -168,4 +174,23 @@ public final class FormUtils { } } } + + private static void checkNumberOfParts(Message m, int numberOfParts) { + if (m == null || m.getExchange() == null || m.getExchange().getInMessage() == null) { + return; + } + String maxPartsCountProp = (String)m.getExchange() + .getInMessage().getContextualProperty(MAX_FORM_PARAM_COUNT); + if (maxPartsCountProp == null) { + return; + } + try { + int maxPartsCount = Integer.valueOf(maxPartsCountProp); + if (maxPartsCount != -1 && numberOfParts >= maxPartsCount) { + throw new WebApplicationException(413); + } + } catch (NumberFormatException ex) { + throw new WebApplicationException(500); + } + } } Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java Tue Mar 13 23:23:50 2012 @@ -739,12 +739,12 @@ public final class JAXRSUtils { String enc = HttpUtils.getEncoding(mt, "UTF-8"); String body = FormUtils.readBody(m.getContent(InputStream.class), enc); HttpServletRequest request = (HttpServletRequest)m.get(AbstractHTTPDestination.HTTP_REQUEST); - FormUtils.populateMapFromString(params, (String)body, enc, decode, request); + FormUtils.populateMapFromString(params, m, (String)body, enc, decode, request); } else { if (mt != null && "multipart".equalsIgnoreCase(mt.getType()) && MediaType.MULTIPART_FORM_DATA_TYPE.isCompatible(mt)) { MultipartBody body = AttachmentUtils.getMultipartBody(mc); - FormUtils.populateMapFromMultipart(params, body, decode); + FormUtils.populateMapFromMultipart(params, body, m, decode); } else { org.apache.cxf.common.i18n.Message errorMsg = new org.apache.cxf.common.i18n.Message("WRONG_FORM_MEDIA_TYPE", Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/multipart/AttachmentUtils.java Tue Mar 13 23:23:50 2012 @@ -41,6 +41,7 @@ import org.apache.cxf.jaxrs.ext.multipar import org.apache.cxf.jaxrs.impl.MetadataMap; import org.apache.cxf.jaxrs.utils.FormUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; +import org.apache.cxf.phase.PhaseInterceptorChain; public final class AttachmentUtils { private static final Logger LOG = LogUtils.getL7dLogger(JAXRSUtils.class); @@ -143,6 +144,7 @@ public final class AttachmentUtils { MultivaluedMap data = new MetadataMap(); FormUtils.populateMapFromMultipart((MultivaluedMap)data, AttachmentUtils.getMultipartBody(mc), + PhaseInterceptorChain.getCurrentMessage(), true); return data; } Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/SelectMethodCandidatesTest.java Tue Mar 13 23:23:50 2012 @@ -91,6 +91,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); @@ -137,6 +141,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); @@ -180,6 +188,10 @@ public class SelectMethodCandidatesTest ex.setInMessage(m); m.setExchange(ex); Endpoint e = EasyMock.createMock(Endpoint.class); + e.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + e.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); e.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(ProviderFactory.getInstance()).times(2); e.get("org.apache.cxf.jaxrs.comparator"); Modified: cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java (original) +++ cxf/branches/2.5.x-fixes/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/client/ResponseReaderTest.java Tue Mar 13 23:23:50 2012 @@ -59,6 +59,10 @@ public class ResponseReaderTest extends ProviderFactory instance = ProviderFactory.getInstance(); Endpoint endpoint = EasyMock.createMock(Endpoint.class); + endpoint.size(); + EasyMock.expectLastCall().andReturn(0).anyTimes(); + endpoint.getEndpointInfo(); + EasyMock.expectLastCall().andReturn(null).anyTimes(); endpoint.get(ProviderFactory.class.getName()); EasyMock.expectLastCall().andReturn(instance).anyTimes(); EasyMock.replay(endpoint); Modified: cxf/branches/2.5.x-fixes/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthUtils.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthUtils.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthUtils.java (original) +++ cxf/branches/2.5.x-fixes/rt/rs/security/oauth-parent/oauth/src/main/java/org/apache/cxf/rs/security/oauth/utils/OAuthUtils.java Tue Mar 13 23:23:50 2012 @@ -49,6 +49,7 @@ import org.apache.cxf.jaxrs.ext.MessageC import org.apache.cxf.jaxrs.impl.MetadataMap; import org.apache.cxf.jaxrs.model.URITemplate; import org.apache.cxf.jaxrs.utils.FormUtils; +import org.apache.cxf.phase.PhaseInterceptorChain; import org.apache.cxf.rs.security.oauth.data.Client; import org.apache.cxf.rs.security.oauth.data.RequestToken; import org.apache.cxf.rs.security.oauth.data.Token; @@ -127,7 +128,8 @@ public final class OAuthUtils { ? mc.getContent(InputStream.class) : oAuthMessage.getBodyAsStream(); String body = FormUtils.readBody(stream, enc); MultivaluedMap map = new MetadataMap(); - FormUtils.populateMapFromString(map, body, enc, true, request); + FormUtils.populateMapFromString(map, PhaseInterceptorChain.getCurrentMessage(), body, enc, true, + request); for (String key : map.keySet()) { oAuthMessage.addParameter(key, map.getFirst(key)); } Modified: cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java (original) +++ cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreSpring.java Tue Mar 13 23:23:50 2012 @@ -35,6 +35,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriInfo; @@ -135,7 +136,21 @@ public class BookStoreSpring { @GET public Book getDefaultBook() { return books.get(mainId); - } + } + + @POST + @Path("depth") + @Produces({"application/xml", "application/json" }) + @Consumes({"application/xml", "application/json" }) + public Book echoBook(Book book) { + return book; + } + + @POST + @Path("depth-form") + @Consumes(MediaType.APPLICATION_FORM_URLENCODED) + public void depthForm(MultivaluedMap map) { + } @POST @Path("books/convert") Modified: cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java (original) +++ cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerSpringBookTest.java Tue Mar 13 23:23:50 2012 @@ -48,6 +48,7 @@ import org.apache.cxf.helpers.IOUtils; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.jaxrs.client.JAXRSClientFactory; import org.apache.cxf.jaxrs.client.WebClient; +import org.apache.cxf.jaxrs.ext.form.Form; import org.apache.cxf.jaxrs.ext.xml.XMLSource; import org.apache.cxf.jaxrs.model.wadl.WadlGenerator; import org.apache.cxf.jaxrs.provider.AegisElementProvider; @@ -221,6 +222,36 @@ public class JAXRSClientServerSpringBook "application/vnd.example-com.foo+json"); } + @Test + public void testBookDepthExceededXML() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth"; + WebClient wc = WebClient.create(endpointAddress); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testBookDepthExceededJettison() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks10/depth"; + WebClient wc = WebClient.create(endpointAddress); + wc.accept("application/json").type("application/json"); + Response r = wc.post(new Book("CXF", 123L)); + assertEquals(413, r.getStatus()); + } + + @Test + public void testTooManyFormParams() throws Exception { + String endpointAddress = + "http://localhost:" + PORT + "/the/thebooks9/depth-form"; + WebClient wc = WebClient.create(endpointAddress); + Response r = wc.form(new Form().set("a", "b")); + assertEquals(204, r.getStatus()); + r = wc.form(new Form().set("a", "b").set("c", "b")); + assertEquals(413, r.getStatus()); + } + @Test public void testGetBookJsonp() throws Exception { Modified: cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml URL: http://svn.apache.org/viewvc/cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml?rev=1300407&r1=1300406&r2=1300407&view=diff ============================================================================== --- cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml (original) +++ cxf/branches/2.5.x-fixes/systests/jaxrs/src/test/resources/jaxrs/WEB-INF/beans.xml Tue Mar 13 23:23:50 2012 @@ -199,6 +199,33 @@ http://cxf.apache.org/schemas/core.xsd"> + + + + + + + + + + + + + + + + + + + + + + + + +