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

joerghoh pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git


The following commit(s) were added to refs/heads/master by this push:
     new 2f1a04b  SLING-13138 Add configurable fail-fast parameter limit 
handling (#74)
2f1a04b is described below

commit 2f1a04b128d13207dc8f8455adcb5d67f10f6ea6
Author: aswindhanan <[email protected]>
AuthorDate: Wed Sep 2 12:34:54 2026 -0500

    SLING-13138 Add configurable fail-fast parameter limit handling (#74)
    
    * SLING-13138 Add configurable fail-fast parameter limit handling
    * SLING-13138 Improve test coverage for parameter limit feature
    * SLING-13138 Improve ParameterMapTest code quality
---
 .../sling/engine/impl/parameters/ParameterMap.java |  11 +-
 .../RequestParameterSupportConfigurer.java         |  10 ++
 .../engine/impl/parameters/ParameterMapTest.java   | 146 +++++++++++++++++++++
 3 files changed, 165 insertions(+), 2 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java 
b/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java
index 7f886c0..884fd5b 100644
--- a/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java
+++ b/src/main/java/org/apache/sling/engine/impl/parameters/ParameterMap.java
@@ -40,6 +40,7 @@ public class ParameterMap extends LinkedHashMap<String, 
RequestParameter[]> impl
     static final int DEFAULT_MAX_PARAMS = 10000;
 
     private static int maxParameters = DEFAULT_MAX_PARAMS;
+    private static boolean failOnParameterLimit = false;
 
     private Map<String, String[]> stringParameterMap;
 
@@ -49,6 +50,10 @@ public class ParameterMap extends LinkedHashMap<String, 
RequestParameter[]> impl
         ParameterMap.maxParameters = (maxParameters > 0) ? maxParameters : -1;
     }
 
+    static void setFailOnParameterLimit(final boolean fail) {
+        ParameterMap.failOnParameterLimit = fail;
+    }
+
     public RequestParameter getValue(String name) {
         RequestParameter[] params = getValues(name);
         return (params != null && params.length > 0) ? params[0] : null;
@@ -71,8 +76,10 @@ public class ParameterMap extends LinkedHashMap<String, 
RequestParameter[]> impl
     void addParameter(RequestParameter parameter, boolean prependNew) {
 
         // check number of parameters
-        if (this.requestParameters.size() == maxParameters) {
-            // TODO: how to handle this situation ?? just ignore or throw or 
what ??
+        if (maxParameters > -1 && this.requestParameters.size() >= 
maxParameters) {
+            if (failOnParameterLimit) {
+                throw new IllegalStateException("Too many name/value pairs, 
limit is " + maxParameters);
+            }
             LoggerFactory.getLogger(Util.class)
                     .warn("Too many name/value pairs, stopped processing after 
" + maxParameters + " entries");
             return;
diff --git 
a/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportConfigurer.java
 
b/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportConfigurer.java
index 78586a3..7421b46 100644
--- 
a/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportConfigurer.java
+++ 
b/src/main/java/org/apache/sling/engine/impl/parameters/RequestParameterSupportConfigurer.java
@@ -128,6 +128,13 @@ public class RequestParameterSupportConfigurer implements 
Filter {
                 description =
                         "The maximum number of files allowed for 
multipart/form-data requests in a single request. The default is 50.")
         long request_max_file_count() default 50;
+
+        @AttributeDefinition(
+                name = "Fail on Parameter Limit",
+                description = "Whether to throw an exception when the maximum 
number of parameters is exceeded. "
+                        + "If false (default), a warning is logged and 
processing continues with truncated parameters. "
+                        + "If true, an IllegalStateException is thrown.")
+        boolean sling_default_parameter_fail_on_limit() default false;
     }
 
     static final String PID = "org.apache.sling.engine.parameters";
@@ -147,6 +154,7 @@ public class RequestParameterSupportConfigurer implements 
Filter {
         final long maxFileSize = config.file_max();
         final int fileSizeThreshold = config.file_threshold();
         final boolean checkAddParameters = 
config.sling_default_parameter_checkForAdditionalContainerParameters();
+        final boolean failOnParameterLimit = 
config.sling_default_parameter_fail_on_limit();
 
         if (log.isInfoEnabled()) {
             log.info("Default Character Encoding: {}", fixEncoding);
@@ -157,10 +165,12 @@ public class RequestParameterSupportConfigurer implements 
Filter {
             log.info("Tempory File Creation Threshold: {}", fileSizeThreshold);
             log.info("Check for additional container parameters: {}", 
checkAddParameters);
             log.info("Maximum File Count: {}", 
config.request_max_file_count());
+            log.info("Fail on Parameter Limit: {}", failOnParameterLimit);
         }
 
         Util.setDefaultFixEncoding(fixEncoding);
         ParameterMap.setMaxParameters(maxParams);
+        ParameterMap.setFailOnParameterLimit(failOnParameterLimit);
         ParameterSupport.configure(
                 maxRequestSize,
                 fileLocation,
diff --git 
a/src/test/java/org/apache/sling/engine/impl/parameters/ParameterMapTest.java 
b/src/test/java/org/apache/sling/engine/impl/parameters/ParameterMapTest.java
new file mode 100644
index 0000000..a89e279
--- /dev/null
+++ 
b/src/test/java/org/apache/sling/engine/impl/parameters/ParameterMapTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.sling.engine.impl.parameters;
+
+import org.apache.sling.api.request.RequestParameter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import static org.junit.Assert.assertEquals;
+
+public class ParameterMapTest {
+
+    private static final int ORIGINAL_MAX_PARAMS = 
ParameterMap.DEFAULT_MAX_PARAMS;
+
+    @Rule
+    public ExpectedException exception = ExpectedException.none();
+
+    private void resetToDefaults() {
+        ParameterMap.setMaxParameters(ORIGINAL_MAX_PARAMS);
+        ParameterMap.setFailOnParameterLimit(false);
+    }
+
+    @Before
+    public void setUp() {
+        resetToDefaults();
+    }
+
+    @After
+    public void tearDown() {
+        resetToDefaults();
+    }
+
+    @Test
+    public void testDefaultBehavior() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(2);
+
+        // Should work normally within limit
+        pm.addParameter(createTestParameter("param1", "value1"), false);
+        pm.addParameter(createTestParameter("param2", "value2"), false);
+        assertEquals(2, pm.size());
+
+        // Should log warning and continue when exceeding limit
+        pm.addParameter(createTestParameter("param3", "value3"), false);
+        assertEquals(2, pm.size()); // Should still be 2, param3 ignored
+    }
+
+    @Test
+    public void testFailOnParameterLimit() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(2);
+        ParameterMap.setFailOnParameterLimit(true);
+
+        // Should work normally within limit
+        pm.addParameter(createTestParameter("param1", "value1"), false);
+        pm.addParameter(createTestParameter("param2", "value2"), false);
+        assertEquals(2, pm.size());
+
+        // Should throw exception when exceeding limit
+        exception.expect(IllegalStateException.class);
+        exception.expectMessage("Too many name/value pairs");
+        exception.expectMessage("2");
+        pm.addParameter(createTestParameter("param3", "value3"), false);
+    }
+
+    @Test
+    public void testParameterLimitExactlyAtBoundary() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(1);
+        ParameterMap.setFailOnParameterLimit(false);
+
+        // Add exactly at limit
+        pm.addParameter(createTestParameter("param1", "value1"), false);
+        assertEquals(1, pm.size());
+
+        // Next addition should trigger warning and be ignored
+        pm.addParameter(createTestParameter("param2", "value2"), false);
+        assertEquals(1, pm.size()); // Should remain 1
+    }
+
+    @Test
+    public void testUnlimitedParameters() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(-1); // Unlimited
+        ParameterMap.setFailOnParameterLimit(false);
+
+        // Should allow unlimited parameters
+        for (int i = 1; i <= 100; i++) {
+            pm.addParameter(createTestParameter("param" + i, "value" + i), 
false);
+        }
+        assertEquals(100, pm.size());
+    }
+
+    @Test
+    public void testFailOnLimitWithLargeLimit() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(5);
+        ParameterMap.setFailOnParameterLimit(true);
+
+        // Add up to limit
+        for (int i = 1; i <= 5; i++) {
+            pm.addParameter(createTestParameter("param" + i, "value" + i), 
false);
+        }
+        assertEquals(5, pm.size());
+
+        // Next should fail
+        exception.expect(IllegalStateException.class);
+        exception.expectMessage("Too many name/value pairs");
+        exception.expectMessage("5");
+        pm.addParameter(createTestParameter("param6", "value6"), false);
+    }
+
+    @Test
+    public void testFailOnLimitDisabledWithZeroLimit() {
+        ParameterMap pm = new ParameterMap();
+        ParameterMap.setMaxParameters(0); // Becomes -1 (unlimited)
+        ParameterMap.setFailOnParameterLimit(true); // Shouldn't matter since 
unlimited
+
+        // Should allow parameters despite failOnLimit=true
+        pm.addParameter(createTestParameter("param1", "value1"), false);
+        assertEquals(1, pm.size());
+    }
+
+    private RequestParameter createTestParameter(String name, String value) {
+        return new ContainerRequestParameter(name, value, "UTF-8");
+    }
+}

Reply via email to