You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2015/11/14 21:24:42 UTC

svn commit: r1714360 - in /commons/proper/collections/trunk/src: changes/changes.xml main/java/org/apache/commons/collections4/map/MultiValueMap.java test/java/org/apache/commons/collections4/map/MultiValueMapTest.java

Author: tn
Date: Sat Nov 14 20:24:42 2015
New Revision: 1714360

URL: http://svn.apache.org/viewvc?rev=1714360&view=rev
Log:
[COLLECTIONS-580] Add validation to MultiValueMap#ReflectionFactory: only Collection classes are support.

Modified:
    commons/proper/collections/trunk/src/changes/changes.xml
    commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java
    commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java

Modified: commons/proper/collections/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/changes/changes.xml?rev=1714360&r1=1714359&r2=1714360&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Sat Nov 14 20:24:42 2015
@@ -29,6 +29,11 @@
       ForClosure, InstantiateFactory, InstantiateTransformer, InvokerTransformer,
       PrototypeCloneFactory, PrototypeSerializationFactory, WhileClosure.
     </action>
+    <action issue="COLLECTIONS-580" dev="tn" type="fix">
+      Added validation when de-serializing a "MultiValueMap#ReflectionFactory":
+      only Collection classes are allowed, otherwise an UnsupportedOperationException
+      will be thrown during de-serialization.
+    </action>
     <action issue="COLLECTIONS-576" dev="tn" type="fix" due-to="Stephan Roch">
       Subclasses of MultiKey did not re-calculate their hashcode after de-serialization.
     </action>

Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java?rev=1714360&r1=1714359&r2=1714360&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java (original)
+++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/map/MultiValueMap.java Sat Nov 14 20:24:42 2015
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
-
 import java.util.AbstractCollection;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -209,6 +208,7 @@ public class MultiValueMap<K, V> extends
      * @param value the value to remove
      * @return {@code true} if the mapping was removed, {@code false} otherwise
      */
+    @Override
     public boolean removeMapping(final Object key, final Object value) {
         final Collection<V> valuesForKey = getCollection(key);
         if (valuesForKey == null) {
@@ -434,14 +434,18 @@ public class MultiValueMap<K, V> extends
                 }
                 final K key = keyIterator.next();
                 final Transformer<V, Entry<K, V>> transformer = new Transformer<V, Entry<K, V>>() {
+                    @Override
                     public Entry<K, V> transform(final V input) {
                         return new Entry<K, V>() {
+                            @Override
                             public K getKey() {
                                 return key;
                             }
+                            @Override
                             public V getValue() {
                                 return input;
                             }
+                            @Override
                             public V setValue(V value) {
                                 throw new UnsupportedOperationException();
                             }
@@ -519,6 +523,7 @@ public class MultiValueMap<K, V> extends
             this.iterator = values.iterator();
         }
 
+        @Override
         public void remove() {
             iterator.remove();
             if (values.isEmpty()) {
@@ -526,10 +531,12 @@ public class MultiValueMap<K, V> extends
             }
         }
 
+        @Override
         public boolean hasNext() {
             return iterator.hasNext();
         }
 
+        @Override
         public V next() {
             return iterator.next();
         }
@@ -549,6 +556,7 @@ public class MultiValueMap<K, V> extends
             this.clazz = clazz;
         }
 
+        @Override
         public T create() {
             try {
                 return clazz.newInstance();
@@ -556,6 +564,14 @@ public class MultiValueMap<K, V> extends
                 throw new FunctorException("Cannot instantiate class: " + clazz, ex);
             }
         }
+
+        private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
+            is.defaultReadObject();
+            // ensure that the de-serialized class is a Collection, COLLECTIONS-580
+            if (clazz != null && !Collection.class.isAssignableFrom(clazz)) {
+                throw new UnsupportedOperationException();
+            }
+        }
     }
 
 }

Modified: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java?rev=1714360&r1=1714359&r2=1714360&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java (original)
+++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/map/MultiValueMapTest.java Sat Nov 14 20:24:42 2015
@@ -16,6 +16,11 @@
  */
 package org.apache.commons.collections4.map;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -387,6 +392,39 @@ public class MultiValueMapTest<K, V> ext
         assertEquals(new MultiValueMap<K, V>(), map);
     }
 
+    public void testUnsafeDeSerialization() throws Exception {
+        MultiValueMap map1 = MultiValueMap.multiValueMap(new HashMap(), ArrayList.class);
+        byte[] bytes = serialize(map1);
+        Object result = deserialize(bytes);
+        assertEquals(map1, result);
+        
+        MultiValueMap map2 = MultiValueMap.multiValueMap(new HashMap(), (Class) String.class);
+        bytes = serialize(map2);
+        try {
+            result = deserialize(bytes);
+            fail("unsafe clazz accepted when de-serializing MultiValueMap");
+        } catch (UnsupportedOperationException ex) {
+            // expected
+        }
+    }
+
+    private byte[] serialize(Object object) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+
+        oos.writeObject(object);
+        oos.close();
+
+        return baos.toByteArray();
+    }
+    
+    private Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(data);
+        ObjectInputStream iis = new ObjectInputStream(bais);
+        
+        return iis.readObject();
+    }
+
     //-----------------------------------------------------------------------
     // Manual serialization testing as this class cannot easily 
     // extend the AbstractTestMap