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 d061d648cda9e7fa000a861bab1d20ca2ece8717
Author: Andriy Redko <[email protected]>
AuthorDate: Thu Jun 4 11:40:57 2026 -0400

    Introduce default value for maxFormParameterCount (#3177)
---
 .../java/org/apache/cxf/jaxrs/utils/FormUtils.java |   9 +-
 .../org/apache/cxf/jaxrs/utils/FormUtilsTest.java  | 103 +++++++++++++++++----
 2 files changed, 88 insertions(+), 24 deletions(-)

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 0c14eb0b29c..5d51005b154 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
@@ -54,6 +54,8 @@ import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.transport.http.AbstractHTTPDestination;
 
 public final class FormUtils {
+    public static final int DEFAULT_MAX_FORM_PARAM_COUNT = 500;
+
     public static final String FORM_PARAMS_FROM_HTTP_PARAMS = 
"set.form.parameters.from.http.parameters";
     public static final String FORM_PARAM_MAP = "org.apache.cxf.form_data";
     public static final String FORM_PARAM_MAP_DECODED = 
"org.apache.cxf.form_data.decoded";
@@ -272,11 +274,8 @@ public final class FormUtils {
         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;
-        }
+        final String maxPartsCountProp = 
MessageUtils.getContextualString(m.getExchange().getInMessage(),
+            MAX_FORM_PARAM_COUNT, 
Integer.toString(DEFAULT_MAX_FORM_PARAM_COUNT));
         try {
             int maxPartsCount = Integer.parseInt(maxPartsCountProp);
             if (maxPartsCount != -1 && numberOfParts >= maxPartsCount) {
diff --git 
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/FormUtilsTest.java 
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/FormUtilsTest.java
index 4e55527ea05..3076a291d4f 100644
--- 
a/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/FormUtilsTest.java
+++ 
b/rt/frontend/jaxrs/src/test/java/org/apache/cxf/jaxrs/utils/FormUtilsTest.java
@@ -19,41 +19,55 @@
 
 package org.apache.cxf.jaxrs.utils;
 
+import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
+import java.util.UUID;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.MultivaluedMap;
 
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
+import org.apache.cxf.jaxrs.ext.multipart.MultipartBody;
 import org.apache.cxf.jaxrs.impl.MetadataMap;
+import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.Message;
 
 import org.junit.Test;
 
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class FormUtilsTest {
-
-    private static final String HTTP_PARAM1 = "httpParam1";
-    private static final String HTTP_PARAM2 = "httpParam2";
-    private static final String HTTP_PARAM_VALUE1 = "httpValue1";
-    private static final String HTTP_PARAM_VALUE2 = "httpValue2";
-
-    private static final String FORM_PARAM1 = "formParam1";
-    private static final String FORM_PARAM2 = "formParam2";
-    private static final String FORM_PARAM_VALUE1 = "formValue1";
-    private static final String FORM_PARAM_VALUE2 = "formValue2";
+    private static final String HTTP_PARAM = "httpParam";
+    private static final String HTTP_PARAM1 = HTTP_PARAM + "1";
+    private static final String HTTP_PARAM2 = HTTP_PARAM + "2";
+    private static final String HTTP_PARAM_VALUE = "httpValue";
+    private static final String HTTP_PARAM_VALUE1 = HTTP_PARAM_VALUE + "1";
+    private static final String HTTP_PARAM_VALUE2 = HTTP_PARAM_VALUE + "2";
+
+    private static final String FORM_PARAM = "formParam";
+    private static final String FORM_PARAM1 = FORM_PARAM + "1";
+    private static final String FORM_PARAM2 = FORM_PARAM + "2";
+    private static final String FORM_PARAM_VALUE = "formValue";
+    private static final String FORM_PARAM_VALUE1 = FORM_PARAM_VALUE + "1";
+    private static final String FORM_PARAM_VALUE2 = FORM_PARAM_VALUE + "2";
 
     private Message mockMessage;
     private HttpServletRequest mockRequest;
 
     @Test
     public void populateMapFromStringFromHTTP() {
-        mockObjects(null);
+        mockObjects(null, 2);
 
         MultivaluedMap<String, String> params = new MetadataMap<>();
         FormUtils.populateMapFromString(params, mockMessage, null, 
StandardCharsets.UTF_8.name(),
@@ -66,7 +80,7 @@ public class FormUtilsTest {
 
     @Test
     public void populateMapFromStringFromHTTPWithProp() {
-        mockObjects("false");
+        mockObjects("false", 2);
 
         MultivaluedMap<String, String> params = new MetadataMap<>();
         FormUtils.populateMapFromString(params, mockMessage, null, 
StandardCharsets.UTF_8.name(),
@@ -77,7 +91,7 @@ public class FormUtilsTest {
 
     @Test
     public void populateMapFromStringFromBody() {
-        mockObjects(null);
+        mockObjects(null, 2);
 
         MultivaluedMap<String, String> params = new MetadataMap<>();
         String postBody = FORM_PARAM1 + "=" + FORM_PARAM_VALUE1 + "&" + 
FORM_PARAM2 + "=" + FORM_PARAM_VALUE2;
@@ -90,19 +104,70 @@ public class FormUtilsTest {
     }
 
 
-    private void mockObjects(String formPropertyValue) {
+    @Test
+    public void populateMapFromBodyExceedsDefaultMaxFormParams() {
+        mockObjects(null, FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT);
+        
+        final MultivaluedMap<String, String> params = new MetadataMap<>();
+        final String postBody = IntStream
+                .range(1, FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT + 1)
+                .mapToObj(i -> FORM_PARAM + i + "=" + FORM_PARAM_VALUE + i)
+                .collect(Collectors.joining("&"));
+        final WebApplicationException ex = 
assertThrows(WebApplicationException.class,
+            () -> FormUtils.populateMapFromString(params, mockMessage, 
postBody, 
+                StandardCharsets.UTF_8.name(), false));
+        assertThat(ex.getResponse().getStatus(), equalTo(413)); /* Request 
Entity Too Large */
+
+        // Increase the limit and try again
+        when(mockMessage.getContextualProperty("maxFormParameterCount"))
+            
.thenReturn(Integer.toString(FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT + 1));
+        FormUtils.populateMapFromString(params, mockMessage, null, 
StandardCharsets.UTF_8.name(), false, mockRequest);
+        assertEquals(500, params.size());
+    }
+    
+    @Test
+    public void populateMapFromMultiPartExceedsDefaultMaxFormParams() {
+        mockObjects(null, FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT);
+
+        final MultivaluedMap<String, String> params = new MetadataMap<>();
+        final MultipartBody body = new MultipartBody(IntStream
+                .range(1, FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT + 1)
+                .mapToObj(i -> {
+                    final MultivaluedMap<String, String> headers = new 
MetadataMap<>();
+                    headers.putSingle("Content-ID", 
UUID.randomUUID().toString());
+                    return new Attachment(InputStream.nullInputStream(), 
headers);
+                })
+                .collect(Collectors.toList()));
+        final WebApplicationException ex = 
assertThrows(WebApplicationException.class,
+            () -> FormUtils.populateMapFromMultipart(params, body, 
mockMessage, false));
+        assertThat(ex.getResponse().getStatus(), equalTo(413)); /* Request 
Entity Too Large */
+
+        // Increase the limit and try again
+        when(mockMessage.getContextualProperty("maxFormParameterCount"))
+            
.thenReturn(Integer.toString(FormUtils.DEFAULT_MAX_FORM_PARAM_COUNT + 1));
+        FormUtils.populateMapFromMultipart(params, body, mockMessage, false);
+        assertEquals(500, params.size());
+    }
+
+    private void mockObjects(String formPropertyValue, int params) {
+        final ExchangeImpl exchange = new ExchangeImpl();
+
         mockMessage = mock(Message.class);
         
when(mockMessage.getContextualProperty(FormUtils.FORM_PARAMS_FROM_HTTP_PARAMS))
             .thenReturn(formPropertyValue);
-        when(mockMessage.getExchange()).thenReturn(null);
+        when(mockMessage.getExchange()).thenReturn(exchange);
         when(mockMessage.put(FormUtils.FORM_PARAM_MAP_DECODED, true))
             .thenReturn(null);
-        
+        exchange.setInMessage(mockMessage);
+
         mockRequest = mock(HttpServletRequest.class);
-        String[] httpParamNames = {HTTP_PARAM1, HTTP_PARAM2};
+        String[] httpParamNames =  IntStream.range(1, params + 1)
+            .mapToObj(i -> "httpParam" + i)
+            .toArray(String[]::new);
         Enumeration<String> httpParamsEnum = 
Collections.enumeration(Arrays.asList(httpParamNames));
         when(mockRequest.getParameterNames()).thenReturn(httpParamsEnum);
-        when(mockRequest.getParameterValues(HTTP_PARAM1)).thenReturn(new 
String[] {HTTP_PARAM_VALUE1});
-        when(mockRequest.getParameterValues(HTTP_PARAM2)).thenReturn(new 
String[] {HTTP_PARAM_VALUE2});
+        for (int i = 1; i <= httpParamNames.length; ++i) {
+            when(mockRequest.getParameterValues(HTTP_PARAM + 
i)).thenReturn(new String[] {HTTP_PARAM_VALUE + i});
+        }
     }
 }
\ No newline at end of file

Reply via email to