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 b0ce37f0d Fix putAll(K, Iterable) NPE for null value transformer (#731)
b0ce37f0d is described below

commit b0ce37f0d62f0a6efa306d90d446f6d0f9549bdb
Author: Naveed Khan <[email protected]>
AuthorDate: Thu Sep 3 11:07:32 2026 +0000

    Fix putAll(K, Iterable) NPE for null value transformer (#731)
    
    * fix putAll(K, Iterable) NPE for null value transformer
    
    TransformedMultiValuedMap.putAll(K, Iterable) sent values through
    FluentIterable.of(values).transform(valueTransformer), which throws
    NullPointerException when valueTransformer is null even though null
    is documented as no conversion and put() handles it via transformValue.
    Skip the transform when the transformer is null.
    
    * route putAll(K, Iterable) values through transformValue()
    
    Check the overridable transformValue() instead of valueTransformer
    directly so a subclass that overrides transformValue() while passing
    null to the superclass still gets its conversion applied on putAll,
    matching what put() already does.
---
 .../multimap/TransformedMultiValuedMap.java        |  2 +-
 .../multimap/TransformedMultiValuedMapTest.java    | 26 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git 
a/src/main/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java
 
b/src/main/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java
index fc37a632a..f23558692 100644
--- 
a/src/main/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java
+++ 
b/src/main/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMap.java
@@ -133,7 +133,7 @@ public class TransformedMultiValuedMap<K, V> extends 
AbstractMultiValuedMapDecor
     public boolean putAll(final K key, final Iterable<? extends V> values) {
         Objects.requireNonNull(values, "values");
 
-        final Iterable<V> transformedValues = 
FluentIterable.of(values).transform(valueTransformer);
+        final Iterable<V> transformedValues = 
FluentIterable.of(values).transform(this::transformValue);
         final Iterator<? extends V> it = transformedValues.iterator();
         return it.hasNext() && 
CollectionUtils.addAll(decorated().get(transformKey(key)), it);
     }
diff --git 
a/src/test/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMapTest.java
 
b/src/test/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMapTest.java
index d83b47108..1935f6afc 100644
--- 
a/src/test/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMapTest.java
+++ 
b/src/test/java/org/apache/commons/collections4/multimap/TransformedMultiValuedMapTest.java
@@ -22,6 +22,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.Arrays;
 import java.util.Collection;
 
 import org.apache.commons.collections4.MultiValuedMap;
@@ -130,6 +131,31 @@ public class TransformedMultiValuedMapTest<K, V> extends 
AbstractMultiValuedMapT
         assertTrue(map.remove(Integer.valueOf((String) 
els[0])).contains(els[0]));
     }
 
+    @Test
+    @SuppressWarnings("unchecked")
+    void testPutAllIterableWithNullTransformers() {
+        final MultiValuedMap<K, V> map = 
TransformedMultiValuedMap.transformingMap(
+                new ArrayListValuedHashMap<>(), null, null);
+        assertTrue(map.putAll((K) "k", Arrays.asList((V) "a", (V) "b")));
+        assertEquals(Arrays.asList("a", "b"), map.get((K) "k"));
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    void testPutAllIterableAppliesTransformValueOverride() {
+        final TransformedMultiValuedMap<K, V> map = new 
TransformedMultiValuedMap<K, V>(
+                new ArrayListValuedHashMap<>(), null, null) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected V transformValue(final V object) {
+                return (V) String.valueOf(object);
+            }
+        };
+        assertTrue(map.putAll((K) "k", Arrays.asList((V) Integer.valueOf(1), 
(V) Integer.valueOf(2))));
+        assertEquals(Arrays.asList("1", "2"), map.get((K) "k"));
+    }
+
     @Test
     @SuppressWarnings("unchecked")
     void testValueTransformedMap() {

Reply via email to