Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8254666

Prevent instantiation of EnumSet subclasses through deserialization



    • CSR
    • Resolution: Approved
    • P3
    • 16
    • core-libs
    • None
    • behavioral
    • minimal
    • Affects the specification of EnumSet in the Serialized Forms page. The change prevents successful deserialization of malformed stream objects, but should be largely benign to well-formed stream objects.
    • Java API
    • SE



      EnumSet is an exemplar of the Serialization Proxy Pattern. As such, it should strictly implement that pattern and demonstrate how best to defend against inappropriate instantiation through deserialization.


      EnumSet is an abstract class that permits subclassing only within the java.util package. There are two concrete subclasses, RegularEnumSet and JumboEnumSet. The serialization proxy pattern serializes all instances of these classes as instances of the proxy, which implies that non-proxy instances should normally never occur in the serial stream. If a non-proxy instance were to occur in the serial stream, this would typically cause EnumSet::readObject to be invoked during deserialization. This method unconditionally throws an exception, preventing the non-proxy instance from being deserialized successfully.

      It is possible for the non-proxy serialized instance of an EnumSet subclass to omit the stream descriptor for the EnumSet superclass. In that case, EnumSet::readObjectNoData would be invoked instead of EnumSet::readObject. However, EnumSet::readObjectNoData is not declared, so would not be invoked. This could allow deserialization of the non-proxy instance to complete successfully.


      To prevent such objects from being deserialized successfully, an EnumSet::readObjectNoData() should be added - whose implementation unconditionally throws an exception, similar to that of the existing EnumSet::readObject.


      To java.util.EnumSet:

      1. Add a minor clarifying method level doc common to the existing readObject, to fix a "no comment" warning.

      2. Add readObjectNoData that unconditionally throws an exception.

          +  * Throws {@code InvalidObjectException}.
             * @param s the stream
             * @throws java.io.InvalidObjectException always
            private void readObject(java.io.ObjectInputStream s)
                throws java.io.InvalidObjectException { ... }
          + /**
          +  * Throws {@code InvalidObjectException}.
          +  * @throws java.io.InvalidObjectException always
          +  */
          + @java.io.Serial
          + private void readObjectNoData()
          +     throws java.io.InvalidObjectException { ... }


        Issue Links



              chegar Chris Hegarty
              chegar Chris Hegarty
              Daniel Fuchs, Roger Riggs, Stuart Marks
              0 Vote for this issue
              1 Start watching this issue