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