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

add ObjectOutputStream.writeUnshared(), ObjectInputStream.readUnshared() methods

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • 1.4.0
    • 1.4.0
    • core-libs
    • None
    • beta
    • generic
    • generic
    • Verified

      Currently it is possible to obtain references to (potentially private) objects
      during deserialization by appending spurious back references to the stream of serialized data. Security-conscious programmers are encouraged to clone
      sensitive internal objects after deserializing them, to ensure that outside
      parties with access to the serialization stream cannot forge references to them.
      This solution slows performance and wastes memory--two objects must be created
      and a copy operation invoked in order to ensure a unique reference to a single
      usable object.

      A more efficient solution is possible with the addition of two new methods:
      ObjectOutputStream.writeUnshared() and ObjectInputStream.readUnshared(). The
      semantics of these methods are as follows (more or less--this is a rough cut):

      1. ObjectOutputStream.writeUnshared() behaves the same way as
      ObjectOutputStream.writeObject() except for two key differences:

          - the wire handle table is not consulted when writing the object (i.e.,
            writeUnshared() will never write a back reference, even if the
            same object has been written to the stream previously via a call to
            writeObject().

          - the written object is not entered into the wire handle table. Instead,
            a "null" (or equivalent, depending on implementation details yet to be
            worked out) reference is entered into the wire handle table for the
            next available wire handle, ensuring that no subsequent calls
            to writeObject() will ever write a back reference to the wire handle
            allocated for the object written with writeUnshared().

      Note that writing an object with writeUnshared() does not affect the manner
      in which objects referenced in turn by the "unshared" object are serialized.
      In other words, if serializable object A contains a reference to serializable
      object B and A is written with a call to writeUnshared(), B will still be
      written as a normal, "shared" object with a call to writeObject().

      Classes can cause object fields to be written with writeUnshared() instead of
      writeObject() by:

          - defining a class-specific writeObject() method which calls
            writeUnshared() explicitly to write the given fields.

          - defining serialPersistentFields so that it includes ObjectStreamField
            entries for the unshared fields. Each of the "unshared" entries
            should be constructed with a new ObjectStreamField constructor
            which takes a boolean parameter indicating whether or not the
            represented field is "shared".

      2. ObjectInputStream.readUnshared() behaves the same way as
      ObjectInputStream.readObject() except for two differences:

          - calling readUnshared() to deserialize a back reference in the stream
            will cause some form of an ObjectStreamException to be thrown.

          - calling readUnshared() will invalidate the wire handle table entry
            for the deserialized object, so that subsequent back references to the
            wire handle table entry for the unshared object will be unresolvable
            (attempting to read such a back reference should result in some form
            of an ObjectStreamException).

      3. A new constructor should be added to ObjectStreamField which allows
      classes to mark specific fields as "unshared":

          ObjectStreamField(String name, Class cl, boolean shared);

      Storing an ObjectStreamField with shared set to false in the
      serialPersistentFields field of a class would cause the field
      (represented by the ObjectStreamField) to be serialized using
      writeUnshared(), including cases in which the PutField API is used
      to "write" the field value.

      The additions proposed here for ObjectOutputStream and ObjectInputStream
      are orthogonal to one another, and invisible with respect to the
      underlying serialization protocol. An ObjectInputStream supporting
      readUnshared() can read streams written by ObjectOutputStreams without writeUnshared() (and can even call readUnshared() on objects in the stream,
      if the reader is sure that no later attempts will be made to read additional
      references to the object). Similarly, serialization streams written by
      an ObjectOutputStream with calls to writeUnshared() will still be deserializable
      by earlier versions of ObjectInputStream. Hence, these changes do not
      affect compatibility with previous versions of the JDK.

            mwarressunw Michael Warres (Inactive)
            mwarressunw Michael Warres (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: