Details
-
Bug
-
Resolution: Fixed
-
P3
-
8
-
b113
-
Verified
Backports
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8194021 | openjdk7u | Brian Burkhalter | P3 | Resolved | Fixed | master |
Description
HashSet.readObject should validate its serial data, similar to what is done in HashMap.
diff --git a/src/share/classes/java/util/HashSet.java b/src/share/classes/java/util/HashSet.java
--- a/src/share/classes/java/util/HashSet.java
+++ b/src/share/classes/java/util/HashSet.java
@@ -24,6 +24,8 @@
*/
package java.util;
+
+import java.io.InvalidObjectException;
/**
* This class implements the <tt>Set</tt> interface, backed by a hash table
@@ -293,17 +295,20 @@ public class HashSet<E>
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
-
- // Read in HashMap capacity and load factor and create backing HashMap
- int capacity = s.readInt();
+ s.readInt(); // Read and ignore capacity
float loadFactor = s.readFloat();
+ if (loadFactor <= 0 || Float.isNaN(loadFactor))
+ throw new InvalidObjectException("Illegal load factor: " +
+ loadFactor);
+ int size = s.readInt();
+ if (size < 0)
+ throw new InvalidObjectException("Illegal element count: " + size);
+ // Compute capacity by number of elements and desired load (if >= 0.25)
+ int capacity = (int)Math.min(size * Math.min(1 / loadFactor, 4.0f),
+ HashMap.MAXIMUM_CAPACITY);
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
-
- // Read in size
- int size = s.readInt();
-
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
@SuppressWarnings("unchecked")
diff --git a/src/share/classes/java/util/HashSet.java b/src/share/classes/java/util/HashSet.java
--- a/src/share/classes/java/util/HashSet.java
+++ b/src/share/classes/java/util/HashSet.java
@@ -24,6 +24,8 @@
*/
package java.util;
+
+import java.io.InvalidObjectException;
/**
* This class implements the <tt>Set</tt> interface, backed by a hash table
@@ -293,17 +295,20 @@ public class HashSet<E>
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
-
- // Read in HashMap capacity and load factor and create backing HashMap
- int capacity = s.readInt();
+ s.readInt(); // Read and ignore capacity
float loadFactor = s.readFloat();
+ if (loadFactor <= 0 || Float.isNaN(loadFactor))
+ throw new InvalidObjectException("Illegal load factor: " +
+ loadFactor);
+ int size = s.readInt();
+ if (size < 0)
+ throw new InvalidObjectException("Illegal element count: " + size);
+ // Compute capacity by number of elements and desired load (if >= 0.25)
+ int capacity = (int)Math.min(size * Math.min(1 / loadFactor, 4.0f),
+ HashMap.MAXIMUM_CAPACITY);
map = (((HashSet<?>)this) instanceof LinkedHashSet ?
new LinkedHashMap<E,Object>(capacity, loadFactor) :
new HashMap<E,Object>(capacity, loadFactor));
-
- // Read in size
- int size = s.readInt();
-
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
@SuppressWarnings("unchecked")
Attachments
Issue Links
- backported by
-
JDK-8194021 More defensive HashSet.readObject
- Resolved
- relates to
-
JDK-8026216 Improve test coverage of collections serialization and deserialization
- Open