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 <[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]
