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 e1ce56f24 reject non-positive maxSize in LRUMap deserialization (#690)
e1ce56f24 is described below

commit e1ce56f243f14dc711047a61a9abe0305e1412a0
Author: Dexter.k <[email protected]>
AuthorDate: Sat Jun 20 16:50:02 2026 +0000

    reject non-positive maxSize in LRUMap deserialization (#690)
    
    doReadObject read maxSize with readInt() but skipped the constructor's 
maxSize >= 1 check, so a crafted stream could build an LRUMap with a 
non-positive bound that corrupts the eviction list on the next put. Validate 
maxSize and throw InvalidObjectException.
---
 .../java/org/apache/commons/collections4/map/LRUMap.java   |  4 ++++
 .../org/apache/commons/collections4/map/LRUMapTest.java    | 14 ++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/src/main/java/org/apache/commons/collections4/map/LRUMap.java 
b/src/main/java/org/apache/commons/collections4/map/LRUMap.java
index feecbe44c..d30896c39 100644
--- a/src/main/java/org/apache/commons/collections4/map/LRUMap.java
+++ b/src/main/java/org/apache/commons/collections4/map/LRUMap.java
@@ -17,6 +17,7 @@
 package org.apache.commons.collections4.map;
 
 import java.io.IOException;
+import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
@@ -297,6 +298,9 @@ public class LRUMap<K, V>
     @Override
     protected void doReadObject(final ObjectInputStream in) throws 
IOException, ClassNotFoundException {
         maxSize = in.readInt();
+        if (maxSize < 1) {
+            throw new InvalidObjectException("LRUMap max size must be greater 
than 0");
+        }
         super.doReadObject(in);
     }
 
diff --git a/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java 
b/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java
index db65f2e2a..15fe791dc 100644
--- a/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java
+++ b/src/test/java/org/apache/commons/collections4/map/LRUMapTest.java
@@ -25,6 +25,8 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.fail;
 
+import java.io.InvalidObjectException;
+import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -310,6 +312,18 @@ public class LRUMapTest<K, V> extends 
AbstractOrderedMapTest<K, V> {
         assertThrows(IllegalArgumentException.class, () -> new LRUMap<K, 
V>(10, 12, 0.75f, false), "initialSize must not be larger than maxSize");
     }
 
+    @Test
+    void testDeserializeRejectsNonPositiveMaxSize() throws Exception {
+        final LRUMap<String, String> map = new LRUMap<>(3);
+        map.put("a", "1");
+        final Field maxSizeField = LRUMap.class.getDeclaredField("maxSize");
+        maxSizeField.setAccessible(true);
+        for (final int maxSize : new int[] {0, -7}) {
+            maxSizeField.setInt(map, maxSize);
+            assertThrows(InvalidObjectException.class, () -> 
serializeDeserialize(map));
+        }
+    }
+
     @Test
     @SuppressWarnings("unchecked")
     void testInternalState_Buckets() {

Reply via email to