You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2026/10/14 13:41:58 UTC
(tomcat) 09/18: Validate initialSize in the SynchronizedQueue(int) constructor
This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 05210c2a4654c0df78b55379b6e7bc07c4ea2d34
Author: opencode <re...@apache.org>
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: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org