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

rmaucher pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/10.1.x by this push:
     new 4b70c7e9b7 Allow maxLocaleCount to soft fail
4b70c7e9b7 is described below

commit 4b70c7e9b73ebab6d45c4755ba1828b7a80a9a3b
Author: remm <[email protected]>
AuthorDate: Fri Oct 23 11:38:00 2026 +0200

    Allow maxLocaleCount to soft fail
    
    Exceeding the locale count leaves the request functionally correct,
    unlike what happens for request parameters.
    As a result, simply ignore extra locales, and log an info message about
    it.
---
 java/org/apache/catalina/connector/Request.java    | 18 ++----
 .../org/apache/catalina/connector/TestRequest.java | 65 +---------------------
 webapps/docs/changelog.xml                         |  5 ++
 webapps/docs/config/http.xml                       |  6 +-
 4 files changed, 17 insertions(+), 77 deletions(-)

diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index a4750befbb..4f8c81d023 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -131,12 +131,6 @@ public class Request implements HttpServletRequest {
 
     private static final String HTTP_UPGRADE_HEADER_NAME = "upgrade";
 
-    /**
-     * The default value of the maximum number of locales to parse from the 
Accept-Language header(s). Must match the
-     * default of the maxLocaleCount attribute of the Connector with which a 
Request is associated.
-     */
-    private static final int DEFAULT_MAX_LOCALE_COUNT = 10;
-
     /*
      * Use AcceptLanguage2 parser rather than the StandardAcceptLanguageParser.
      */
@@ -447,10 +441,9 @@ public class Request implements HttpServletRequest {
      * The maximum number of locales permitted for a request. The 
Accept-Language header value is untrusted input
      * bounded only by the maximum header size so the number of locales is 
bounded by default to limit the
      * per-request processing and the number of distinct locales exposed to 
web applications and internal components.
-     * Requests that exceed this limit are rejected when the locales are 
parsed. A value of less than zero means no
-     * limit.
+     * A value of less than zero means no limit.
      */
-    private int maxLocaleCount = DEFAULT_MAX_LOCALE_COUNT;
+    private int maxLocaleCount = -1;
 
     // --------------------------------------------------------- Public Methods
 
@@ -507,7 +500,7 @@ public class Request implements HttpServletRequest {
             maxParameterCount = -1;
             maxPartCount = -1;
             maxPartHeaderSize = -1;
-            maxLocaleCount = DEFAULT_MAX_LOCALE_COUNT;
+            maxLocaleCount = -1;
         }
         if (parts != null) {
             for (Part part : parts) {
@@ -3355,8 +3348,9 @@ public class Request implements HttpServletRequest {
         for (ArrayList<Locale> list : locales.values()) {
             for (Locale locale : list) {
                 if (maxLocaleCount > -1 && this.locales.size() >= 
maxLocaleCount) {
-                    throw new IllegalArgumentException(
-                            sm.getString("coyoteRequest.tooManyLocales", 
Integer.valueOf(maxLocaleCount)));
+                    // Remove the last element
+                    this.locales.remove(this.locales.size() - 1);
+                    log.info(sm.getString("coyoteRequest.tooManyLocales", 
Integer.valueOf(maxLocaleCount)));
                 }
                 addLocale(locale);
             }
diff --git a/test/org/apache/catalina/connector/TestRequest.java 
b/test/org/apache/catalina/connector/TestRequest.java
index e06926b1f9..98fea5a8fa 100644
--- a/test/org/apache/catalina/connector/TestRequest.java
+++ b/test/org/apache/catalina/connector/TestRequest.java
@@ -825,33 +825,6 @@ public class TestRequest extends TomcatBaseTest {
         }
     }
 
-    /*
-     * The number of locales in the Accept-Language header(s) is
-     * limited because the header value is untrusted input. Requests
-     * that exceed the limit are rejected (when the locales are
-     * accessed) in the same way as requests that exceed
-     * maxCookieCount.
-     */
-    @Test
-    public void testAcceptLanguageLocaleLimit() throws Exception {
-        TesterRequest req = new TesterRequest();
-
-        req.addHeader("accept-language", buildAcceptLanguage(20));
-
-        try {
-            req.getLocales();
-            Assert.fail("Accessing the locales when the limit is exceeded 
should throw an IllegalArgumentException");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-
-        // Requests within the limit are processed and the highest
-        // quality locale (at the start of the list) is retained
-        req = new TesterRequest();
-        req.addHeader("accept-language", "aa-000,aa-001,aa-002");
-        Assert.assertEquals(Locale.forLanguageTag("aa-000"), req.getLocale());
-    }
-
     /*
      * The locale limit is configurable via the maxLocaleCount attribute
      * of the Connector associated with the request.
@@ -866,12 +839,7 @@ public class TestRequest extends TomcatBaseTest {
         connector.setMaxLocaleCount(5);
         Assert.assertEquals(5, localeCount(connector, buildAcceptLanguage(5)));
 
-        try {
-            localeCount(connector, buildAcceptLanguage(6));
-            Assert.fail("Exceeding maxLocaleCount should throw an 
IllegalArgumentException");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
+        Assert.assertEquals(5, localeCount(connector, buildAcceptLanguage(6)));
 
         // No limit
         connector = new Connector();
@@ -905,28 +873,6 @@ public class TestRequest extends TomcatBaseTest {
         return count;
     }
 
-    /*
-     * The limit on untrusted locale tags is enforced while the
-     * header is parsed so that Locale objects are not created for
-     * entries that can never be used.
-     */
-    @Test
-    public void testAcceptLanguageLocaleLimitHeaderFlood() throws Exception {
-        Connector connector = new Connector();
-
-        // Default limit of 10. A header with far more tags than the
-        // limit is rejected.
-        try {
-            localeCount(connector, buildAcceptLanguage(5000));
-            Assert.fail("A header with 5000 locales should be rejected");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
-
-        // Exactly the limit is accepted.
-        Assert.assertEquals(10, localeCount(connector, 
buildAcceptLanguage(10)));
-    }
-
     /*
      * When multiple Accept-Language headers are present the limit
      * applies to the combined set of locales and parsing stops
@@ -939,13 +885,8 @@ public class TestRequest extends TomcatBaseTest {
                 "aa-005,aa-006,aa-007,aa-008,aa-009"));
 
         // 5 + 6 = 11, exceeds the default limit
-        try {
-            localeCount(new Connector(), "aa-000,aa-001,aa-002,aa-003,aa-004",
-                    "aa-005,aa-006,aa-007,aa-008,aa-009,aa-010");
-            Assert.fail("11 locales across two headers should be rejected");
-        } catch (IllegalArgumentException iae) {
-            // Expected
-        }
+        Assert.assertEquals(10, localeCount(new Connector(), 
"aa-000,aa-001,aa-002,aa-003,aa-004",
+                    "aa-005,aa-006,aa-007,aa-008,aa-009,aa-010"));
     }
 
     private static int localeCount(Connector connector, String... 
acceptLanguages) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index c8dfc6e84d..f8afa8b677 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -261,6 +261,11 @@
         Mark JAASRealm as a deprecated component. JAASRealm will be removed in
         Tomcat 12. (schultz)
       </update>
+      <fix>
+        Rework <code>maxLocaleCount</code> behavior to ignore extra locales
+        when parsed instead of throwing an ISE, since a request remains
+        functionally coherent. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 24d5a1dd23..a5d9e673bf 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -173,9 +173,9 @@
     <attribute name="maxLocaleCount" required="false">
       <p>The maximum number of locales (obtained from the
       <code>Accept-Language</code> header(s)) that are permitted for a request.
-      Requests that exceed this limit will be rejected when the locales are
-      parsed. A value of less than 0 means no limit. If not specified, a
-      default of 10 is used.</p>
+      Locales above this limit will be ignored when the locales are
+      parsed and an info will be logged. A value of less than 0 means no
+      limit. If not specified, a default of 10 is used.</p>
     </attribute>
 
     <attribute name="maxParameterCount" required="false">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to