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

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

commit b760e70832bddeb4c63d425954b1b8315a8e5c30
Author: opencode <[email protected]>
AuthorDate: Wed Oct 14 12:02:08 2026 +0200

    Validate initialSize in the SynchronizedQueue(int) constructor
    
    The public constructor accepted values it could not handle. A zero
    initial size produced a queue whose first offer() threw
    ArrayIndexOutOfBoundsException, and a negative value produced
    NegativeArraySizeException from the array allocation. Neither state is
    usable, and a zero-size queue cannot recover since expand() doubles the
    current size.
    
    Reject non-positive values with IllegalArgumentException using a
    localized message from a new LocalStrings bundle for the
    org.apache.tomcat.util.collections package, following the StringManager
    pattern used by other util packages. No in-tree caller is affected; the
    only production instantiation uses the default constructor.
    
    Add tests for rejected zero and negative sizes, for the smallest valid
    size of one, and add the missing @Test annotation to testPollEmpty which
    previously prevented it from running.
---
 .../util/collections/LocalStrings.properties       | 16 +++++++++++++
 .../tomcat/util/collections/SynchronizedQueue.java | 14 +++++++++++-
 .../util/collections/TestSynchronizedQueue.java    | 26 ++++++++++++++++++++++
 3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/tomcat/util/collections/LocalStrings.properties 
b/java/org/apache/tomcat/util/collections/LocalStrings.properties
new file mode 100644
index 0000000000..c844da4f32
--- /dev/null
+++ b/java/org/apache/tomcat/util/collections/LocalStrings.properties
@@ -0,0 +1,16 @@
+# 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.
+
+synchronizedQueue.invalidInitialSize=The initial size [{0}] must be greater 
than zero
diff --git a/java/org/apache/tomcat/util/collections/SynchronizedQueue.java 
b/java/org/apache/tomcat/util/collections/SynchronizedQueue.java
index 5962784f53..d541fa15fc 100644
--- a/java/org/apache/tomcat/util/collections/SynchronizedQueue.java
+++ b/java/org/apache/tomcat/util/collections/SynchronizedQueue.java
@@ -16,6 +16,8 @@
  */
 package org.apache.tomcat.util.collections;
 
+import org.apache.tomcat.util.res.StringManager;
+
 /**
  * This is intended as a (mostly) GC-free alternative to {@link 
java.util.concurrent.ConcurrentLinkedQueue} when the
  * requirement is to create an unbounded queue with no requirement to shrink 
the queue. The aim is to provide the bare
@@ -25,6 +27,8 @@ package org.apache.tomcat.util.collections;
  */
 public class SynchronizedQueue<T> {
 
+    private static final StringManager sm = 
StringManager.getManager(SynchronizedQueue.class);
+
     /**
      * The default initial capacity for a new queue.
      */
@@ -60,9 +64,17 @@ public class SynchronizedQueue<T> {
     /**
      * Constructs a new SynchronizedQueue with the specified initial capacity.
      *
-     * @param initialSize the initial capacity
+     * @param initialSize the initial capacity, which must be positive
+     *
+     * @throws IllegalArgumentException if the specified initial capacity is
+     *         not positive
      */
     public SynchronizedQueue(int initialSize) {
+        if (initialSize <= 0) {
+            throw new IllegalArgumentException(
+                    sm.getString("synchronizedQueue.invalidInitialSize",
+                            initialSize));
+        }
         queue = new Object[initialSize];
         size = initialSize;
     }
diff --git a/test/org/apache/tomcat/util/collections/TestSynchronizedQueue.java 
b/test/org/apache/tomcat/util/collections/TestSynchronizedQueue.java
index 7ecad08fb6..c140343397 100644
--- a/test/org/apache/tomcat/util/collections/TestSynchronizedQueue.java
+++ b/test/org/apache/tomcat/util/collections/TestSynchronizedQueue.java
@@ -21,6 +21,7 @@ import org.junit.Test;
 
 public class TestSynchronizedQueue {
 
+    @Test
     public void testPollEmpty() {
         SynchronizedQueue<Object> queue = new SynchronizedQueue<>();
         Assert.assertNull(queue.poll());
@@ -114,4 +115,29 @@ public class TestSynchronizedQueue {
 
         Assert.assertNull(queue.poll());
     }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testZeroInitialSizeRejected() {
+        new SynchronizedQueue<>(0);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNegativeInitialSizeRejected() {
+        new SynchronizedQueue<>(-1);
+    }
+
+    @Test
+    public void testInitialSizeOne() {
+        SynchronizedQueue<Object> queue = new SynchronizedQueue<>(1);
+
+        Object o1 = new Object();
+        Object o2 = new Object();
+
+        queue.offer(o1);
+        queue.offer(o2);
+
+        Assert.assertSame(queue.poll(), o1);
+        Assert.assertSame(queue.poll(), o2);
+        Assert.assertNull(queue.poll());
+    }
 }


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

Reply via email to