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

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git


The following commit(s) were added to refs/heads/master by this push:
     new a7f887155 Validate deserialized size in CircularFifoQueue.readObject 
(#678)
a7f887155 is described below

commit a7f8871557d6082e0708ef0505fa13c4257b83c7
Author: Digiscrypt Technologies <[email protected]>
AuthorDate: Sun Jun 28 00:17:59 2026 +0530

    Validate deserialized size in CircularFifoQueue.readObject (#678)
    
    * validate deserialized size in CircularFifoQueue.readObject
    
    * Update CircularFifoQueueTest.java
    
    * Update CircularFifoQueueTest.java
    
    ---------
    
    Co-authored-by: digi-scrypt <[email protected]>
    Co-authored-by: Gary Gregory <[email protected]>
---
 .../collections4/queue/CircularFifoQueue.java      |  7 ++++
 .../collections4/queue/CircularFifoQueueTest.java  | 41 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git 
a/src/main/java/org/apache/commons/collections4/queue/CircularFifoQueue.java 
b/src/main/java/org/apache/commons/collections4/queue/CircularFifoQueue.java
index 3988666e7..9417583e3 100644
--- a/src/main/java/org/apache/commons/collections4/queue/CircularFifoQueue.java
+++ b/src/main/java/org/apache/commons/collections4/queue/CircularFifoQueue.java
@@ -17,6 +17,7 @@
 package org.apache.commons.collections4.queue;
 
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
@@ -358,8 +359,14 @@ public class CircularFifoQueue<E> extends 
AbstractCollection<E>
     @SuppressWarnings("unchecked")
     private void readObject(final ObjectInputStream in) throws IOException, 
ClassNotFoundException {
         in.defaultReadObject();
+        if (maxElements < 1) {
+            throw new InvalidObjectException("maxElements must be greater than 
0");
+        }
         elements = (E[]) new Object[maxElements];
         final int size = in.readInt();
+        if (size < 0 || size > maxElements) {
+            throw new InvalidObjectException("size is out of range: " + size);
+        }
         for (int i = 0; i < size; i++) {
             elements[i] = (E) in.readObject();
         }
diff --git 
a/src/test/java/org/apache/commons/collections4/queue/CircularFifoQueueTest.java
 
b/src/test/java/org/apache/commons/collections4/queue/CircularFifoQueueTest.java
index fca917e22..20df0a8ac 100644
--- 
a/src/test/java/org/apache/commons/collections4/queue/CircularFifoQueueTest.java
+++ 
b/src/test/java/org/apache/commons/collections4/queue/CircularFifoQueueTest.java
@@ -21,6 +21,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.InvalidObjectException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -428,6 +429,46 @@ public class CircularFifoQueueTest<E> extends 
AbstractQueueTest<E> {
         assertTrue(b3.contains("c"));
     }
 
+    @Test
+    @SuppressWarnings("unchecked")
+    void testDeserializeRejectsCorruptSize() throws Exception {
+        // a stored size larger than maxElements would write past the backing 
array
+        final CircularFifoQueue<E> full = new CircularFifoQueue<>(7);
+        for (int i = 0; i < 7; i++) {
+            full.add((E) ("x" + i));
+        }
+        final byte[] tooLarge = serialize(full);
+        // first 0x00000007 is maxElements; shrink it so size (7) now exceeds 
it
+        patchInt(tooLarge, indexOfInt(tooLarge, 7), 2);
+        assertThrows(InvalidObjectException.class, () -> 
deserialize(tooLarge));
+
+        // a negative stored size leaves the queue in an inconsistent state
+        final CircularFifoQueue<E> partial = new CircularFifoQueue<>(7);
+        partial.add((E) "a");
+        partial.add((E) "b");
+        final byte[] negative = serialize(partial);
+        patchInt(negative, indexOfInt(negative, 2), -1);
+        assertThrows(InvalidObjectException.class, () -> 
deserialize(negative));
+    }
+
+    private static int indexOfInt(final byte[] data, final int value) {
+        final byte[] needle = {(byte) (value >>> 24), (byte) (value >>> 16), 
(byte) (value >>> 8), (byte) value};
+        for (int i = 0; i <= data.length - 4; i++) {
+            if (data[i] == needle[0] && data[i + 1] == needle[1]
+                    && data[i + 2] == needle[2] && data[i + 3] == needle[3]) {
+                return i;
+            }
+        }
+        throw new IllegalStateException("value not found in stream");
+    }
+
+    private static void patchInt(final byte[] data, final int pos, final int 
value) {
+        data[pos] = (byte) (value >>> 24);
+        data[pos + 1] = (byte) (value >>> 16);
+        data[pos + 2] = (byte) (value >>> 8);
+        data[pos + 3] = (byte) value;
+    }
+
 //    void testCreate() throws Exception {
 //        resetEmpty();
 //        writeExternalFormToDisk((java.io.Serializable) getCollection(), 
"src/test/resources/data/test/CircularFifoQueue.emptyCollection.version4.obj");

Reply via email to