This is an automated email from the ASF dual-hosted git repository.

reta pushed a commit to branch 3.6.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git

commit b279f743d3d766e1d017a33ce91224386af0e786
Author: Andriy Redko <[email protected]>
AuthorDate: Thu Sep 10 18:39:41 2026 -0400

    Add maxFormParameterSize contextual message parameter and bound form params 
processing to it (#3457)
    
    (cherry picked from commit c9f8dc497879b5a2eca2a51a6d21f80966d534a1)
---
 .../cxf/jaxrs/impl/HttpServletRequestFilter.java   |  3 ++-
 .../java/org/apache/cxf/jaxrs/utils/FormUtils.java |  5 +++++
 .../org/apache/cxf/jaxrs/utils/JAXRSUtils.java     |  2 +-
 .../oauth2/client/ClientCodeRequestFilter.java     |  7 +++++--
 .../security/oidc/rp/OidcIdTokenRequestFilter.java |  7 +++++--
 .../oidc/rp/OidcRpAuthenticationFilter.java        |  7 +++++--
 .../systest/jaxrs/JAXRSClientServerBookTest.java   | 24 ++++++++++++++++++++++
 7 files changed, 47 insertions(+), 8 deletions(-)

diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
index 7b7eea6f3a0..754a62254b9 100644
--- 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
+++ 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/HttpServletRequestFilter.java
@@ -120,7 +120,8 @@ public class HttpServletRequestFilter extends 
HttpServletRequestWrapper {
                 formParams = new MetadataMap<>();
                 MediaType mt = 
JAXRSUtils.toMediaType((String)m.get(Message.CONTENT_TYPE));
                 String enc = HttpUtils.getEncoding(mt, 
StandardCharsets.UTF_8.name());
-                String body = 
FormUtils.readBody(m.getContent(InputStream.class), enc);
+                String body = 
FormUtils.readBody(m.getContent(InputStream.class), enc,
+                        FormUtils.getMaxFormParamsSize(m));
                 FormUtils.populateMapFromString(formParams, m, body, enc, 
true);
             }
         }
diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
index a360717c664..f2dbb71c160 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/FormUtils.java
@@ -67,6 +67,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 = "maxFormParameterCount";
+    private static final String MAX_FORM_PARAM_SIZE = "maxFormParameterSize";
     private static final String CONTENT_DISPOSITION_FILES_PARAM = "files";
     private FormUtils() {
 
@@ -316,4 +317,8 @@ public final class FormUtils {
         return 
MediaType.APPLICATION_FORM_URLENCODED.equals(m.get(Message.CONTENT_TYPE))
             && HttpMethod.POST.equals(m.get(Message.HTTP_REQUEST_METHOD));
     }
+
+    public static int getMaxFormParamsSize(Message m) {
+        return MessageUtils.getContextualInteger(m, MAX_FORM_PARAM_SIZE, 
DEFAULT_FORM_PARAMS_MAX_SIZE);
+    }
 }
diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
index 3307d54b332..8a59b27cb12 100644
--- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
+++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/JAXRSUtils.java
@@ -1195,7 +1195,7 @@ public final class JAXRSUtils {
 
             if (mt == null || 
mt.isCompatible(MediaType.APPLICATION_FORM_URLENCODED_TYPE)) {
                 InputStream entityStream = copyAndGetEntityStream(m);
-                String body = FormUtils.readBody(entityStream, enc);
+                String body = FormUtils.readBody(entityStream, enc, 
FormUtils.getMaxFormParamsSize(m));
                 // Do not decode unless the key is empty value, fe 
@FormParam("")
                 FormUtils.populateMapFromStringOrHttpRequest(params, m, body, 
enc, StringUtils.isEmpty(key) && decode);
             } else {
diff --git 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
index f3261f26196..168747f7ec4 100644
--- 
a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
+++ 
b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/client/ClientCodeRequestFilter.java
@@ -45,6 +45,7 @@ import org.apache.cxf.jaxrs.impl.MetadataMap;
 import org.apache.cxf.jaxrs.utils.ExceptionUtils;
 import org.apache.cxf.jaxrs.utils.FormUtils;
 import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
 import org.apache.cxf.rs.security.oauth2.common.ClientAccessToken;
 import org.apache.cxf.rs.security.oauth2.grants.code.AuthorizationCodeGrant;
 import org.apache.cxf.rs.security.oauth2.grants.code.CodeVerifierTransformer;
@@ -312,8 +313,10 @@ public class ClientCodeRequestFilter implements 
ContainerRequestFilter {
         MultivaluedMap<String, String> requestState = new MetadataMap<>();
         requestState.putAll(ui.getQueryParameters(decodeRequestParameters));
         if 
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
-            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name());
-            FormUtils.populateMapFromString(requestState, 
JAXRSUtils.getCurrentMessage(), body,
+            final Message currentMessage = JAXRSUtils.getCurrentMessage();
+            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name(),
+                    FormUtils.getMaxFormParamsSize(currentMessage));
+            FormUtils.populateMapFromString(requestState, currentMessage, body,
                                             StandardCharsets.UTF_8.name(), 
decodeRequestParameters);
         }
         return requestState;
diff --git 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
index 04126ce9614..123cb5b5c8b 100644
--- 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
+++ 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcIdTokenRequestFilter.java
@@ -32,6 +32,7 @@ import org.apache.cxf.common.util.StringUtils;
 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.message.Message;
 import org.apache.cxf.rs.security.oauth2.client.Consumer;
 import org.apache.cxf.rs.security.oidc.common.IdToken;
 
@@ -61,8 +62,10 @@ public class OidcIdTokenRequestFilter implements 
ContainerRequestFilter {
     private MultivaluedMap<String, String> toFormData(ContainerRequestContext 
rc) {
         MultivaluedMap<String, String> requestState = new MetadataMap<>();
         if 
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
-            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name());
-            FormUtils.populateMapFromString(requestState, 
JAXRSUtils.getCurrentMessage(), body,
+            final Message currentMessage = JAXRSUtils.getCurrentMessage();
+            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name(),
+                    FormUtils.getMaxFormParamsSize(currentMessage));
+            FormUtils.populateMapFromString(requestState, currentMessage, body,
                                             StandardCharsets.UTF_8.name(), 
false);
             rc.setEntityStream(new 
ByteArrayInputStream(StringUtils.toBytesUTF8(body)));
         }
diff --git 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
index 28579c9645e..f9b443a048a 100644
--- 
a/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
+++ 
b/rt/rs/security/sso/oidc/src/main/java/org/apache/cxf/rs/security/oidc/rp/OidcRpAuthenticationFilter.java
@@ -40,6 +40,7 @@ import org.apache.cxf.jaxrs.ext.MessageContextImpl;
 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.message.Message;
 import org.apache.cxf.rs.security.jose.jwt.JwtException;
 import org.apache.cxf.rs.security.jose.jwt.JwtUtils;
 import org.apache.cxf.rs.security.oauth2.client.ClientTokenContext;
@@ -115,8 +116,10 @@ public class OidcRpAuthenticationFilter implements 
ContainerRequestFilter {
         MultivaluedMap<String, String> requestState = new MetadataMap<>();
         requestState.putAll(rc.getUriInfo().getQueryParameters(true));
         if 
(MediaType.APPLICATION_FORM_URLENCODED_TYPE.isCompatible(rc.getMediaType())) {
-            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name());
-            FormUtils.populateMapFromString(requestState, 
JAXRSUtils.getCurrentMessage(), body,
+            final Message currentMessage = JAXRSUtils.getCurrentMessage();
+            String body = FormUtils.readBody(rc.getEntityStream(), 
StandardCharsets.UTF_8.name(),
+                    FormUtils.getMaxFormParamsSize(currentMessage));
+            FormUtils.populateMapFromString(requestState, currentMessage, body,
                                             StandardCharsets.UTF_8.name(), 
true);
             rc.setEntityStream(new 
ByteArrayInputStream(StringUtils.toBytesUTF8(body)));
 
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
index 11c9d35c11e..a676202a52c 100644
--- 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerBookTest.java
@@ -352,6 +352,17 @@ public class JAXRSClientServerBookTest extends 
AbstractBusClientServerTestBase {
         assertThat("max form params limit reached",  r.getStatus(), 
equalTo(413));
     }
 
+    @Test
+    public void testTooManyFormParamsUsingForm() throws Exception {
+        // Exceeding 500 limit
+        String params = IntStream.range(0, 501).mapToObj(i -> "id" + i + "=" + 
i).collect(Collectors.joining("&"));
+        String address = "http://localhost:"; + PORT + 
"/bookstore/formParams/1";
+        WebClient wc = WebClient.create(address);
+        wc.type(MediaType.APPLICATION_FORM_URLENCODED);
+        Response r = wc.post(new 
ByteArrayInputStream(params.getBytes(StandardCharsets.UTF_8)));
+        assertThat("max form params limit reached",  r.getStatus(), 
equalTo(413));
+    }
+    
     @Test
     public void testTooLargeFormParams() throws Exception {
         // Exceeding 100Mb limit
@@ -365,6 +376,19 @@ public class JAXRSClientServerBookTest extends 
AbstractBusClientServerTestBase {
         assertThat("max form params limit reached",  r.getStatus(), 
equalTo(500));
     }
 
+    @Test
+    public void testTooLargeFormParamsUsingForm() throws Exception {
+        // Exceeding 100Mb limit
+        String params = IntStream.range(0, 150)
+            .mapToObj(i -> "id" + i + "="
+                + new 
String(Integer.toString(i)).repeat(524800)).collect(Collectors.joining("&"));
+        String address = "http://localhost:"; + PORT + 
"/bookstore/formParams/1";
+        WebClient wc = WebClient.create(address);
+        wc.type(MediaType.APPLICATION_FORM_URLENCODED);
+        Response r = wc.post(new 
ByteArrayInputStream(params.getBytes(StandardCharsets.UTF_8)));
+        assertThat("max form params limit reached",  r.getStatus(), 
equalTo(500));
+    }
+
     @Test
     public void testGetBookDescriptionHttpResponse() throws Exception {
         String address = "http://localhost:"; + PORT + 
"/bookstore/httpresponse";

Reply via email to