1 /*
   2  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.io.ObjectStreamClass.WeakClassKey;
  29 import java.lang.ref.ReferenceQueue;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.Modifier;
  32 import java.lang.reflect.Proxy;
  33 import java.security.AccessControlContext;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 import java.security.PrivilegedActionException;
  37 import java.security.PrivilegedExceptionAction;
  38 import java.util.Arrays;
  39 import java.util.HashMap;
  40 import java.util.Objects;
  41 import java.util.concurrent.ConcurrentHashMap;
  42 import java.util.concurrent.ConcurrentMap;
  43 
  44 import static java.io.ObjectStreamClass.processQueue;
  45 
  46 import sun.misc.ObjectInputFilter;
  47 import sun.misc.ObjectStreamClassValidator;
  48 import sun.misc.SharedSecrets;
  49 import sun.reflect.misc.ReflectUtil;
  50 import sun.misc.JavaOISAccess;
  51 import sun.util.logging.PlatformLogger;
  52 
  53 /**
  54  * An ObjectInputStream deserializes primitive data and objects previously
  55  * written using an ObjectOutputStream.
  56  *
  57  * <p>ObjectOutputStream and ObjectInputStream can provide an application with
  58  * persistent storage for graphs of objects when used with a FileOutputStream
  59  * and FileInputStream respectively.  ObjectInputStream is used to recover
  60  * those objects previously serialized. Other uses include passing objects
  61  * between hosts using a socket stream or for marshaling and unmarshaling
  62  * arguments and parameters in a remote communication system.
  63  *
  64  * <p>ObjectInputStream ensures that the types of all objects in the graph
  65  * created from the stream match the classes present in the Java Virtual
  66  * Machine.  Classes are loaded as required using the standard mechanisms.
  67  *
  68  * <p>Only objects that support the java.io.Serializable or
  69  * java.io.Externalizable interface can be read from streams.
  70  *
  71  * <p>The method <code>readObject</code> is used to read an object from the
  72  * stream.  Java's safe casting should be used to get the desired type.  In
  73  * Java, strings and arrays are objects and are treated as objects during
  74  * serialization. When read they need to be cast to the expected type.
  75  *
  76  * <p>Primitive data types can be read from the stream using the appropriate
  77  * method on DataInput.
  78  *
  79  * <p>The default deserialization mechanism for objects restores the contents
  80  * of each field to the value and type it had when it was written.  Fields
  81  * declared as transient or static are ignored by the deserialization process.
  82  * References to other objects cause those objects to be read from the stream
  83  * as necessary.  Graphs of objects are restored correctly using a reference
  84  * sharing mechanism.  New objects are always allocated when deserializing,
  85  * which prevents existing objects from being overwritten.
  86  *
  87  * <p>Reading an object is analogous to running the constructors of a new
  88  * object.  Memory is allocated for the object and initialized to zero (NULL).
  89  * No-arg constructors are invoked for the non-serializable classes and then
  90  * the fields of the serializable classes are restored from the stream starting
  91  * with the serializable class closest to java.lang.object and finishing with
  92  * the object's most specific class.
  93  *
  94  * <p>For example to read from a stream as written by the example in
  95  * ObjectOutputStream:
  96  * <br>
  97  * <pre>
  98  *      FileInputStream fis = new FileInputStream("t.tmp");
  99  *      ObjectInputStream ois = new ObjectInputStream(fis);
 100  *
 101  *      int i = ois.readInt();
 102  *      String today = (String) ois.readObject();
 103  *      Date date = (Date) ois.readObject();
 104  *
 105  *      ois.close();
 106  * </pre>
 107  *
 108  * <p>Classes control how they are serialized by implementing either the
 109  * java.io.Serializable or java.io.Externalizable interfaces.
 110  *
 111  * <p>Implementing the Serializable interface allows object serialization to
 112  * save and restore the entire state of the object and it allows classes to
 113  * evolve between the time the stream is written and the time it is read.  It
 114  * automatically traverses references between objects, saving and restoring
 115  * entire graphs.
 116  *
 117  * <p>Serializable classes that require special handling during the
 118  * serialization and deserialization process should implement the following
 119  * methods:
 120  *
 121  * <pre>
 122  * private void writeObject(java.io.ObjectOutputStream stream)
 123  *     throws IOException;
 124  * private void readObject(java.io.ObjectInputStream stream)
 125  *     throws IOException, ClassNotFoundException;
 126  * private void readObjectNoData()
 127  *     throws ObjectStreamException;
 128  * </pre>
 129  *
 130  * <p>The readObject method is responsible for reading and restoring the state
 131  * of the object for its particular class using data written to the stream by
 132  * the corresponding writeObject method.  The method does not need to concern
 133  * itself with the state belonging to its superclasses or subclasses.  State is
 134  * restored by reading data from the ObjectInputStream for the individual
 135  * fields and making assignments to the appropriate fields of the object.
 136  * Reading primitive data types is supported by DataInput.
 137  *
 138  * <p>Any attempt to read object data which exceeds the boundaries of the
 139  * custom data written by the corresponding writeObject method will cause an
 140  * OptionalDataException to be thrown with an eof field value of true.
 141  * Non-object reads which exceed the end of the allotted data will reflect the
 142  * end of data in the same way that they would indicate the end of the stream:
 143  * bytewise reads will return -1 as the byte read or number of bytes read, and
 144  * primitive reads will throw EOFExceptions.  If there is no corresponding
 145  * writeObject method, then the end of default serialized data marks the end of
 146  * the allotted data.
 147  *
 148  * <p>Primitive and object read calls issued from within a readExternal method
 149  * behave in the same manner--if the stream is already positioned at the end of
 150  * data written by the corresponding writeExternal method, object reads will
 151  * throw OptionalDataExceptions with eof set to true, bytewise reads will
 152  * return -1, and primitive reads will throw EOFExceptions.  Note that this
 153  * behavior does not hold for streams written with the old
 154  * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
 155  * end of data written by writeExternal methods is not demarcated, and hence
 156  * cannot be detected.
 157  *
 158  * <p>The readObjectNoData method is responsible for initializing the state of
 159  * the object for its particular class in the event that the serialization
 160  * stream does not list the given class as a superclass of the object being
 161  * deserialized.  This may occur in cases where the receiving party uses a
 162  * different version of the deserialized instance's class than the sending
 163  * party, and the receiver's version extends classes that are not extended by
 164  * the sender's version.  This may also occur if the serialization stream has
 165  * been tampered; hence, readObjectNoData is useful for initializing
 166  * deserialized objects properly despite a "hostile" or incomplete source
 167  * stream.
 168  *
 169  * <p>Serialization does not read or assign values to the fields of any object
 170  * that does not implement the java.io.Serializable interface.  Subclasses of
 171  * Objects that are not serializable can be serializable. In this case the
 172  * non-serializable class must have a no-arg constructor to allow its fields to
 173  * be initialized.  In this case it is the responsibility of the subclass to
 174  * save and restore the state of the non-serializable class. It is frequently
 175  * the case that the fields of that class are accessible (public, package, or
 176  * protected) or that there are get and set methods that can be used to restore
 177  * the state.
 178  *
 179  * <p>Any exception that occurs while deserializing an object will be caught by
 180  * the ObjectInputStream and abort the reading process.
 181  *
 182  * <p>Implementing the Externalizable interface allows the object to assume
 183  * complete control over the contents and format of the object's serialized
 184  * form.  The methods of the Externalizable interface, writeExternal and
 185  * readExternal, are called to save and restore the objects state.  When
 186  * implemented by a class they can write and read their own state using all of
 187  * the methods of ObjectOutput and ObjectInput.  It is the responsibility of
 188  * the objects to handle any versioning that occurs.
 189  *
 190  * <p>Enum constants are deserialized differently than ordinary serializable or
 191  * externalizable objects.  The serialized form of an enum constant consists
 192  * solely of its name; field values of the constant are not transmitted.  To
 193  * deserialize an enum constant, ObjectInputStream reads the constant name from
 194  * the stream; the deserialized constant is then obtained by calling the static
 195  * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
 196  * base type and the received constant name as arguments.  Like other
 197  * serializable or externalizable objects, enum constants can function as the
 198  * targets of back references appearing subsequently in the serialization
 199  * stream.  The process by which enum constants are deserialized cannot be
 200  * customized: any class-specific readObject, readObjectNoData, and readResolve
 201  * methods defined by enum types are ignored during deserialization.
 202  * Similarly, any serialPersistentFields or serialVersionUID field declarations
 203  * are also ignored--all enum types have a fixed serialVersionUID of 0L.
 204  *
 205  * @author      Mike Warres
 206  * @author      Roger Riggs
 207  * @see java.io.DataInput
 208  * @see java.io.ObjectOutputStream
 209  * @see java.io.Serializable
 210  * @see <a href="../../../platform/serialization/spec/input.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
 211  * @since   JDK1.1
 212  */
 213 public class ObjectInputStream
 214     extends InputStream implements ObjectInput, ObjectStreamConstants
 215 {
 216     /** handle value representing null */
 217     private static final int NULL_HANDLE = -1;
 218 
 219     /** marker for unshared objects in internal handle table */
 220     private static final Object unsharedMarker = new Object();
 221 
 222     /** table mapping primitive type names to corresponding class objects */
 223     private static final HashMap<String, Class<?>> primClasses
 224         = new HashMap<>(8, 1.0F);
 225     static {
 226         primClasses.put("boolean", boolean.class);
 227         primClasses.put("byte", byte.class);
 228         primClasses.put("char", char.class);
 229         primClasses.put("short", short.class);
 230         primClasses.put("int", int.class);
 231         primClasses.put("long", long.class);
 232         primClasses.put("float", float.class);
 233         primClasses.put("double", double.class);
 234         primClasses.put("void", void.class);
 235     }
 236 
 237     private static class Caches {
 238         /** cache of subclass security audit results */
 239         static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
 240             new ConcurrentHashMap<>();
 241 
 242         /** queue for WeakReferences to audited subclasses */
 243         static final ReferenceQueue<Class<?>> subclassAuditsQueue =
 244             new ReferenceQueue<>();
 245     }
 246 
 247     static {
 248         /* Setup access so sun.misc can invoke package private functions. */
 249         sun.misc.SharedSecrets.setJavaOISAccess(new JavaOISAccess() {
 250             public void setObjectInputFilter(ObjectInputStream stream, ObjectInputFilter filter) {
 251                 stream.setInternalObjectInputFilter(filter);
 252             }
 253 
 254             public ObjectInputFilter getObjectInputFilter(ObjectInputStream stream) {
 255                 return stream.getInternalObjectInputFilter();
 256             }
 257         });
 258     }
 259 
 260     /*
 261      * Separate class to defer initialization of logging until needed.
 262      */
 263     private static class Logging {
 264 
 265         /*
 266          * Logger for ObjectInputFilter results.
 267          * Setup the filter logger if it is set to INFO or WARNING.
 268          * (Assuming it will not change).
 269          */
 270         private static final PlatformLogger traceLogger;
 271         private static final PlatformLogger infoLogger;
 272         static {
 273             PlatformLogger filterLog = PlatformLogger.getLogger("java.io.serialization");
 274             infoLogger = (filterLog != null &&
 275                 filterLog.isLoggable(PlatformLogger.Level.INFO)) ? filterLog : null;
 276             traceLogger = (filterLog != null &&
 277                 filterLog.isLoggable(PlatformLogger.Level.FINER)) ? filterLog : null;
 278         }
 279     }
 280 
 281     /** filter stream for handling block data conversion */
 282     private final BlockDataInputStream bin;
 283     /** validation callback list */
 284     private final ValidationList vlist;
 285     /** recursion depth */
 286     private long depth;
 287     /** Total number of references to any type of object, class, enum, proxy, etc. */
 288     private long totalObjectRefs;
 289     /** whether stream is closed */
 290     private boolean closed;
 291 
 292     /** wire handle -> obj/exception map */
 293     private final HandleTable handles;
 294     /** scratch field for passing handle values up/down call stack */
 295     private int passHandle = NULL_HANDLE;
 296     /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
 297     private boolean defaultDataEnd = false;
 298 
 299     /** buffer for reading primitive field values */
 300     private byte[] primVals;
 301 
 302     /** if true, invoke readObjectOverride() instead of readObject() */
 303     private final boolean enableOverride;
 304     /** if true, invoke resolveObject() */
 305     private boolean enableResolve;
 306 
 307     /**
 308      * Context during upcalls to class-defined readObject methods; holds
 309      * object currently being deserialized and descriptor for current class.
 310      * Null when not during readObject upcall.
 311      */
 312     private SerialCallbackContext curContext;
 313 
 314     /**
 315      * Filter of class descriptors and classes read from the stream;
 316      * may be null.
 317      */
 318     private ObjectInputFilter serialFilter;
 319 
 320     /**
 321      * Creates an ObjectInputStream that reads from the specified InputStream.
 322      * A serialization stream header is read from the stream and verified.
 323      * This constructor will block until the corresponding ObjectOutputStream
 324      * has written and flushed the header.
 325      *
 326      * <p>If a security manager is installed, this constructor will check for
 327      * the "enableSubclassImplementation" SerializablePermission when invoked
 328      * directly or indirectly by the constructor of a subclass which overrides
 329      * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
 330      * methods.
 331      *
 332      * @param   in input stream to read from
 333      * @throws  StreamCorruptedException if the stream header is incorrect
 334      * @throws  IOException if an I/O error occurs while reading stream header
 335      * @throws  SecurityException if untrusted subclass illegally overrides
 336      *          security-sensitive methods
 337      * @throws  NullPointerException if <code>in</code> is <code>null</code>
 338      * @see     ObjectInputStream#ObjectInputStream()
 339      * @see     ObjectInputStream#readFields()
 340      * @see     ObjectOutputStream#ObjectOutputStream(OutputStream)
 341      */
 342     public ObjectInputStream(InputStream in) throws IOException {
 343         verifySubclass();
 344         bin = new BlockDataInputStream(in);
 345         handles = new HandleTable(10);
 346         vlist = new ValidationList();
 347         serialFilter = ObjectInputFilter.Config.getSerialFilter();
 348         enableOverride = false;
 349         readStreamHeader();
 350         bin.setBlockDataMode(true);
 351     }
 352 
 353     /**
 354      * Provide a way for subclasses that are completely reimplementing
 355      * ObjectInputStream to not have to allocate private data just used by this
 356      * implementation of ObjectInputStream.
 357      *
 358      * <p>If there is a security manager installed, this method first calls the
 359      * security manager's <code>checkPermission</code> method with the
 360      * <code>SerializablePermission("enableSubclassImplementation")</code>
 361      * permission to ensure it's ok to enable subclassing.
 362      *
 363      * @throws  SecurityException if a security manager exists and its
 364      *          <code>checkPermission</code> method denies enabling
 365      *          subclassing.
 366      * @throws  IOException if an I/O error occurs while creating this stream
 367      * @see SecurityManager#checkPermission
 368      * @see java.io.SerializablePermission
 369      */
 370     protected ObjectInputStream() throws IOException, SecurityException {
 371         SecurityManager sm = System.getSecurityManager();
 372         if (sm != null) {
 373             sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
 374         }
 375         bin = null;
 376         handles = null;
 377         vlist = null;
 378         serialFilter = ObjectInputFilter.Config.getSerialFilter();
 379         enableOverride = true;
 380     }
 381 
 382     /**
 383      * Read an object from the ObjectInputStream.  The class of the object, the
 384      * signature of the class, and the values of the non-transient and
 385      * non-static fields of the class and all of its supertypes are read.
 386      * Default deserializing for a class can be overridden using the writeObject
 387      * and readObject methods.  Objects referenced by this object are read
 388      * transitively so that a complete equivalent graph of objects is
 389      * reconstructed by readObject.
 390      *
 391      * <p>The root object is completely restored when all of its fields and the
 392      * objects it references are completely restored.  At this point the object
 393      * validation callbacks are executed in order based on their registered
 394      * priorities. The callbacks are registered by objects (in the readObject
 395      * special methods) as they are individually restored.
 396      *
 397      * <p>Exceptions are thrown for problems with the InputStream and for
 398      * classes that should not be deserialized.  All exceptions are fatal to
 399      * the InputStream and leave it in an indeterminate state; it is up to the
 400      * caller to ignore or recover the stream state.
 401      *
 402      * @throws  ClassNotFoundException Class of a serialized object cannot be
 403      *          found.
 404      * @throws  InvalidClassException Something is wrong with a class used by
 405      *          serialization.
 406      * @throws  StreamCorruptedException Control information in the
 407      *          stream is inconsistent.
 408      * @throws  OptionalDataException Primitive data was found in the
 409      *          stream instead of objects.
 410      * @throws  IOException Any of the usual Input/Output related exceptions.
 411      */
 412     public final Object readObject()
 413         throws IOException, ClassNotFoundException
 414     {
 415         if (enableOverride) {
 416             return readObjectOverride();
 417         }
 418 
 419         // if nested read, passHandle contains handle of enclosing object
 420         int outerHandle = passHandle;
 421         try {
 422             Object obj = readObject0(false);
 423             handles.markDependency(outerHandle, passHandle);
 424             ClassNotFoundException ex = handles.lookupException(passHandle);
 425             if (ex != null) {
 426                 throw ex;
 427             }
 428             if (depth == 0) {
 429                 vlist.doCallbacks();
 430             }
 431             return obj;
 432         } finally {
 433             passHandle = outerHandle;
 434             if (closed && depth == 0) {
 435                 clear();
 436             }
 437         }
 438     }
 439 
 440     /**
 441      * This method is called by trusted subclasses of ObjectOutputStream that
 442      * constructed ObjectOutputStream using the protected no-arg constructor.
 443      * The subclass is expected to provide an override method with the modifier
 444      * "final".
 445      *
 446      * @return  the Object read from the stream.
 447      * @throws  ClassNotFoundException Class definition of a serialized object
 448      *          cannot be found.
 449      * @throws  OptionalDataException Primitive data was found in the stream
 450      *          instead of objects.
 451      * @throws  IOException if I/O errors occurred while reading from the
 452      *          underlying stream
 453      * @see #ObjectInputStream()
 454      * @see #readObject()
 455      * @since 1.2
 456      */
 457     protected Object readObjectOverride()
 458         throws IOException, ClassNotFoundException
 459     {
 460         return null;
 461     }
 462 
 463     /**
 464      * Reads an "unshared" object from the ObjectInputStream.  This method is
 465      * identical to readObject, except that it prevents subsequent calls to
 466      * readObject and readUnshared from returning additional references to the
 467      * deserialized instance obtained via this call.  Specifically:
 468      * <ul>
 469      *   <li>If readUnshared is called to deserialize a back-reference (the
 470      *       stream representation of an object which has been written
 471      *       previously to the stream), an ObjectStreamException will be
 472      *       thrown.
 473      *
 474      *   <li>If readUnshared returns successfully, then any subsequent attempts
 475      *       to deserialize back-references to the stream handle deserialized
 476      *       by readUnshared will cause an ObjectStreamException to be thrown.
 477      * </ul>
 478      * Deserializing an object via readUnshared invalidates the stream handle
 479      * associated with the returned object.  Note that this in itself does not
 480      * always guarantee that the reference returned by readUnshared is unique;
 481      * the deserialized object may define a readResolve method which returns an
 482      * object visible to other parties, or readUnshared may return a Class
 483      * object or enum constant obtainable elsewhere in the stream or through
 484      * external means. If the deserialized object defines a readResolve method
 485      * and the invocation of that method returns an array, then readUnshared
 486      * returns a shallow clone of that array; this guarantees that the returned
 487      * array object is unique and cannot be obtained a second time from an
 488      * invocation of readObject or readUnshared on the ObjectInputStream,
 489      * even if the underlying data stream has been manipulated.
 490      *
 491      * <p>ObjectInputStream subclasses which override this method can only be
 492      * constructed in security contexts possessing the
 493      * "enableSubclassImplementation" SerializablePermission; any attempt to
 494      * instantiate such a subclass without this permission will cause a
 495      * SecurityException to be thrown.
 496      *
 497      * @return  reference to deserialized object
 498      * @throws  ClassNotFoundException if class of an object to deserialize
 499      *          cannot be found
 500      * @throws  StreamCorruptedException if control information in the stream
 501      *          is inconsistent
 502      * @throws  ObjectStreamException if object to deserialize has already
 503      *          appeared in stream
 504      * @throws  OptionalDataException if primitive data is next in stream
 505      * @throws  IOException if an I/O error occurs during deserialization
 506      * @since   1.4
 507      */
 508     public Object readUnshared() throws IOException, ClassNotFoundException {
 509         // if nested read, passHandle contains handle of enclosing object
 510         int outerHandle = passHandle;
 511         try {
 512             Object obj = readObject0(true);
 513             handles.markDependency(outerHandle, passHandle);
 514             ClassNotFoundException ex = handles.lookupException(passHandle);
 515             if (ex != null) {
 516                 throw ex;
 517             }
 518             if (depth == 0) {
 519                 vlist.doCallbacks();
 520             }
 521             return obj;
 522         } finally {
 523             passHandle = outerHandle;
 524             if (closed && depth == 0) {
 525                 clear();
 526             }
 527         }
 528     }
 529 
 530     /**
 531      * Read the non-static and non-transient fields of the current class from
 532      * this stream.  This may only be called from the readObject method of the
 533      * class being deserialized. It will throw the NotActiveException if it is
 534      * called otherwise.
 535      *
 536      * @throws  ClassNotFoundException if the class of a serialized object
 537      *          could not be found.
 538      * @throws  IOException if an I/O error occurs.
 539      * @throws  NotActiveException if the stream is not currently reading
 540      *          objects.
 541      */
 542     public void defaultReadObject()
 543         throws IOException, ClassNotFoundException
 544     {
 545         SerialCallbackContext ctx = curContext;
 546         if (ctx == null) {
 547             throw new NotActiveException("not in call to readObject");
 548         }
 549         Object curObj = ctx.getObj();
 550         ObjectStreamClass curDesc = ctx.getDesc();
 551         bin.setBlockDataMode(false);
 552         defaultReadFields(curObj, curDesc);
 553         bin.setBlockDataMode(true);
 554         if (!curDesc.hasWriteObjectData()) {
 555             /*
 556              * Fix for 4360508: since stream does not contain terminating
 557              * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
 558              * knows to simulate end-of-custom-data behavior.
 559              */
 560             defaultDataEnd = true;
 561         }
 562         ClassNotFoundException ex = handles.lookupException(passHandle);
 563         if (ex != null) {
 564             throw ex;
 565         }
 566     }
 567 
 568     /**
 569      * Reads the persistent fields from the stream and makes them available by
 570      * name.
 571      *
 572      * @return  the <code>GetField</code> object representing the persistent
 573      *          fields of the object being deserialized
 574      * @throws  ClassNotFoundException if the class of a serialized object
 575      *          could not be found.
 576      * @throws  IOException if an I/O error occurs.
 577      * @throws  NotActiveException if the stream is not currently reading
 578      *          objects.
 579      * @since 1.2
 580      */
 581     public ObjectInputStream.GetField readFields()
 582         throws IOException, ClassNotFoundException
 583     {
 584         SerialCallbackContext ctx = curContext;
 585         if (ctx == null) {
 586             throw new NotActiveException("not in call to readObject");
 587         }
 588         Object curObj = ctx.getObj();
 589         ObjectStreamClass curDesc = ctx.getDesc();
 590         bin.setBlockDataMode(false);
 591         GetFieldImpl getField = new GetFieldImpl(curDesc);
 592         getField.readFields();
 593         bin.setBlockDataMode(true);
 594         if (!curDesc.hasWriteObjectData()) {
 595             /*
 596              * Fix for 4360508: since stream does not contain terminating
 597              * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
 598              * knows to simulate end-of-custom-data behavior.
 599              */
 600             defaultDataEnd = true;
 601         }
 602 
 603         return getField;
 604     }
 605 
 606     /**
 607      * Register an object to be validated before the graph is returned.  While
 608      * similar to resolveObject these validations are called after the entire
 609      * graph has been reconstituted.  Typically, a readObject method will
 610      * register the object with the stream so that when all of the objects are
 611      * restored a final set of validations can be performed.
 612      *
 613      * @param   obj the object to receive the validation callback.
 614      * @param   prio controls the order of callbacks;zero is a good default.
 615      *          Use higher numbers to be called back earlier, lower numbers for
 616      *          later callbacks. Within a priority, callbacks are processed in
 617      *          no particular order.
 618      * @throws  NotActiveException The stream is not currently reading objects
 619      *          so it is invalid to register a callback.
 620      * @throws  InvalidObjectException The validation object is null.
 621      */
 622     public void registerValidation(ObjectInputValidation obj, int prio)
 623         throws NotActiveException, InvalidObjectException
 624     {
 625         if (depth == 0) {
 626             throw new NotActiveException("stream inactive");
 627         }
 628         vlist.register(obj, prio);
 629     }
 630 
 631     /**
 632      * Load the local class equivalent of the specified stream class
 633      * description.  Subclasses may implement this method to allow classes to
 634      * be fetched from an alternate source.
 635      *
 636      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 637      * <code>annotateClass</code>.  This method will be invoked only once for
 638      * each unique class in the stream.  This method can be implemented by
 639      * subclasses to use an alternate loading mechanism but must return a
 640      * <code>Class</code> object. Once returned, if the class is not an array
 641      * class, its serialVersionUID is compared to the serialVersionUID of the
 642      * serialized class, and if there is a mismatch, the deserialization fails
 643      * and an {@link InvalidClassException} is thrown.
 644      *
 645      * <p>The default implementation of this method in
 646      * <code>ObjectInputStream</code> returns the result of calling
 647      * <pre>
 648      *     Class.forName(desc.getName(), false, loader)
 649      * </pre>
 650      * where <code>loader</code> is determined as follows: if there is a
 651      * method on the current thread's stack whose declaring class was
 652      * defined by a user-defined class loader (and was not a generated to
 653      * implement reflective invocations), then <code>loader</code> is class
 654      * loader corresponding to the closest such method to the currently
 655      * executing frame; otherwise, <code>loader</code> is
 656      * <code>null</code>. If this call results in a
 657      * <code>ClassNotFoundException</code> and the name of the passed
 658      * <code>ObjectStreamClass</code> instance is the Java language keyword
 659      * for a primitive type or void, then the <code>Class</code> object
 660      * representing that primitive type or void will be returned
 661      * (e.g., an <code>ObjectStreamClass</code> with the name
 662      * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>).
 663      * Otherwise, the <code>ClassNotFoundException</code> will be thrown to
 664      * the caller of this method.
 665      *
 666      * @param   desc an instance of class <code>ObjectStreamClass</code>
 667      * @return  a <code>Class</code> object corresponding to <code>desc</code>
 668      * @throws  IOException any of the usual Input/Output exceptions.
 669      * @throws  ClassNotFoundException if class of a serialized object cannot
 670      *          be found.
 671      */
 672     protected Class<?> resolveClass(ObjectStreamClass desc)
 673         throws IOException, ClassNotFoundException
 674     {
 675         String name = desc.getName();
 676         try {
 677             return Class.forName(name, false, latestUserDefinedLoader());
 678         } catch (ClassNotFoundException ex) {
 679             Class<?> cl = primClasses.get(name);
 680             if (cl != null) {
 681                 return cl;
 682             } else {
 683                 throw ex;
 684             }
 685         }
 686     }
 687 
 688     /**
 689      * Returns a proxy class that implements the interfaces named in a proxy
 690      * class descriptor; subclasses may implement this method to read custom
 691      * data from the stream along with the descriptors for dynamic proxy
 692      * classes, allowing them to use an alternate loading mechanism for the
 693      * interfaces and the proxy class.
 694      *
 695      * <p>This method is called exactly once for each unique proxy class
 696      * descriptor in the stream.
 697      *
 698      * <p>The corresponding method in <code>ObjectOutputStream</code> is
 699      * <code>annotateProxyClass</code>.  For a given subclass of
 700      * <code>ObjectInputStream</code> that overrides this method, the
 701      * <code>annotateProxyClass</code> method in the corresponding subclass of
 702      * <code>ObjectOutputStream</code> must write any data or objects read by
 703      * this method.
 704      *
 705      * <p>The default implementation of this method in
 706      * <code>ObjectInputStream</code> returns the result of calling
 707      * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
 708      * objects for the interfaces that are named in the <code>interfaces</code>
 709      * parameter.  The <code>Class</code> object for each interface name
 710      * <code>i</code> is the value returned by calling
 711      * <pre>
 712      *     Class.forName(i, false, loader)
 713      * </pre>
 714      * where <code>loader</code> is that of the first non-<code>null</code>
 715      * class loader up the execution stack, or <code>null</code> if no
 716      * non-<code>null</code> class loaders are on the stack (the same class
 717      * loader choice used by the <code>resolveClass</code> method).  Unless any
 718      * of the resolved interfaces are non-public, this same value of
 719      * <code>loader</code> is also the class loader passed to
 720      * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
 721      * their class loader is passed instead (if more than one non-public
 722      * interface class loader is encountered, an
 723      * <code>IllegalAccessError</code> is thrown).
 724      * If <code>Proxy.getProxyClass</code> throws an
 725      * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
 726      * will throw a <code>ClassNotFoundException</code> containing the
 727      * <code>IllegalArgumentException</code>.
 728      *
 729      * @param interfaces the list of interface names that were
 730      *                deserialized in the proxy class descriptor
 731      * @return  a proxy class for the specified interfaces
 732      * @throws        IOException any exception thrown by the underlying
 733      *                <code>InputStream</code>
 734      * @throws        ClassNotFoundException if the proxy class or any of the
 735      *                named interfaces could not be found
 736      * @see ObjectOutputStream#annotateProxyClass(Class)
 737      * @since 1.3
 738      */
 739     protected Class<?> resolveProxyClass(String[] interfaces)
 740         throws IOException, ClassNotFoundException
 741     {
 742         ClassLoader latestLoader = latestUserDefinedLoader();
 743         ClassLoader nonPublicLoader = null;
 744         boolean hasNonPublicInterface = false;
 745 
 746         // define proxy in class loader of non-public interface(s), if any
 747         Class<?>[] classObjs = new Class<?>[interfaces.length];
 748         for (int i = 0; i < interfaces.length; i++) {
 749             Class<?> cl = Class.forName(interfaces[i], false, latestLoader);
 750             if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
 751                 if (hasNonPublicInterface) {
 752                     if (nonPublicLoader != cl.getClassLoader()) {
 753                         throw new IllegalAccessError(
 754                             "conflicting non-public interface class loaders");
 755                     }
 756                 } else {
 757                     nonPublicLoader = cl.getClassLoader();
 758                     hasNonPublicInterface = true;
 759                 }
 760             }
 761             classObjs[i] = cl;
 762         }
 763         try {
 764             return Proxy.getProxyClass(
 765                 hasNonPublicInterface ? nonPublicLoader : latestLoader,
 766                 classObjs);
 767         } catch (IllegalArgumentException e) {
 768             throw new ClassNotFoundException(null, e);
 769         }
 770     }
 771 
 772     /**
 773      * This method will allow trusted subclasses of ObjectInputStream to
 774      * substitute one object for another during deserialization. Replacing
 775      * objects is disabled until enableResolveObject is called. The
 776      * enableResolveObject method checks that the stream requesting to resolve
 777      * object can be trusted. Every reference to serializable objects is passed
 778      * to resolveObject.  To insure that the private state of objects is not
 779      * unintentionally exposed only trusted streams may use resolveObject.
 780      *
 781      * <p>This method is called after an object has been read but before it is
 782      * returned from readObject.  The default resolveObject method just returns
 783      * the same object.
 784      *
 785      * <p>When a subclass is replacing objects it must insure that the
 786      * substituted object is compatible with every field where the reference
 787      * will be stored.  Objects whose type is not a subclass of the type of the
 788      * field or array element abort the serialization by raising an exception
 789      * and the object is not be stored.
 790      *
 791      * <p>This method is called only once when each object is first
 792      * encountered.  All subsequent references to the object will be redirected
 793      * to the new object.
 794      *
 795      * @param   obj object to be substituted
 796      * @return  the substituted object
 797      * @throws  IOException Any of the usual Input/Output exceptions.
 798      */
 799     protected Object resolveObject(Object obj) throws IOException {
 800         return obj;
 801     }
 802 
 803     /**
 804      * Enable the stream to allow objects read from the stream to be replaced.
 805      * When enabled, the resolveObject method is called for every object being
 806      * deserialized.
 807      *
 808      * <p>If <i>enable</i> is true, and there is a security manager installed,
 809      * this method first calls the security manager's
 810      * <code>checkPermission</code> method with the
 811      * <code>SerializablePermission("enableSubstitution")</code> permission to
 812      * ensure it's ok to enable the stream to allow objects read from the
 813      * stream to be replaced.
 814      *
 815      * @param   enable true for enabling use of <code>resolveObject</code> for
 816      *          every object being deserialized
 817      * @return  the previous setting before this method was invoked
 818      * @throws  SecurityException if a security manager exists and its
 819      *          <code>checkPermission</code> method denies enabling the stream
 820      *          to allow objects read from the stream to be replaced.
 821      * @see SecurityManager#checkPermission
 822      * @see java.io.SerializablePermission
 823      */
 824     protected boolean enableResolveObject(boolean enable)
 825         throws SecurityException
 826     {
 827         if (enable == enableResolve) {
 828             return enable;
 829         }
 830         if (enable) {
 831             SecurityManager sm = System.getSecurityManager();
 832             if (sm != null) {
 833                 sm.checkPermission(SUBSTITUTION_PERMISSION);
 834             }
 835         }
 836         enableResolve = enable;
 837         return !enableResolve;
 838     }
 839 
 840     /**
 841      * The readStreamHeader method is provided to allow subclasses to read and
 842      * verify their own stream headers. It reads and verifies the magic number
 843      * and version number.
 844      *
 845      * @throws  IOException if there are I/O errors while reading from the
 846      *          underlying <code>InputStream</code>
 847      * @throws  StreamCorruptedException if control information in the stream
 848      *          is inconsistent
 849      */
 850     protected void readStreamHeader()
 851         throws IOException, StreamCorruptedException
 852     {
 853         short s0 = bin.readShort();
 854         short s1 = bin.readShort();
 855         if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) {
 856             throw new StreamCorruptedException(
 857                 String.format("invalid stream header: %04X%04X", s0, s1));
 858         }
 859     }
 860 
 861     /**
 862      * Read a class descriptor from the serialization stream.  This method is
 863      * called when the ObjectInputStream expects a class descriptor as the next
 864      * item in the serialization stream.  Subclasses of ObjectInputStream may
 865      * override this method to read in class descriptors that have been written
 866      * in non-standard formats (by subclasses of ObjectOutputStream which have
 867      * overridden the <code>writeClassDescriptor</code> method).  By default,
 868      * this method reads class descriptors according to the format defined in
 869      * the Object Serialization specification.
 870      *
 871      * @return  the class descriptor read
 872      * @throws  IOException If an I/O error has occurred.
 873      * @throws  ClassNotFoundException If the Class of a serialized object used
 874      *          in the class descriptor representation cannot be found
 875      * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
 876      * @since 1.3
 877      */
 878     protected ObjectStreamClass readClassDescriptor()
 879         throws IOException, ClassNotFoundException
 880     {
 881         ObjectStreamClass desc = new ObjectStreamClass();
 882         desc.readNonProxy(this);
 883         return desc;
 884     }
 885 
 886     /**
 887      * Reads a byte of data. This method will block if no input is available.
 888      *
 889      * @return  the byte read, or -1 if the end of the stream is reached.
 890      * @throws  IOException If an I/O error has occurred.
 891      */
 892     public int read() throws IOException {
 893         return bin.read();
 894     }
 895 
 896     /**
 897      * Reads into an array of bytes.  This method will block until some input
 898      * is available. Consider using java.io.DataInputStream.readFully to read
 899      * exactly 'length' bytes.
 900      *
 901      * @param   buf the buffer into which the data is read
 902      * @param   off the start offset of the data
 903      * @param   len the maximum number of bytes read
 904      * @return  the actual number of bytes read, -1 is returned when the end of
 905      *          the stream is reached.
 906      * @throws  IOException If an I/O error has occurred.
 907      * @see java.io.DataInputStream#readFully(byte[],int,int)
 908      */
 909     public int read(byte[] buf, int off, int len) throws IOException {
 910         if (buf == null) {
 911             throw new NullPointerException();
 912         }
 913         int endoff = off + len;
 914         if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
 915             throw new IndexOutOfBoundsException();
 916         }
 917         return bin.read(buf, off, len, false);
 918     }
 919 
 920     /**
 921      * Returns the number of bytes that can be read without blocking.
 922      *
 923      * @return  the number of available bytes.
 924      * @throws  IOException if there are I/O errors while reading from the
 925      *          underlying <code>InputStream</code>
 926      */
 927     public int available() throws IOException {
 928         return bin.available();
 929     }
 930 
 931     /**
 932      * Closes the input stream. Must be called to release any resources
 933      * associated with the stream.
 934      *
 935      * @throws  IOException If an I/O error has occurred.
 936      */
 937     public void close() throws IOException {
 938         /*
 939          * Even if stream already closed, propagate redundant close to
 940          * underlying stream to stay consistent with previous implementations.
 941          */
 942         closed = true;
 943         if (depth == 0) {
 944             clear();
 945         }
 946         bin.close();
 947     }
 948 
 949     /**
 950      * Reads in a boolean.
 951      *
 952      * @return  the boolean read.
 953      * @throws  EOFException If end of file is reached.
 954      * @throws  IOException If other I/O error has occurred.
 955      */
 956     public boolean readBoolean() throws IOException {
 957         return bin.readBoolean();
 958     }
 959 
 960     /**
 961      * Reads an 8 bit byte.
 962      *
 963      * @return  the 8 bit byte read.
 964      * @throws  EOFException If end of file is reached.
 965      * @throws  IOException If other I/O error has occurred.
 966      */
 967     public byte readByte() throws IOException  {
 968         return bin.readByte();
 969     }
 970 
 971     /**
 972      * Reads an unsigned 8 bit byte.
 973      *
 974      * @return  the 8 bit byte read.
 975      * @throws  EOFException If end of file is reached.
 976      * @throws  IOException If other I/O error has occurred.
 977      */
 978     public int readUnsignedByte()  throws IOException {
 979         return bin.readUnsignedByte();
 980     }
 981 
 982     /**
 983      * Reads a 16 bit char.
 984      *
 985      * @return  the 16 bit char read.
 986      * @throws  EOFException If end of file is reached.
 987      * @throws  IOException If other I/O error has occurred.
 988      */
 989     public char readChar()  throws IOException {
 990         return bin.readChar();
 991     }
 992 
 993     /**
 994      * Reads a 16 bit short.
 995      *
 996      * @return  the 16 bit short read.
 997      * @throws  EOFException If end of file is reached.
 998      * @throws  IOException If other I/O error has occurred.
 999      */
1000     public short readShort()  throws IOException {
1001         return bin.readShort();
1002     }
1003 
1004     /**
1005      * Reads an unsigned 16 bit short.
1006      *
1007      * @return  the 16 bit short read.
1008      * @throws  EOFException If end of file is reached.
1009      * @throws  IOException If other I/O error has occurred.
1010      */
1011     public int readUnsignedShort() throws IOException {
1012         return bin.readUnsignedShort();
1013     }
1014 
1015     /**
1016      * Reads a 32 bit int.
1017      *
1018      * @return  the 32 bit integer read.
1019      * @throws  EOFException If end of file is reached.
1020      * @throws  IOException If other I/O error has occurred.
1021      */
1022     public int readInt()  throws IOException {
1023         return bin.readInt();
1024     }
1025 
1026     /**
1027      * Reads a 64 bit long.
1028      *
1029      * @return  the read 64 bit long.
1030      * @throws  EOFException If end of file is reached.
1031      * @throws  IOException If other I/O error has occurred.
1032      */
1033     public long readLong()  throws IOException {
1034         return bin.readLong();
1035     }
1036 
1037     /**
1038      * Reads a 32 bit float.
1039      *
1040      * @return  the 32 bit float read.
1041      * @throws  EOFException If end of file is reached.
1042      * @throws  IOException If other I/O error has occurred.
1043      */
1044     public float readFloat() throws IOException {
1045         return bin.readFloat();
1046     }
1047 
1048     /**
1049      * Reads a 64 bit double.
1050      *
1051      * @return  the 64 bit double read.
1052      * @throws  EOFException If end of file is reached.
1053      * @throws  IOException If other I/O error has occurred.
1054      */
1055     public double readDouble() throws IOException {
1056         return bin.readDouble();
1057     }
1058 
1059     /**
1060      * Reads bytes, blocking until all bytes are read.
1061      *
1062      * @param   buf the buffer into which the data is read
1063      * @throws  EOFException If end of file is reached.
1064      * @throws  IOException If other I/O error has occurred.
1065      */
1066     public void readFully(byte[] buf) throws IOException {
1067         bin.readFully(buf, 0, buf.length, false);
1068     }
1069 
1070     /**
1071      * Reads bytes, blocking until all bytes are read.
1072      *
1073      * @param   buf the buffer into which the data is read
1074      * @param   off the start offset of the data
1075      * @param   len the maximum number of bytes to read
1076      * @throws  EOFException If end of file is reached.
1077      * @throws  IOException If other I/O error has occurred.
1078      */
1079     public void readFully(byte[] buf, int off, int len) throws IOException {
1080         int endoff = off + len;
1081         if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
1082             throw new IndexOutOfBoundsException();
1083         }
1084         bin.readFully(buf, off, len, false);
1085     }
1086 
1087     /**
1088      * Skips bytes.
1089      *
1090      * @param   len the number of bytes to be skipped
1091      * @return  the actual number of bytes skipped.
1092      * @throws  IOException If an I/O error has occurred.
1093      */
1094     public int skipBytes(int len) throws IOException {
1095         return bin.skipBytes(len);
1096     }
1097 
1098     /**
1099      * Reads in a line that has been terminated by a \n, \r, \r\n or EOF.
1100      *
1101      * @return  a String copy of the line.
1102      * @throws  IOException if there are I/O errors while reading from the
1103      *          underlying <code>InputStream</code>
1104      * @deprecated This method does not properly convert bytes to characters.
1105      *          see DataInputStream for the details and alternatives.
1106      */
1107     @Deprecated
1108     public String readLine() throws IOException {
1109         return bin.readLine();
1110     }
1111 
1112     /**
1113      * Reads a String in
1114      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
1115      * format.
1116      *
1117      * @return  the String.
1118      * @throws  IOException if there are I/O errors while reading from the
1119      *          underlying <code>InputStream</code>
1120      * @throws  UTFDataFormatException if read bytes do not represent a valid
1121      *          modified UTF-8 encoding of a string
1122      */
1123     public String readUTF() throws IOException {
1124         return bin.readUTF();
1125     }
1126 
1127     /**
1128      * Returns the serialization filter for this stream.
1129      * The serialization filter is the most recent filter set in
1130      * {@link #setInternalObjectInputFilter setInternalObjectInputFilter} or
1131      * the initial process-wide filter from
1132      * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter}.
1133      *
1134      * @return the serialization filter for the stream; may be null
1135      */
1136     private final ObjectInputFilter getInternalObjectInputFilter() {
1137         return serialFilter;
1138     }
1139 
1140     /**
1141      * Set the serialization filter for the stream.
1142      * The filter's {@link ObjectInputFilter#checkInput checkInput} method is called
1143      * for each class and reference in the stream.
1144      * The filter can check any or all of the class, the array length, the number
1145      * of references, the depth of the graph, and the size of the input stream.
1146      * <p>
1147      * If the filter returns {@link ObjectInputFilter.Status#REJECTED Status.REJECTED},
1148      * {@code null} or throws a {@link RuntimeException},
1149      * the active {@code readObject} or {@code readUnshared}
1150      * throws {@link InvalidClassException}, otherwise deserialization
1151      * continues uninterrupted.
1152      * <p>
1153      * The serialization filter is initialized to the value of
1154      * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter}
1155      * when the {@code  ObjectInputStream} is constructed and can be set
1156      * to a custom filter only once.
1157      *
1158      * @implSpec
1159      * The filter, when not {@code null}, is invoked during {@link #readObject readObject}
1160      * and {@link #readUnshared readUnshared} for each object
1161      * (regular or class) in the stream including the following:
1162      * <ul>
1163      *     <li>each object reference previously deserialized from the stream
1164      *     (class is {@code null}, arrayLength is -1),
1165      *     <li>each regular class (class is not {@code null}, arrayLength is -1),
1166      *     <li>each interface of a dynamic proxy and the dynamic proxy class itself
1167      *     (class is not {@code null}, arrayLength is -1),
1168      *     <li>each array is filtered using the array type and length of the array
1169      *     (class is the array type, arrayLength is the requested length),
1170      *     <li>each object replaced by its class' {@code readResolve} method
1171      *         is filtered using the replacement object's class, if not {@code null},
1172      *         and if it is an array, the arrayLength, otherwise -1,
1173      *     <li>and each object replaced by {@link #resolveObject resolveObject}
1174      *         is filtered using the replacement object's class, if not {@code null},
1175      *         and if it is an array, the arrayLength, otherwise -1.
1176      * </ul>
1177      *
1178      * When the {@link ObjectInputFilter#checkInput checkInput} method is invoked
1179      * it is given access to the current class, the array length,
1180      * the current number of references already read from the stream,
1181      * the depth of nested calls to {@link #readObject readObject} or
1182      * {@link #readUnshared readUnshared},
1183      * and the implementation dependent number of bytes consumed from the input stream.
1184      * <p>
1185      * Each call to {@link #readObject readObject} or
1186      * {@link #readUnshared readUnshared} increases the depth by 1
1187      * before reading an object and decreases by 1 before returning
1188      * normally or exceptionally.
1189      * The depth starts at {@code 1} and increases for each nested object and
1190      * decrements when each nested call returns.
1191      * The count of references in the stream starts at {@code 1} and
1192      * is increased before reading an object.
1193      *
1194      * @param filter the filter, may be null
1195      * @throws SecurityException if there is security manager and the
1196      *       {@code SerializablePermission("serialFilter")} is not granted
1197      * @throws IllegalStateException if the {@linkplain #getInternalObjectInputFilter() current filter}
1198      *       is not {@code null} and is not the process-wide filter
1199      */
1200     private final void setInternalObjectInputFilter(ObjectInputFilter filter) {
1201         SecurityManager sm = System.getSecurityManager();
1202         if (sm != null) {
1203             sm.checkPermission(new SerializablePermission("serialFilter"));
1204         }
1205         // Allow replacement of the process-wide filter if not already set
1206         if (serialFilter != null &&
1207                 serialFilter != ObjectInputFilter.Config.getSerialFilter()) {
1208             throw new IllegalStateException("filter can not be set more than once");
1209         }
1210         this.serialFilter = filter;
1211     }
1212 
1213     /**
1214      * Invoke the serialization filter if non-null.
1215      * If the filter rejects or an exception is thrown, throws InvalidClassException.
1216      *
1217      * @param clazz the class; may be null
1218      * @param arrayLength the array length requested; use {@code -1} if not creating an array
1219      * @throws InvalidClassException if it rejected by the filter or
1220      *        a {@link RuntimeException} is thrown
1221      */
1222     private void filterCheck(Class<?> clazz, int arrayLength)
1223             throws InvalidClassException {
1224         if (serialFilter != null) {
1225             RuntimeException ex = null;
1226             ObjectInputFilter.Status status;
1227             try {
1228                 status = serialFilter.checkInput(new FilterValues(clazz, arrayLength,
1229                         totalObjectRefs, depth, bin.getBytesRead()));
1230             } catch (RuntimeException e) {
1231                 // Preventive interception of an exception to log
1232                 status = ObjectInputFilter.Status.REJECTED;
1233                 ex = e;
1234             }
1235             if (status == null  ||
1236                     status == ObjectInputFilter.Status.REJECTED) {
1237                 // Debug logging of filter checks that fail
1238                 if (Logging.infoLogger != null) {
1239                     Logging.infoLogger.info(
1240                             "ObjectInputFilter {0}: {1}, array length: {2}, nRefs: {3}, depth: {4}, bytes: {5}, ex: {6}",
1241                             status, clazz, arrayLength, totalObjectRefs, depth, bin.getBytesRead(),
1242                             Objects.toString(ex, "n/a"));
1243                 }
1244                 InvalidClassException ice = new InvalidClassException("filter status: " + status);
1245                 ice.initCause(ex);
1246                 throw ice;
1247             } else {
1248                 // Trace logging for those that succeed
1249                 if (Logging.traceLogger != null) {
1250                     Logging.traceLogger.finer(
1251                             "ObjectInputFilter {0}: {1}, array length: {2}, nRefs: {3}, depth: {4}, bytes: {5}, ex: {6}",
1252                             status, clazz, arrayLength, totalObjectRefs, depth, bin.getBytesRead(),
1253                             Objects.toString(ex, "n/a"));
1254                 }
1255             }
1256         }
1257     }
1258 
1259     /**
1260      * Provide access to the persistent fields read from the input stream.
1261      */
1262     public static abstract class GetField {
1263 
1264         /**
1265          * Get the ObjectStreamClass that describes the fields in the stream.
1266          *
1267          * @return  the descriptor class that describes the serializable fields
1268          */
1269         public abstract ObjectStreamClass getObjectStreamClass();
1270 
1271         /**
1272          * Return true if the named field is defaulted and has no value in this
1273          * stream.
1274          *
1275          * @param  name the name of the field
1276          * @return true, if and only if the named field is defaulted
1277          * @throws IOException if there are I/O errors while reading from
1278          *         the underlying <code>InputStream</code>
1279          * @throws IllegalArgumentException if <code>name</code> does not
1280          *         correspond to a serializable field
1281          */
1282         public abstract boolean defaulted(String name) throws IOException;
1283 
1284         /**
1285          * Get the value of the named boolean field from the persistent field.
1286          *
1287          * @param  name the name of the field
1288          * @param  val the default value to use if <code>name</code> does not
1289          *         have a value
1290          * @return the value of the named <code>boolean</code> field
1291          * @throws IOException if there are I/O errors while reading from the
1292          *         underlying <code>InputStream</code>
1293          * @throws IllegalArgumentException if type of <code>name</code> is
1294          *         not serializable or if the field type is incorrect
1295          */
1296         public abstract boolean get(String name, boolean val)
1297             throws IOException;
1298 
1299         /**
1300          * Get the value of the named byte field from the persistent field.
1301          *
1302          * @param  name the name of the field
1303          * @param  val the default value to use if <code>name</code> does not
1304          *         have a value
1305          * @return the value of the named <code>byte</code> field
1306          * @throws IOException if there are I/O errors while reading from the
1307          *         underlying <code>InputStream</code>
1308          * @throws IllegalArgumentException if type of <code>name</code> is
1309          *         not serializable or if the field type is incorrect
1310          */
1311         public abstract byte get(String name, byte val) throws IOException;
1312 
1313         /**
1314          * Get the value of the named char field from the persistent field.
1315          *
1316          * @param  name the name of the field
1317          * @param  val the default value to use if <code>name</code> does not
1318          *         have a value
1319          * @return the value of the named <code>char</code> field
1320          * @throws IOException if there are I/O errors while reading from the
1321          *         underlying <code>InputStream</code>
1322          * @throws IllegalArgumentException if type of <code>name</code> is
1323          *         not serializable or if the field type is incorrect
1324          */
1325         public abstract char get(String name, char val) throws IOException;
1326 
1327         /**
1328          * Get the value of the named short field from the persistent field.
1329          *
1330          * @param  name the name of the field
1331          * @param  val the default value to use if <code>name</code> does not
1332          *         have a value
1333          * @return the value of the named <code>short</code> field
1334          * @throws IOException if there are I/O errors while reading from the
1335          *         underlying <code>InputStream</code>
1336          * @throws IllegalArgumentException if type of <code>name</code> is
1337          *         not serializable or if the field type is incorrect
1338          */
1339         public abstract short get(String name, short val) throws IOException;
1340 
1341         /**
1342          * Get the value of the named int field from the persistent field.
1343          *
1344          * @param  name the name of the field
1345          * @param  val the default value to use if <code>name</code> does not
1346          *         have a value
1347          * @return the value of the named <code>int</code> field
1348          * @throws IOException if there are I/O errors while reading from the
1349          *         underlying <code>InputStream</code>
1350          * @throws IllegalArgumentException if type of <code>name</code> is
1351          *         not serializable or if the field type is incorrect
1352          */
1353         public abstract int get(String name, int val) throws IOException;
1354 
1355         /**
1356          * Get the value of the named long field from the persistent field.
1357          *
1358          * @param  name the name of the field
1359          * @param  val the default value to use if <code>name</code> does not
1360          *         have a value
1361          * @return the value of the named <code>long</code> field
1362          * @throws IOException if there are I/O errors while reading from the
1363          *         underlying <code>InputStream</code>
1364          * @throws IllegalArgumentException if type of <code>name</code> is
1365          *         not serializable or if the field type is incorrect
1366          */
1367         public abstract long get(String name, long val) throws IOException;
1368 
1369         /**
1370          * Get the value of the named float field from the persistent field.
1371          *
1372          * @param  name the name of the field
1373          * @param  val the default value to use if <code>name</code> does not
1374          *         have a value
1375          * @return the value of the named <code>float</code> field
1376          * @throws IOException if there are I/O errors while reading from the
1377          *         underlying <code>InputStream</code>
1378          * @throws IllegalArgumentException if type of <code>name</code> is
1379          *         not serializable or if the field type is incorrect
1380          */
1381         public abstract float get(String name, float val) throws IOException;
1382 
1383         /**
1384          * Get the value of the named double field from the persistent field.
1385          *
1386          * @param  name the name of the field
1387          * @param  val the default value to use if <code>name</code> does not
1388          *         have a value
1389          * @return the value of the named <code>double</code> field
1390          * @throws IOException if there are I/O errors while reading from the
1391          *         underlying <code>InputStream</code>
1392          * @throws IllegalArgumentException if type of <code>name</code> is
1393          *         not serializable or if the field type is incorrect
1394          */
1395         public abstract double get(String name, double val) throws IOException;
1396 
1397         /**
1398          * Get the value of the named Object field from the persistent field.
1399          *
1400          * @param  name the name of the field
1401          * @param  val the default value to use if <code>name</code> does not
1402          *         have a value
1403          * @return the value of the named <code>Object</code> field
1404          * @throws IOException if there are I/O errors while reading from the
1405          *         underlying <code>InputStream</code>
1406          * @throws IllegalArgumentException if type of <code>name</code> is
1407          *         not serializable or if the field type is incorrect
1408          */
1409         public abstract Object get(String name, Object val) throws IOException;
1410     }
1411 
1412     /**
1413      * Verifies that this (possibly subclass) instance can be constructed
1414      * without violating security constraints: the subclass must not override
1415      * security-sensitive non-final methods, or else the
1416      * "enableSubclassImplementation" SerializablePermission is checked.
1417      */
1418     private void verifySubclass() {
1419         Class<?> cl = getClass();
1420         if (cl == ObjectInputStream.class) {
1421             return;
1422         }
1423         SecurityManager sm = System.getSecurityManager();
1424         if (sm == null) {
1425             return;
1426         }
1427         processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
1428         WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
1429         Boolean result = Caches.subclassAudits.get(key);
1430         if (result == null) {
1431             result = Boolean.valueOf(auditSubclass(cl));
1432             Caches.subclassAudits.putIfAbsent(key, result);
1433         }
1434         if (result.booleanValue()) {
1435             return;
1436         }
1437         sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
1438     }
1439 
1440     /**
1441      * Performs reflective checks on given subclass to verify that it doesn't
1442      * override security-sensitive non-final methods.  Returns true if subclass
1443      * is "safe", false otherwise.
1444      */
1445     private static boolean auditSubclass(final Class<?> subcl) {
1446         Boolean result = AccessController.doPrivileged(
1447             new PrivilegedAction<Boolean>() {
1448                 public Boolean run() {
1449                     for (Class<?> cl = subcl;
1450                          cl != ObjectInputStream.class;
1451                          cl = cl.getSuperclass())
1452                     {
1453                         try {
1454                             cl.getDeclaredMethod(
1455                                 "readUnshared", (Class[]) null);
1456                             return Boolean.FALSE;
1457                         } catch (NoSuchMethodException ex) {
1458                         }
1459                         try {
1460                             cl.getDeclaredMethod("readFields", (Class[]) null);
1461                             return Boolean.FALSE;
1462                         } catch (NoSuchMethodException ex) {
1463                         }
1464                     }
1465                     return Boolean.TRUE;
1466                 }
1467             }
1468         );
1469         return result.booleanValue();
1470     }
1471 
1472     /**
1473      * Clears internal data structures.
1474      */
1475     private void clear() {
1476         handles.clear();
1477         vlist.clear();
1478     }
1479 
1480     /**
1481      * Underlying readObject implementation.
1482      */
1483     private Object readObject0(boolean unshared) throws IOException {
1484         boolean oldMode = bin.getBlockDataMode();
1485         if (oldMode) {
1486             int remain = bin.currentBlockRemaining();
1487             if (remain > 0) {
1488                 throw new OptionalDataException(remain);
1489             } else if (defaultDataEnd) {
1490                 /*
1491                  * Fix for 4360508: stream is currently at the end of a field
1492                  * value block written via default serialization; since there
1493                  * is no terminating TC_ENDBLOCKDATA tag, simulate
1494                  * end-of-custom-data behavior explicitly.
1495                  */
1496                 throw new OptionalDataException(true);
1497             }
1498             bin.setBlockDataMode(false);
1499         }
1500 
1501         byte tc;
1502         while ((tc = bin.peekByte()) == TC_RESET) {
1503             bin.readByte();
1504             handleReset();
1505         }
1506 
1507         depth++;
1508         totalObjectRefs++;
1509         try {
1510             switch (tc) {
1511                 case TC_NULL:
1512                     return readNull();
1513 
1514                 case TC_REFERENCE:
1515                     return readHandle(unshared);
1516 
1517                 case TC_CLASS:
1518                     return readClass(unshared);
1519 
1520                 case TC_CLASSDESC:
1521                 case TC_PROXYCLASSDESC:
1522                     return readClassDesc(unshared);
1523 
1524                 case TC_STRING:
1525                 case TC_LONGSTRING:
1526                     return checkResolve(readString(unshared));
1527 
1528                 case TC_ARRAY:
1529                     return checkResolve(readArray(unshared));
1530 
1531                 case TC_ENUM:
1532                     return checkResolve(readEnum(unshared));
1533 
1534                 case TC_OBJECT:
1535                     return checkResolve(readOrdinaryObject(unshared));
1536 
1537                 case TC_EXCEPTION:
1538                     IOException ex = readFatalException();
1539                     throw new WriteAbortedException("writing aborted", ex);
1540 
1541                 case TC_BLOCKDATA:
1542                 case TC_BLOCKDATALONG:
1543                     if (oldMode) {
1544                         bin.setBlockDataMode(true);
1545                         bin.peek();             // force header read
1546                         throw new OptionalDataException(
1547                             bin.currentBlockRemaining());
1548                     } else {
1549                         throw new StreamCorruptedException(
1550                             "unexpected block data");
1551                     }
1552 
1553                 case TC_ENDBLOCKDATA:
1554                     if (oldMode) {
1555                         throw new OptionalDataException(true);
1556                     } else {
1557                         throw new StreamCorruptedException(
1558                             "unexpected end of block data");
1559                     }
1560 
1561                 default:
1562                     throw new StreamCorruptedException(
1563                         String.format("invalid type code: %02X", tc));
1564             }
1565         } finally {
1566             depth--;
1567             bin.setBlockDataMode(oldMode);
1568         }
1569     }
1570 
1571     /**
1572      * If resolveObject has been enabled and given object does not have an
1573      * exception associated with it, calls resolveObject to determine
1574      * replacement for object, and updates handle table accordingly.  Returns
1575      * replacement object, or echoes provided object if no replacement
1576      * occurred.  Expects that passHandle is set to given object's handle prior
1577      * to calling this method.
1578      */
1579     private Object checkResolve(Object obj) throws IOException {
1580         if (!enableResolve || handles.lookupException(passHandle) != null) {
1581             return obj;
1582         }
1583         Object rep = resolveObject(obj);
1584         if (rep != obj) {
1585             // The type of the original object has been filtered but resolveObject
1586             // may have replaced it;  filter the replacement's type
1587             if (rep != null) {
1588                 if (rep.getClass().isArray()) {
1589                     filterCheck(rep.getClass(), Array.getLength(rep));
1590                 } else {
1591                     filterCheck(rep.getClass(), -1);
1592                 }
1593             }
1594             handles.setObject(passHandle, rep);
1595         }
1596         return rep;
1597     }
1598 
1599     /**
1600      * Reads string without allowing it to be replaced in stream.  Called from
1601      * within ObjectStreamClass.read().
1602      */
1603     String readTypeString() throws IOException {
1604         int oldHandle = passHandle;
1605         try {
1606             byte tc = bin.peekByte();
1607             switch (tc) {
1608                 case TC_NULL:
1609                     return (String) readNull();
1610 
1611                 case TC_REFERENCE:
1612                     return (String) readHandle(false);
1613 
1614                 case TC_STRING:
1615                 case TC_LONGSTRING:
1616                     return readString(false);
1617 
1618                 default:
1619                     throw new StreamCorruptedException(
1620                         String.format("invalid type code: %02X", tc));
1621             }
1622         } finally {
1623             passHandle = oldHandle;
1624         }
1625     }
1626 
1627     /**
1628      * Reads in null code, sets passHandle to NULL_HANDLE and returns null.
1629      */
1630     private Object readNull() throws IOException {
1631         if (bin.readByte() != TC_NULL) {
1632             throw new InternalError();
1633         }
1634         passHandle = NULL_HANDLE;
1635         return null;
1636     }
1637 
1638     /**
1639      * Reads in object handle, sets passHandle to the read handle, and returns
1640      * object associated with the handle.
1641      */
1642     private Object readHandle(boolean unshared) throws IOException {
1643         if (bin.readByte() != TC_REFERENCE) {
1644             throw new InternalError();
1645         }
1646         passHandle = bin.readInt() - baseWireHandle;
1647         if (passHandle < 0 || passHandle >= handles.size()) {
1648             throw new StreamCorruptedException(
1649                 String.format("invalid handle value: %08X", passHandle +
1650                 baseWireHandle));
1651         }
1652         if (unshared) {
1653             // REMIND: what type of exception to throw here?
1654             throw new InvalidObjectException(
1655                 "cannot read back reference as unshared");
1656         }
1657 
1658         Object obj = handles.lookupObject(passHandle);
1659         if (obj == unsharedMarker) {
1660             // REMIND: what type of exception to throw here?
1661             throw new InvalidObjectException(
1662                 "cannot read back reference to unshared object");
1663         }
1664         filterCheck(null, -1);       // just a check for number of references, depth, no class
1665         return obj;
1666     }
1667 
1668     /**
1669      * Reads in and returns class object.  Sets passHandle to class object's
1670      * assigned handle.  Returns null if class is unresolvable (in which case a
1671      * ClassNotFoundException will be associated with the class' handle in the
1672      * handle table).
1673      */
1674     private Class<?> readClass(boolean unshared) throws IOException {
1675         if (bin.readByte() != TC_CLASS) {
1676             throw new InternalError();
1677         }
1678         ObjectStreamClass desc = readClassDesc(false);
1679         Class<?> cl = desc.forClass();
1680         passHandle = handles.assign(unshared ? unsharedMarker : cl);
1681 
1682         ClassNotFoundException resolveEx = desc.getResolveException();
1683         if (resolveEx != null) {
1684             handles.markException(passHandle, resolveEx);
1685         }
1686 
1687         handles.finish(passHandle);
1688         return cl;
1689     }
1690 
1691     /**
1692      * Reads in and returns (possibly null) class descriptor.  Sets passHandle
1693      * to class descriptor's assigned handle.  If class descriptor cannot be
1694      * resolved to a class in the local VM, a ClassNotFoundException is
1695      * associated with the class descriptor's handle.
1696      */
1697     private ObjectStreamClass readClassDesc(boolean unshared)
1698         throws IOException
1699     {
1700         byte tc = bin.peekByte();
1701         ObjectStreamClass descriptor;
1702         switch (tc) {
1703             case TC_NULL:
1704                 descriptor = (ObjectStreamClass) readNull();
1705                 break;
1706             case TC_REFERENCE:
1707                 descriptor = (ObjectStreamClass) readHandle(unshared);
1708                 break;
1709             case TC_PROXYCLASSDESC:
1710                 descriptor = readProxyDesc(unshared);
1711                 break;
1712             case TC_CLASSDESC:
1713                 descriptor = readNonProxyDesc(unshared);
1714                 break;
1715             default:
1716                 throw new StreamCorruptedException(
1717                     String.format("invalid type code: %02X", tc));
1718         }
1719         if (descriptor != null) {
1720             validateDescriptor(descriptor);
1721         }
1722         return descriptor;
1723     }
1724 
1725     private boolean isCustomSubclass() {
1726         // Return true if this class is a custom subclass of ObjectInputStream
1727         return getClass().getClassLoader()
1728                     != ObjectInputStream.class.getClassLoader();
1729     }
1730 
1731     /**
1732      * Reads in and returns class descriptor for a dynamic proxy class.  Sets
1733      * passHandle to proxy class descriptor's assigned handle.  If proxy class
1734      * descriptor cannot be resolved to a class in the local VM, a
1735      * ClassNotFoundException is associated with the descriptor's handle.
1736      */
1737     private ObjectStreamClass readProxyDesc(boolean unshared)
1738         throws IOException
1739     {
1740         if (bin.readByte() != TC_PROXYCLASSDESC) {
1741             throw new InternalError();
1742         }
1743 
1744         ObjectStreamClass desc = new ObjectStreamClass();
1745         int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1746         passHandle = NULL_HANDLE;
1747 
1748         int numIfaces = bin.readInt();
1749         String[] ifaces = new String[numIfaces];
1750         for (int i = 0; i < numIfaces; i++) {
1751             ifaces[i] = bin.readUTF();
1752         }
1753 
1754         Class<?> cl = null;
1755         ClassNotFoundException resolveEx = null;
1756         bin.setBlockDataMode(true);
1757         try {
1758             if ((cl = resolveProxyClass(ifaces)) == null) {
1759                 resolveEx = new ClassNotFoundException("null class");
1760             } else if (!Proxy.isProxyClass(cl)) {
1761                 throw new InvalidClassException("Not a proxy");
1762             } else {
1763                 // ReflectUtil.checkProxyPackageAccess makes a test
1764                 // equivalent to isCustomSubclass so there's no need
1765                 // to condition this call to isCustomSubclass == true here.
1766                 ReflectUtil.checkProxyPackageAccess(
1767                         getClass().getClassLoader(),
1768                         cl.getInterfaces());
1769                 // Filter the interfaces
1770                 for (Class<?> clazz : cl.getInterfaces()) {
1771                     filterCheck(clazz, -1);
1772                 }
1773             }
1774         } catch (ClassNotFoundException ex) {
1775             resolveEx = ex;
1776         }
1777 
1778         // Call filterCheck on the class before reading anything else
1779         filterCheck(cl, -1);
1780 
1781         skipCustomData();
1782 
1783         try {
1784             totalObjectRefs++;
1785             depth++;
1786             desc.initProxy(cl, resolveEx, readClassDesc(false));
1787         } finally {
1788             depth--;
1789         }
1790 
1791         handles.finish(descHandle);
1792         passHandle = descHandle;
1793         return desc;
1794     }
1795 
1796     /**
1797      * Reads in and returns class descriptor for a class that is not a dynamic
1798      * proxy class.  Sets passHandle to class descriptor's assigned handle.  If
1799      * class descriptor cannot be resolved to a class in the local VM, a
1800      * ClassNotFoundException is associated with the descriptor's handle.
1801      */
1802     private ObjectStreamClass readNonProxyDesc(boolean unshared)
1803         throws IOException
1804     {
1805         if (bin.readByte() != TC_CLASSDESC) {
1806             throw new InternalError();
1807         }
1808 
1809         ObjectStreamClass desc = new ObjectStreamClass();
1810         int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1811         passHandle = NULL_HANDLE;
1812 
1813         ObjectStreamClass readDesc = null;
1814         try {
1815             readDesc = readClassDescriptor();
1816         } catch (ClassNotFoundException ex) {
1817             throw (IOException) new InvalidClassException(
1818                 "failed to read class descriptor").initCause(ex);
1819         }
1820 
1821         Class<?> cl = null;
1822         ClassNotFoundException resolveEx = null;
1823         bin.setBlockDataMode(true);
1824         final boolean checksRequired = isCustomSubclass();
1825         try {
1826             if ((cl = resolveClass(readDesc)) == null) {
1827                 resolveEx = new ClassNotFoundException("null class");
1828             } else if (checksRequired) {
1829                 ReflectUtil.checkPackageAccess(cl);
1830             }
1831         } catch (ClassNotFoundException ex) {
1832             resolveEx = ex;
1833         }
1834 
1835         // Call filterCheck on the class before reading anything else
1836         filterCheck(cl, -1);
1837 
1838         skipCustomData();
1839 
1840         try {
1841             totalObjectRefs++;
1842             depth++;
1843             desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false));
1844         } finally {
1845             depth--;
1846         }
1847 
1848         handles.finish(descHandle);
1849         passHandle = descHandle;
1850 
1851         return desc;
1852     }
1853 
1854     /**
1855      * Reads in and returns new string.  Sets passHandle to new string's
1856      * assigned handle.
1857      */
1858     private String readString(boolean unshared) throws IOException {
1859         String str;
1860         byte tc = bin.readByte();
1861         switch (tc) {
1862             case TC_STRING:
1863                 str = bin.readUTF();
1864                 break;
1865 
1866             case TC_LONGSTRING:
1867                 str = bin.readLongUTF();
1868                 break;
1869 
1870             default:
1871                 throw new StreamCorruptedException(
1872                     String.format("invalid type code: %02X", tc));
1873         }
1874         passHandle = handles.assign(unshared ? unsharedMarker : str);
1875         handles.finish(passHandle);
1876         return str;
1877     }
1878 
1879     /**
1880      * Reads in and returns array object, or null if array class is
1881      * unresolvable.  Sets passHandle to array's assigned handle.
1882      */
1883     private Object readArray(boolean unshared) throws IOException {
1884         if (bin.readByte() != TC_ARRAY) {
1885             throw new InternalError();
1886         }
1887 
1888         ObjectStreamClass desc = readClassDesc(false);
1889         int len = bin.readInt();
1890 
1891         filterCheck(desc.forClass(), len);
1892 
1893         Object array = null;
1894         Class<?> cl, ccl = null;
1895         if ((cl = desc.forClass()) != null) {
1896             ccl = cl.getComponentType();
1897             array = Array.newInstance(ccl, len);
1898         }
1899 
1900         int arrayHandle = handles.assign(unshared ? unsharedMarker : array);
1901         ClassNotFoundException resolveEx = desc.getResolveException();
1902         if (resolveEx != null) {
1903             handles.markException(arrayHandle, resolveEx);
1904         }
1905 
1906         if (ccl == null) {
1907             for (int i = 0; i < len; i++) {
1908                 readObject0(false);
1909             }
1910         } else if (ccl.isPrimitive()) {
1911             if (ccl == Integer.TYPE) {
1912                 bin.readInts((int[]) array, 0, len);
1913             } else if (ccl == Byte.TYPE) {
1914                 bin.readFully((byte[]) array, 0, len, true);
1915             } else if (ccl == Long.TYPE) {
1916                 bin.readLongs((long[]) array, 0, len);
1917             } else if (ccl == Float.TYPE) {
1918                 bin.readFloats((float[]) array, 0, len);
1919             } else if (ccl == Double.TYPE) {
1920                 bin.readDoubles((double[]) array, 0, len);
1921             } else if (ccl == Short.TYPE) {
1922                 bin.readShorts((short[]) array, 0, len);
1923             } else if (ccl == Character.TYPE) {
1924                 bin.readChars((char[]) array, 0, len);
1925             } else if (ccl == Boolean.TYPE) {
1926                 bin.readBooleans((boolean[]) array, 0, len);
1927             } else {
1928                 throw new InternalError();
1929             }
1930         } else {
1931             Object[] oa = (Object[]) array;
1932             for (int i = 0; i < len; i++) {
1933                 oa[i] = readObject0(false);
1934                 handles.markDependency(arrayHandle, passHandle);
1935             }
1936         }
1937 
1938         handles.finish(arrayHandle);
1939         passHandle = arrayHandle;
1940         return array;
1941     }
1942 
1943     /**
1944      * Reads in and returns enum constant, or null if enum type is
1945      * unresolvable.  Sets passHandle to enum constant's assigned handle.
1946      */
1947     private Enum<?> readEnum(boolean unshared) throws IOException {
1948         if (bin.readByte() != TC_ENUM) {
1949             throw new InternalError();
1950         }
1951 
1952         ObjectStreamClass desc = readClassDesc(false);
1953         if (!desc.isEnum()) {
1954             throw new InvalidClassException("non-enum class: " + desc);
1955         }
1956 
1957         int enumHandle = handles.assign(unshared ? unsharedMarker : null);
1958         ClassNotFoundException resolveEx = desc.getResolveException();
1959         if (resolveEx != null) {
1960             handles.markException(enumHandle, resolveEx);
1961         }
1962 
1963         String name = readString(false);
1964         Enum<?> result = null;
1965         Class<?> cl = desc.forClass();
1966         if (cl != null) {
1967             try {
1968                 @SuppressWarnings("unchecked")
1969                 Enum<?> en = Enum.valueOf((Class)cl, name);
1970                 result = en;
1971             } catch (IllegalArgumentException ex) {
1972                 throw (IOException) new InvalidObjectException(
1973                     "enum constant " + name + " does not exist in " +
1974                     cl).initCause(ex);
1975             }
1976             if (!unshared) {
1977                 handles.setObject(enumHandle, result);
1978             }
1979         }
1980 
1981         handles.finish(enumHandle);
1982         passHandle = enumHandle;
1983         return result;
1984     }
1985 
1986     /**
1987      * Reads and returns "ordinary" (i.e., not a String, Class,
1988      * ObjectStreamClass, array, or enum constant) object, or null if object's
1989      * class is unresolvable (in which case a ClassNotFoundException will be
1990      * associated with object's handle).  Sets passHandle to object's assigned
1991      * handle.
1992      */
1993     private Object readOrdinaryObject(boolean unshared)
1994         throws IOException
1995     {
1996         if (bin.readByte() != TC_OBJECT) {
1997             throw new InternalError();
1998         }
1999 
2000         ObjectStreamClass desc = readClassDesc(false);
2001         desc.checkDeserialize();
2002 
2003         Class<?> cl = desc.forClass();
2004         if (cl == String.class || cl == Class.class
2005                 || cl == ObjectStreamClass.class) {
2006             throw new InvalidClassException("invalid class descriptor");
2007         }
2008 
2009         Object obj;
2010         try {
2011             obj = desc.isInstantiable() ? desc.newInstance() : null;
2012         } catch (Exception ex) {
2013             throw (IOException) new InvalidClassException(
2014                 desc.forClass().getName(),
2015                 "unable to create instance").initCause(ex);
2016         }
2017 
2018         passHandle = handles.assign(unshared ? unsharedMarker : obj);
2019         ClassNotFoundException resolveEx = desc.getResolveException();
2020         if (resolveEx != null) {
2021             handles.markException(passHandle, resolveEx);
2022         }
2023 
2024         if (desc.isExternalizable()) {
2025             readExternalData((Externalizable) obj, desc);
2026         } else {
2027             readSerialData(obj, desc);
2028         }
2029 
2030         handles.finish(passHandle);
2031 
2032         if (obj != null &&
2033             handles.lookupException(passHandle) == null &&
2034             desc.hasReadResolveMethod())
2035         {
2036             Object rep = desc.invokeReadResolve(obj);
2037             if (unshared && rep.getClass().isArray()) {
2038                 rep = cloneArray(rep);
2039             }
2040             if (rep != obj) {
2041                 // Filter the replacement object
2042                 if (rep != null) {
2043                     if (rep.getClass().isArray()) {
2044                         filterCheck(rep.getClass(), Array.getLength(rep));
2045                     } else {
2046                         filterCheck(rep.getClass(), -1);
2047                     }
2048                 }
2049                 handles.setObject(passHandle, obj = rep);
2050             }
2051         }
2052 
2053         return obj;
2054     }
2055 
2056     /**
2057      * If obj is non-null, reads externalizable data by invoking readExternal()
2058      * method of obj; otherwise, attempts to skip over externalizable data.
2059      * Expects that passHandle is set to obj's handle before this method is
2060      * called.
2061      */
2062     private void readExternalData(Externalizable obj, ObjectStreamClass desc)
2063         throws IOException
2064     {
2065         SerialCallbackContext oldContext = curContext;
2066         if (oldContext != null)
2067             oldContext.check();
2068         curContext = null;
2069         try {
2070             boolean blocked = desc.hasBlockExternalData();
2071             if (blocked) {
2072                 bin.setBlockDataMode(true);
2073             }
2074             if (obj != null) {
2075                 try {
2076                     obj.readExternal(this);
2077                 } catch (ClassNotFoundException ex) {
2078                     /*
2079                      * In most cases, the handle table has already propagated
2080                      * a CNFException to passHandle at this point; this mark
2081                      * call is included to address cases where the readExternal
2082                      * method has cons'ed and thrown a new CNFException of its
2083                      * own.
2084                      */
2085                      handles.markException(passHandle, ex);
2086                 }
2087             }
2088             if (blocked) {
2089                 skipCustomData();
2090             }
2091         } finally {
2092             if (oldContext != null)
2093                 oldContext.check();
2094             curContext = oldContext;
2095         }
2096         /*
2097          * At this point, if the externalizable data was not written in
2098          * block-data form and either the externalizable class doesn't exist
2099          * locally (i.e., obj == null) or readExternal() just threw a
2100          * CNFException, then the stream is probably in an inconsistent state,
2101          * since some (or all) of the externalizable data may not have been
2102          * consumed.  Since there's no "correct" action to take in this case,
2103          * we mimic the behavior of past serialization implementations and
2104          * blindly hope that the stream is in sync; if it isn't and additional
2105          * externalizable data remains in the stream, a subsequent read will
2106          * most likely throw a StreamCorruptedException.
2107          */
2108     }
2109 
2110     /**
2111      * Reads (or attempts to skip, if obj is null or is tagged with a
2112      * ClassNotFoundException) instance data for each serializable class of
2113      * object in stream, from superclass to subclass.  Expects that passHandle
2114      * is set to obj's handle before this method is called.
2115      */
2116     private void readSerialData(Object obj, ObjectStreamClass desc)
2117         throws IOException
2118     {
2119         ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
2120         for (int i = 0; i < slots.length; i++) {
2121             ObjectStreamClass slotDesc = slots[i].desc;
2122 
2123             if (slots[i].hasData) {
2124                 if (obj == null || handles.lookupException(passHandle) != null) {
2125                     defaultReadFields(null, slotDesc); // skip field values
2126                 } else if (slotDesc.hasReadObjectMethod()) {
2127                     ThreadDeath t = null;
2128                     boolean reset = false;
2129                     SerialCallbackContext oldContext = curContext;
2130                     if (oldContext != null)
2131                         oldContext.check();
2132                     try {
2133                         curContext = new SerialCallbackContext(obj, slotDesc);
2134 
2135                         bin.setBlockDataMode(true);
2136                         slotDesc.invokeReadObject(obj, this);
2137                     } catch (ClassNotFoundException ex) {
2138                         /*
2139                          * In most cases, the handle table has already
2140                          * propagated a CNFException to passHandle at this
2141                          * point; this mark call is included to address cases
2142                          * where the custom readObject method has cons'ed and
2143                          * thrown a new CNFException of its own.
2144                          */
2145                         handles.markException(passHandle, ex);
2146                     } finally {
2147                         do {
2148                             try {
2149                                 curContext.setUsed();
2150                                 if (oldContext!= null)
2151                                     oldContext.check();
2152                                 curContext = oldContext;
2153                                 reset = true;
2154                             } catch (ThreadDeath x) {
2155                                 t = x;  // defer until reset is true
2156                             }
2157                         } while (!reset);
2158                         if (t != null)
2159                             throw t;
2160                     }
2161 
2162                     /*
2163                      * defaultDataEnd may have been set indirectly by custom
2164                      * readObject() method when calling defaultReadObject() or
2165                      * readFields(); clear it to restore normal read behavior.
2166                      */
2167                     defaultDataEnd = false;
2168                 } else {
2169                     defaultReadFields(obj, slotDesc);
2170                     }
2171 
2172                 if (slotDesc.hasWriteObjectData()) {
2173                     skipCustomData();
2174                 } else {
2175                     bin.setBlockDataMode(false);
2176                 }
2177             } else {
2178                 if (obj != null &&
2179                     slotDesc.hasReadObjectNoDataMethod() &&
2180                     handles.lookupException(passHandle) == null)
2181                 {
2182                     slotDesc.invokeReadObjectNoData(obj);
2183                 }
2184             }
2185         }
2186             }
2187 
2188     /**
2189      * Skips over all block data and objects until TC_ENDBLOCKDATA is
2190      * encountered.
2191      */
2192     private void skipCustomData() throws IOException {
2193         int oldHandle = passHandle;
2194         for (;;) {
2195             if (bin.getBlockDataMode()) {
2196                 bin.skipBlockData();
2197                 bin.setBlockDataMode(false);
2198             }
2199             switch (bin.peekByte()) {
2200                 case TC_BLOCKDATA:
2201                 case TC_BLOCKDATALONG:
2202                     bin.setBlockDataMode(true);
2203                     break;
2204 
2205                 case TC_ENDBLOCKDATA:
2206                     bin.readByte();
2207                     passHandle = oldHandle;
2208                     return;
2209 
2210                 default:
2211                     readObject0(false);
2212                     break;
2213             }
2214         }
2215     }
2216 
2217     /**
2218      * Reads in values of serializable fields declared by given class
2219      * descriptor.  If obj is non-null, sets field values in obj.  Expects that
2220      * passHandle is set to obj's handle before this method is called.
2221      */
2222     private void defaultReadFields(Object obj, ObjectStreamClass desc)
2223         throws IOException
2224     {
2225         Class<?> cl = desc.forClass();
2226         if (cl != null && obj != null && !cl.isInstance(obj)) {
2227             throw new ClassCastException();
2228         }
2229 
2230         int primDataSize = desc.getPrimDataSize();
2231         if (primVals == null || primVals.length < primDataSize) {
2232             primVals = new byte[primDataSize];
2233         }
2234             bin.readFully(primVals, 0, primDataSize, false);
2235         if (obj != null) {
2236             desc.setPrimFieldValues(obj, primVals);
2237         }
2238 
2239         int objHandle = passHandle;
2240         ObjectStreamField[] fields = desc.getFields(false);
2241         Object[] objVals = new Object[desc.getNumObjFields()];
2242         int numPrimFields = fields.length - objVals.length;
2243         for (int i = 0; i < objVals.length; i++) {
2244             ObjectStreamField f = fields[numPrimFields + i];
2245             objVals[i] = readObject0(f.isUnshared());
2246             if (f.getField() != null) {
2247                 handles.markDependency(objHandle, passHandle);
2248             }
2249         }
2250         if (obj != null) {
2251             desc.setObjFieldValues(obj, objVals);
2252         }
2253         passHandle = objHandle;
2254     }
2255 
2256     /**
2257      * Reads in and returns IOException that caused serialization to abort.
2258      * All stream state is discarded prior to reading in fatal exception.  Sets
2259      * passHandle to fatal exception's handle.
2260      */
2261     private IOException readFatalException() throws IOException {
2262         if (bin.readByte() != TC_EXCEPTION) {
2263             throw new InternalError();
2264         }
2265         clear();
2266         return (IOException) readObject0(false);
2267     }
2268 
2269     /**
2270      * If recursion depth is 0, clears internal data structures; otherwise,
2271      * throws a StreamCorruptedException.  This method is called when a
2272      * TC_RESET typecode is encountered.
2273      */
2274     private void handleReset() throws StreamCorruptedException {
2275         if (depth > 0) {
2276             throw new StreamCorruptedException(
2277                 "unexpected reset; recursion depth: " + depth);
2278         }
2279         clear();
2280     }
2281 
2282     /**
2283      * Converts specified span of bytes into float values.
2284      */
2285     // REMIND: remove once hotspot inlines Float.intBitsToFloat
2286     private static native void bytesToFloats(byte[] src, int srcpos,
2287                                              float[] dst, int dstpos,
2288                                              int nfloats);
2289 
2290     /**
2291      * Converts specified span of bytes into double values.
2292      */
2293     // REMIND: remove once hotspot inlines Double.longBitsToDouble
2294     private static native void bytesToDoubles(byte[] src, int srcpos,
2295                                               double[] dst, int dstpos,
2296                                               int ndoubles);
2297 
2298     /**
2299      * Returns the first non-null class loader (not counting class loaders of
2300      * generated reflection implementation classes) up the execution stack, or
2301      * null if only code from the null class loader is on the stack.  This
2302      * method is also called via reflection by the following RMI-IIOP class:
2303      *
2304      *     com.sun.corba.se.internal.util.JDKClassLoader
2305      *
2306      * This method should not be removed or its signature changed without
2307      * corresponding modifications to the above class.
2308      */
2309     private static ClassLoader latestUserDefinedLoader() {
2310         return sun.misc.VM.latestUserDefinedLoader();
2311     }
2312 
2313     /**
2314      * Default GetField implementation.
2315      */
2316     private class GetFieldImpl extends GetField {
2317 
2318         /** class descriptor describing serializable fields */
2319         private final ObjectStreamClass desc;
2320         /** primitive field values */
2321         private final byte[] primVals;
2322         /** object field values */
2323         private final Object[] objVals;
2324         /** object field value handles */
2325         private final int[] objHandles;
2326 
2327         /**
2328          * Creates GetFieldImpl object for reading fields defined in given
2329          * class descriptor.
2330          */
2331         GetFieldImpl(ObjectStreamClass desc) {
2332             this.desc = desc;
2333             primVals = new byte[desc.getPrimDataSize()];
2334             objVals = new Object[desc.getNumObjFields()];
2335             objHandles = new int[objVals.length];
2336         }
2337 
2338         public ObjectStreamClass getObjectStreamClass() {
2339             return desc;
2340         }
2341 
2342         public boolean defaulted(String name) throws IOException {
2343             return (getFieldOffset(name, null) < 0);
2344         }
2345 
2346         public boolean get(String name, boolean val) throws IOException {
2347             int off = getFieldOffset(name, Boolean.TYPE);
2348             return (off >= 0) ? Bits.getBoolean(primVals, off) : val;
2349         }
2350 
2351         public byte get(String name, byte val) throws IOException {
2352             int off = getFieldOffset(name, Byte.TYPE);
2353             return (off >= 0) ? primVals[off] : val;
2354         }
2355 
2356         public char get(String name, char val) throws IOException {
2357             int off = getFieldOffset(name, Character.TYPE);
2358             return (off >= 0) ? Bits.getChar(primVals, off) : val;
2359         }
2360 
2361         public short get(String name, short val) throws IOException {
2362             int off = getFieldOffset(name, Short.TYPE);
2363             return (off >= 0) ? Bits.getShort(primVals, off) : val;
2364         }
2365 
2366         public int get(String name, int val) throws IOException {
2367             int off = getFieldOffset(name, Integer.TYPE);
2368             return (off >= 0) ? Bits.getInt(primVals, off) : val;
2369         }
2370 
2371         public float get(String name, float val) throws IOException {
2372             int off = getFieldOffset(name, Float.TYPE);
2373             return (off >= 0) ? Bits.getFloat(primVals, off) : val;
2374         }
2375 
2376         public long get(String name, long val) throws IOException {
2377             int off = getFieldOffset(name, Long.TYPE);
2378             return (off >= 0) ? Bits.getLong(primVals, off) : val;
2379         }
2380 
2381         public double get(String name, double val) throws IOException {
2382             int off = getFieldOffset(name, Double.TYPE);
2383             return (off >= 0) ? Bits.getDouble(primVals, off) : val;
2384         }
2385 
2386         public Object get(String name, Object val) throws IOException {
2387             int off = getFieldOffset(name, Object.class);
2388             if (off >= 0) {
2389                 int objHandle = objHandles[off];
2390                 handles.markDependency(passHandle, objHandle);
2391                 return (handles.lookupException(objHandle) == null) ?
2392                     objVals[off] : null;
2393             } else {
2394                 return val;
2395             }
2396         }
2397 
2398         /**
2399          * Reads primitive and object field values from stream.
2400          */
2401         void readFields() throws IOException {
2402             bin.readFully(primVals, 0, primVals.length, false);
2403 
2404             int oldHandle = passHandle;
2405             ObjectStreamField[] fields = desc.getFields(false);
2406             int numPrimFields = fields.length - objVals.length;
2407             for (int i = 0; i < objVals.length; i++) {
2408                 objVals[i] =
2409                     readObject0(fields[numPrimFields + i].isUnshared());
2410                 objHandles[i] = passHandle;
2411             }
2412             passHandle = oldHandle;
2413         }
2414 
2415         /**
2416          * Returns offset of field with given name and type.  A specified type
2417          * of null matches all types, Object.class matches all non-primitive
2418          * types, and any other non-null type matches assignable types only.
2419          * If no matching field is found in the (incoming) class
2420          * descriptor but a matching field is present in the associated local
2421          * class descriptor, returns -1.  Throws IllegalArgumentException if
2422          * neither incoming nor local class descriptor contains a match.
2423          */
2424         private int getFieldOffset(String name, Class<?> type) {
2425             ObjectStreamField field = desc.getField(name, type);
2426             if (field != null) {
2427                 return field.getOffset();
2428             } else if (desc.getLocalDesc().getField(name, type) != null) {
2429                 return -1;
2430             } else {
2431                 throw new IllegalArgumentException("no such field " + name +
2432                                                    " with type " + type);
2433             }
2434         }
2435     }
2436 
2437     /**
2438      * Prioritized list of callbacks to be performed once object graph has been
2439      * completely deserialized.
2440      */
2441     private static class ValidationList {
2442 
2443         private static class Callback {
2444             final ObjectInputValidation obj;
2445             final int priority;
2446             Callback next;
2447             final AccessControlContext acc;
2448 
2449             Callback(ObjectInputValidation obj, int priority, Callback next,
2450                 AccessControlContext acc)
2451             {
2452                 this.obj = obj;
2453                 this.priority = priority;
2454                 this.next = next;
2455                 this.acc = acc;
2456             }
2457         }
2458 
2459         /** linked list of callbacks */
2460         private Callback list;
2461 
2462         /**
2463          * Creates new (empty) ValidationList.
2464          */
2465         ValidationList() {
2466         }
2467 
2468         /**
2469          * Registers callback.  Throws InvalidObjectException if callback
2470          * object is null.
2471          */
2472         void register(ObjectInputValidation obj, int priority)
2473             throws InvalidObjectException
2474         {
2475             if (obj == null) {
2476                 throw new InvalidObjectException("null callback");
2477             }
2478 
2479             Callback prev = null, cur = list;
2480             while (cur != null && priority < cur.priority) {
2481                 prev = cur;
2482                 cur = cur.next;
2483             }
2484             AccessControlContext acc = AccessController.getContext();
2485             if (prev != null) {
2486                 prev.next = new Callback(obj, priority, cur, acc);
2487             } else {
2488                 list = new Callback(obj, priority, list, acc);
2489             }
2490         }
2491 
2492         /**
2493          * Invokes all registered callbacks and clears the callback list.
2494          * Callbacks with higher priorities are called first; those with equal
2495          * priorities may be called in any order.  If any of the callbacks
2496          * throws an InvalidObjectException, the callback process is terminated
2497          * and the exception propagated upwards.
2498          */
2499         void doCallbacks() throws InvalidObjectException {
2500             try {
2501                 while (list != null) {
2502                     AccessController.doPrivileged(
2503                         new PrivilegedExceptionAction<Void>()
2504                     {
2505                         public Void run() throws InvalidObjectException {
2506                             list.obj.validateObject();
2507                             return null;
2508                         }
2509                     }, list.acc);
2510                     list = list.next;
2511                 }
2512             } catch (PrivilegedActionException ex) {
2513                 list = null;
2514                 throw (InvalidObjectException) ex.getException();
2515             }
2516         }
2517 
2518         /**
2519          * Resets the callback list to its initial (empty) state.
2520          */
2521         public void clear() {
2522             list = null;
2523         }
2524     }
2525 
2526     /**
2527      * Hold a snapshot of values to be passed to an ObjectInputFilter.
2528      */
2529     static class FilterValues implements ObjectInputFilter.FilterInfo {
2530         final Class<?> clazz;
2531         final long arrayLength;
2532         final long totalObjectRefs;
2533         final long depth;
2534         final long streamBytes;
2535 
2536         public FilterValues(Class<?> clazz, long arrayLength, long totalObjectRefs,
2537                             long depth, long streamBytes) {
2538             this.clazz = clazz;
2539             this.arrayLength = arrayLength;
2540             this.totalObjectRefs = totalObjectRefs;
2541             this.depth = depth;
2542             this.streamBytes = streamBytes;
2543         }
2544 
2545         @Override
2546         public Class<?> serialClass() {
2547             return clazz;
2548         }
2549 
2550         @Override
2551         public long arrayLength() {
2552             return arrayLength;
2553         }
2554 
2555         @Override
2556         public long references() {
2557             return totalObjectRefs;
2558         }
2559 
2560         @Override
2561         public long depth() {
2562             return depth;
2563         }
2564 
2565         @Override
2566         public long streamBytes() {
2567             return streamBytes;
2568         }
2569     }
2570 
2571     /**
2572      * Input stream supporting single-byte peek operations.
2573      */
2574     private static class PeekInputStream extends InputStream {
2575 
2576         /** underlying stream */
2577         private final InputStream in;
2578         /** peeked byte */
2579         private int peekb = -1;
2580         /** total bytes read from the stream */
2581         private long totalBytesRead = 0;
2582 
2583         /**
2584          * Creates new PeekInputStream on top of given underlying stream.
2585          */
2586         PeekInputStream(InputStream in) {
2587             this.in = in;
2588         }
2589 
2590         /**
2591          * Peeks at next byte value in stream.  Similar to read(), except
2592          * that it does not consume the read value.
2593          */
2594         int peek() throws IOException {
2595             if (peekb >= 0) {
2596                 return peekb;
2597             }
2598             peekb = in.read();
2599             totalBytesRead += peekb >= 0 ? 1 : 0;
2600             return peekb;
2601         }
2602 
2603         public int read() throws IOException {
2604             if (peekb >= 0) {
2605                 int v = peekb;
2606                 peekb = -1;
2607                 return v;
2608             } else {
2609                 int nbytes = in.read();
2610                 totalBytesRead += nbytes >= 0 ? 1 : 0;
2611                 return nbytes;
2612             }
2613         }
2614 
2615         public int read(byte[] b, int off, int len) throws IOException {
2616             int nbytes;
2617             if (len == 0) {
2618                 return 0;
2619             } else if (peekb < 0) {
2620                 nbytes = in.read(b, off, len);
2621                 totalBytesRead += nbytes >= 0 ? nbytes : 0;
2622                 return nbytes;
2623             } else {
2624                 b[off++] = (byte) peekb;
2625                 len--;
2626                 peekb = -1;
2627                 nbytes = in.read(b, off, len);
2628                 totalBytesRead += nbytes >= 0 ? nbytes : 0;
2629                 return (nbytes >= 0) ? (nbytes + 1) : 1;
2630             }
2631         }
2632 
2633         void readFully(byte[] b, int off, int len) throws IOException {
2634             int n = 0;
2635             while (n < len) {
2636                 int count = read(b, off + n, len - n);
2637                 if (count < 0) {
2638                     throw new EOFException();
2639                 }
2640                 n += count;
2641             }
2642         }
2643 
2644         public long skip(long n) throws IOException {
2645             if (n <= 0) {
2646                 return 0;
2647             }
2648             int skipped = 0;
2649             if (peekb >= 0) {
2650                 peekb = -1;
2651                 skipped++;
2652                 n--;
2653             }
2654             n = skipped + in.skip(n);
2655             totalBytesRead += n;
2656             return n;
2657         }
2658 
2659         public int available() throws IOException {
2660             return in.available() + ((peekb >= 0) ? 1 : 0);
2661         }
2662 
2663         public void close() throws IOException {
2664             in.close();
2665         }
2666 
2667         public long getBytesRead() {
2668             return totalBytesRead;
2669         }
2670     }
2671 
2672     /**
2673      * Input stream with two modes: in default mode, inputs data written in the
2674      * same format as DataOutputStream; in "block data" mode, inputs data
2675      * bracketed by block data markers (see object serialization specification
2676      * for details).  Buffering depends on block data mode: when in default
2677      * mode, no data is buffered in advance; when in block data mode, all data
2678      * for the current data block is read in at once (and buffered).
2679      */
2680     private class BlockDataInputStream
2681         extends InputStream implements DataInput
2682     {
2683         /** maximum data block length */
2684         private static final int MAX_BLOCK_SIZE = 1024;
2685         /** maximum data block header length */
2686         private static final int MAX_HEADER_SIZE = 5;
2687         /** (tunable) length of char buffer (for reading strings) */
2688         private static final int CHAR_BUF_SIZE = 256;
2689         /** readBlockHeader() return value indicating header read may block */
2690         private static final int HEADER_BLOCKED = -2;
2691 
2692         /** buffer for reading general/block data */
2693         private final byte[] buf = new byte[MAX_BLOCK_SIZE];
2694         /** buffer for reading block data headers */
2695         private final byte[] hbuf = new byte[MAX_HEADER_SIZE];
2696         /** char buffer for fast string reads */
2697         private final char[] cbuf = new char[CHAR_BUF_SIZE];
2698 
2699         /** block data mode */
2700         private boolean blkmode = false;
2701 
2702         // block data state fields; values meaningful only when blkmode true
2703         /** current offset into buf */
2704         private int pos = 0;
2705         /** end offset of valid data in buf, or -1 if no more block data */
2706         private int end = -1;
2707         /** number of bytes in current block yet to be read from stream */
2708         private int unread = 0;
2709 
2710         /** underlying stream (wrapped in peekable filter stream) */
2711         private final PeekInputStream in;
2712         /** loopback stream (for data reads that span data blocks) */
2713         private final DataInputStream din;
2714 
2715         /**
2716          * Creates new BlockDataInputStream on top of given underlying stream.
2717          * Block data mode is turned off by default.
2718          */
2719         BlockDataInputStream(InputStream in) {
2720             this.in = new PeekInputStream(in);
2721             din = new DataInputStream(this);
2722         }
2723 
2724         /**
2725          * Sets block data mode to the given mode (true == on, false == off)
2726          * and returns the previous mode value.  If the new mode is the same as
2727          * the old mode, no action is taken.  Throws IllegalStateException if
2728          * block data mode is being switched from on to off while unconsumed
2729          * block data is still present in the stream.
2730          */
2731         boolean setBlockDataMode(boolean newmode) throws IOException {
2732             if (blkmode == newmode) {
2733                 return blkmode;
2734             }
2735             if (newmode) {
2736                 pos = 0;
2737                 end = 0;
2738                 unread = 0;
2739             } else if (pos < end) {
2740                 throw new IllegalStateException("unread block data");
2741             }
2742             blkmode = newmode;
2743             return !blkmode;
2744         }
2745 
2746         /**
2747          * Returns true if the stream is currently in block data mode, false
2748          * otherwise.
2749          */
2750         boolean getBlockDataMode() {
2751             return blkmode;
2752         }
2753 
2754         /**
2755          * If in block data mode, skips to the end of the current group of data
2756          * blocks (but does not unset block data mode).  If not in block data
2757          * mode, throws an IllegalStateException.
2758          */
2759         void skipBlockData() throws IOException {
2760             if (!blkmode) {
2761                 throw new IllegalStateException("not in block data mode");
2762             }
2763             while (end >= 0) {
2764                 refill();
2765             }
2766         }
2767 
2768         /**
2769          * Attempts to read in the next block data header (if any).  If
2770          * canBlock is false and a full header cannot be read without possibly
2771          * blocking, returns HEADER_BLOCKED, else if the next element in the
2772          * stream is a block data header, returns the block data length
2773          * specified by the header, else returns -1.
2774          */
2775         private int readBlockHeader(boolean canBlock) throws IOException {
2776             if (defaultDataEnd) {
2777                 /*
2778                  * Fix for 4360508: stream is currently at the end of a field
2779                  * value block written via default serialization; since there
2780                  * is no terminating TC_ENDBLOCKDATA tag, simulate
2781                  * end-of-custom-data behavior explicitly.
2782                  */
2783                 return -1;
2784             }
2785             try {
2786                 for (;;) {
2787                     int avail = canBlock ? Integer.MAX_VALUE : in.available();
2788                     if (avail == 0) {
2789                         return HEADER_BLOCKED;
2790                     }
2791 
2792                     int tc = in.peek();
2793                     switch (tc) {
2794                         case TC_BLOCKDATA:
2795                             if (avail < 2) {
2796                                 return HEADER_BLOCKED;
2797                             }
2798                             in.readFully(hbuf, 0, 2);
2799                             return hbuf[1] & 0xFF;
2800 
2801                         case TC_BLOCKDATALONG:
2802                             if (avail < 5) {
2803                                 return HEADER_BLOCKED;
2804                             }
2805                             in.readFully(hbuf, 0, 5);
2806                             int len = Bits.getInt(hbuf, 1);
2807                             if (len < 0) {
2808                                 throw new StreamCorruptedException(
2809                                     "illegal block data header length: " +
2810                                     len);
2811                             }
2812                             return len;
2813 
2814                         /*
2815                          * TC_RESETs may occur in between data blocks.
2816                          * Unfortunately, this case must be parsed at a lower
2817                          * level than other typecodes, since primitive data
2818                          * reads may span data blocks separated by a TC_RESET.
2819                          */
2820                         case TC_RESET:
2821                             in.read();
2822                             handleReset();
2823                             break;
2824 
2825                         default:
2826                             if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) {
2827                                 throw new StreamCorruptedException(
2828                                     String.format("invalid type code: %02X",
2829                                     tc));
2830                             }
2831                             return -1;
2832                     }
2833                 }
2834             } catch (EOFException ex) {
2835                 throw new StreamCorruptedException(
2836                     "unexpected EOF while reading block data header");
2837             }
2838         }
2839 
2840         /**
2841          * Refills internal buffer buf with block data.  Any data in buf at the
2842          * time of the call is considered consumed.  Sets the pos, end, and
2843          * unread fields to reflect the new amount of available block data; if
2844          * the next element in the stream is not a data block, sets pos and
2845          * unread to 0 and end to -1.
2846          */
2847         private void refill() throws IOException {
2848             try {
2849                 do {
2850                     pos = 0;
2851                     if (unread > 0) {
2852                         int n =
2853                             in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE));
2854                         if (n >= 0) {
2855                             end = n;
2856                             unread -= n;
2857                         } else {
2858                             throw new StreamCorruptedException(
2859                                 "unexpected EOF in middle of data block");
2860                         }
2861                     } else {
2862                         int n = readBlockHeader(true);
2863                         if (n >= 0) {
2864                             end = 0;
2865                             unread = n;
2866                         } else {
2867                             end = -1;
2868                             unread = 0;
2869                         }
2870                     }
2871                 } while (pos == end);
2872             } catch (IOException ex) {
2873                 pos = 0;
2874                 end = -1;
2875                 unread = 0;
2876                 throw ex;
2877             }
2878         }
2879 
2880         /**
2881          * If in block data mode, returns the number of unconsumed bytes
2882          * remaining in the current data block.  If not in block data mode,
2883          * throws an IllegalStateException.
2884          */
2885         int currentBlockRemaining() {
2886             if (blkmode) {
2887                 return (end >= 0) ? (end - pos) + unread : 0;
2888             } else {
2889                 throw new IllegalStateException();
2890             }
2891         }
2892 
2893         /**
2894          * Peeks at (but does not consume) and returns the next byte value in
2895          * the stream, or -1 if the end of the stream/block data (if in block
2896          * data mode) has been reached.
2897          */
2898         int peek() throws IOException {
2899             if (blkmode) {
2900                 if (pos == end) {
2901                     refill();
2902                 }
2903                 return (end >= 0) ? (buf[pos] & 0xFF) : -1;
2904             } else {
2905                 return in.peek();
2906             }
2907         }
2908 
2909         /**
2910          * Peeks at (but does not consume) and returns the next byte value in
2911          * the stream, or throws EOFException if end of stream/block data has
2912          * been reached.
2913          */
2914         byte peekByte() throws IOException {
2915             int val = peek();
2916             if (val < 0) {
2917                 throw new EOFException();
2918             }
2919             return (byte) val;
2920         }
2921 
2922 
2923         /* ----------------- generic input stream methods ------------------ */
2924         /*
2925          * The following methods are equivalent to their counterparts in
2926          * InputStream, except that they interpret data block boundaries and
2927          * read the requested data from within data blocks when in block data
2928          * mode.
2929          */
2930 
2931         public int read() throws IOException {
2932             if (blkmode) {
2933                 if (pos == end) {
2934                     refill();
2935                 }
2936                 return (end >= 0) ? (buf[pos++] & 0xFF) : -1;
2937             } else {
2938                 return in.read();
2939             }
2940         }
2941 
2942         public int read(byte[] b, int off, int len) throws IOException {
2943             return read(b, off, len, false);
2944         }
2945 
2946         public long skip(long len) throws IOException {
2947             long remain = len;
2948             while (remain > 0) {
2949                 if (blkmode) {
2950                     if (pos == end) {
2951                         refill();
2952                     }
2953                     if (end < 0) {
2954                         break;
2955                     }
2956                     int nread = (int) Math.min(remain, end - pos);
2957                     remain -= nread;
2958                     pos += nread;
2959                 } else {
2960                     int nread = (int) Math.min(remain, MAX_BLOCK_SIZE);
2961                     if ((nread = in.read(buf, 0, nread)) < 0) {
2962                         break;
2963                     }
2964                     remain -= nread;
2965                 }
2966             }
2967             return len - remain;
2968         }
2969 
2970         public int available() throws IOException {
2971             if (blkmode) {
2972                 if ((pos == end) && (unread == 0)) {
2973                     int n;
2974                     while ((n = readBlockHeader(false)) == 0) ;
2975                     switch (n) {
2976                         case HEADER_BLOCKED:
2977                             break;
2978 
2979                         case -1:
2980                             pos = 0;
2981                             end = -1;
2982                             break;
2983 
2984                         default:
2985                             pos = 0;
2986                             end = 0;
2987                             unread = n;
2988                             break;
2989                     }
2990                 }
2991                 // avoid unnecessary call to in.available() if possible
2992                 int unreadAvail = (unread > 0) ?
2993                     Math.min(in.available(), unread) : 0;
2994                 return (end >= 0) ? (end - pos) + unreadAvail : 0;
2995             } else {
2996                 return in.available();
2997             }
2998         }
2999 
3000         public void close() throws IOException {
3001             if (blkmode) {
3002                 pos = 0;
3003                 end = -1;
3004                 unread = 0;
3005             }
3006             in.close();
3007         }
3008 
3009         /**
3010          * Attempts to read len bytes into byte array b at offset off.  Returns
3011          * the number of bytes read, or -1 if the end of stream/block data has
3012          * been reached.  If copy is true, reads values into an intermediate
3013          * buffer before copying them to b (to avoid exposing a reference to
3014          * b).
3015          */
3016         int read(byte[] b, int off, int len, boolean copy) throws IOException {
3017             if (len == 0) {
3018                 return 0;
3019             } else if (blkmode) {
3020                 if (pos == end) {
3021                     refill();
3022                 }
3023                 if (end < 0) {
3024                     return -1;
3025                 }
3026                 int nread = Math.min(len, end - pos);
3027                 System.arraycopy(buf, pos, b, off, nread);
3028                 pos += nread;
3029                 return nread;
3030             } else if (copy) {
3031                 int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE));
3032                 if (nread > 0) {
3033                     System.arraycopy(buf, 0, b, off, nread);
3034                 }
3035                 return nread;
3036             } else {
3037                 return in.read(b, off, len);
3038             }
3039         }
3040 
3041         /* ----------------- primitive data input methods ------------------ */
3042         /*
3043          * The following methods are equivalent to their counterparts in
3044          * DataInputStream, except that they interpret data block boundaries
3045          * and read the requested data from within data blocks when in block
3046          * data mode.
3047          */
3048 
3049         public void readFully(byte[] b) throws IOException {
3050             readFully(b, 0, b.length, false);
3051         }
3052 
3053         public void readFully(byte[] b, int off, int len) throws IOException {
3054             readFully(b, off, len, false);
3055         }
3056 
3057         public void readFully(byte[] b, int off, int len, boolean copy)
3058             throws IOException
3059         {
3060             while (len > 0) {
3061                 int n = read(b, off, len, copy);
3062                 if (n < 0) {
3063                     throw new EOFException();
3064                 }
3065                 off += n;
3066                 len -= n;
3067             }
3068         }
3069 
3070         public int skipBytes(int n) throws IOException {
3071             return din.skipBytes(n);
3072         }
3073 
3074         public boolean readBoolean() throws IOException {
3075             int v = read();
3076             if (v < 0) {
3077                 throw new EOFException();
3078             }
3079             return (v != 0);
3080         }
3081 
3082         public byte readByte() throws IOException {
3083             int v = read();
3084             if (v < 0) {
3085                 throw new EOFException();
3086             }
3087             return (byte) v;
3088         }
3089 
3090         public int readUnsignedByte() throws IOException {
3091             int v = read();
3092             if (v < 0) {
3093                 throw new EOFException();
3094             }
3095             return v;
3096         }
3097 
3098         public char readChar() throws IOException {
3099             if (!blkmode) {
3100                 pos = 0;
3101                 in.readFully(buf, 0, 2);
3102             } else if (end - pos < 2) {
3103                 return din.readChar();
3104             }
3105             char v = Bits.getChar(buf, pos);
3106             pos += 2;
3107             return v;
3108         }
3109 
3110         public short readShort() throws IOException {
3111             if (!blkmode) {
3112                 pos = 0;
3113                 in.readFully(buf, 0, 2);
3114             } else if (end - pos < 2) {
3115                 return din.readShort();
3116             }
3117             short v = Bits.getShort(buf, pos);
3118             pos += 2;
3119             return v;
3120         }
3121 
3122         public int readUnsignedShort() throws IOException {
3123             if (!blkmode) {
3124                 pos = 0;
3125                 in.readFully(buf, 0, 2);
3126             } else if (end - pos < 2) {
3127                 return din.readUnsignedShort();
3128             }
3129             int v = Bits.getShort(buf, pos) & 0xFFFF;
3130             pos += 2;
3131             return v;
3132         }
3133 
3134         public int readInt() throws IOException {
3135             if (!blkmode) {
3136                 pos = 0;
3137                 in.readFully(buf, 0, 4);
3138             } else if (end - pos < 4) {
3139                 return din.readInt();
3140             }
3141             int v = Bits.getInt(buf, pos);
3142             pos += 4;
3143             return v;
3144         }
3145 
3146         public float readFloat() throws IOException {
3147             if (!blkmode) {
3148                 pos = 0;
3149                 in.readFully(buf, 0, 4);
3150             } else if (end - pos < 4) {
3151                 return din.readFloat();
3152             }
3153             float v = Bits.getFloat(buf, pos);
3154             pos += 4;
3155             return v;
3156         }
3157 
3158         public long readLong() throws IOException {
3159             if (!blkmode) {
3160                 pos = 0;
3161                 in.readFully(buf, 0, 8);
3162             } else if (end - pos < 8) {
3163                 return din.readLong();
3164             }
3165             long v = Bits.getLong(buf, pos);
3166             pos += 8;
3167             return v;
3168         }
3169 
3170         public double readDouble() throws IOException {
3171             if (!blkmode) {
3172                 pos = 0;
3173                 in.readFully(buf, 0, 8);
3174             } else if (end - pos < 8) {
3175                 return din.readDouble();
3176             }
3177             double v = Bits.getDouble(buf, pos);
3178             pos += 8;
3179             return v;
3180         }
3181 
3182         public String readUTF() throws IOException {
3183             return readUTFBody(readUnsignedShort());
3184         }
3185 
3186         @SuppressWarnings("deprecation")
3187         public String readLine() throws IOException {
3188             return din.readLine();      // deprecated, not worth optimizing
3189         }
3190 
3191         /* -------------- primitive data array input methods --------------- */
3192         /*
3193          * The following methods read in spans of primitive data values.
3194          * Though equivalent to calling the corresponding primitive read
3195          * methods repeatedly, these methods are optimized for reading groups
3196          * of primitive data values more efficiently.
3197          */
3198 
3199         void readBooleans(boolean[] v, int off, int len) throws IOException {
3200             int stop, endoff = off + len;
3201             while (off < endoff) {
3202                 if (!blkmode) {
3203                     int span = Math.min(endoff - off, MAX_BLOCK_SIZE);
3204                     in.readFully(buf, 0, span);
3205                     stop = off + span;
3206                     pos = 0;
3207                 } else if (end - pos < 1) {
3208                     v[off++] = din.readBoolean();
3209                     continue;
3210                 } else {
3211                     stop = Math.min(endoff, off + end - pos);
3212                 }
3213 
3214                 while (off < stop) {
3215                     v[off++] = Bits.getBoolean(buf, pos++);
3216                 }
3217             }
3218         }
3219 
3220         void readChars(char[] v, int off, int len) throws IOException {
3221             int stop, endoff = off + len;
3222             while (off < endoff) {
3223                 if (!blkmode) {
3224                     int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
3225                     in.readFully(buf, 0, span << 1);
3226                     stop = off + span;
3227                     pos = 0;
3228                 } else if (end - pos < 2) {
3229                     v[off++] = din.readChar();
3230                     continue;
3231                 } else {
3232                     stop = Math.min(endoff, off + ((end - pos) >> 1));
3233                 }
3234 
3235                 while (off < stop) {
3236                     v[off++] = Bits.getChar(buf, pos);
3237                     pos += 2;
3238                 }
3239             }
3240         }
3241 
3242         void readShorts(short[] v, int off, int len) throws IOException {
3243             int stop, endoff = off + len;
3244             while (off < endoff) {
3245                 if (!blkmode) {
3246                     int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1);
3247                     in.readFully(buf, 0, span << 1);
3248                     stop = off + span;
3249                     pos = 0;
3250                 } else if (end - pos < 2) {
3251                     v[off++] = din.readShort();
3252                     continue;
3253                 } else {
3254                     stop = Math.min(endoff, off + ((end - pos) >> 1));
3255                 }
3256 
3257                 while (off < stop) {
3258                     v[off++] = Bits.getShort(buf, pos);
3259                     pos += 2;
3260                 }
3261             }
3262         }
3263 
3264         void readInts(int[] v, int off, int len) throws IOException {
3265             int stop, endoff = off + len;
3266             while (off < endoff) {
3267                 if (!blkmode) {
3268                     int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
3269                     in.readFully(buf, 0, span << 2);
3270                     stop = off + span;
3271                     pos = 0;
3272                 } else if (end - pos < 4) {
3273                     v[off++] = din.readInt();
3274                     continue;
3275                 } else {
3276                     stop = Math.min(endoff, off + ((end - pos) >> 2));
3277                 }
3278 
3279                 while (off < stop) {
3280                     v[off++] = Bits.getInt(buf, pos);
3281                     pos += 4;
3282                 }
3283             }
3284         }
3285 
3286         void readFloats(float[] v, int off, int len) throws IOException {
3287             int span, endoff = off + len;
3288             while (off < endoff) {
3289                 if (!blkmode) {
3290                     span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2);
3291                     in.readFully(buf, 0, span << 2);
3292                     pos = 0;
3293                 } else if (end - pos < 4) {
3294                     v[off++] = din.readFloat();
3295                     continue;
3296                 } else {
3297                     span = Math.min(endoff - off, ((end - pos) >> 2));
3298                 }
3299 
3300                 bytesToFloats(buf, pos, v, off, span);
3301                 off += span;
3302                 pos += span << 2;
3303             }
3304         }
3305 
3306         void readLongs(long[] v, int off, int len) throws IOException {
3307             int stop, endoff = off + len;
3308             while (off < endoff) {
3309                 if (!blkmode) {
3310                     int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
3311                     in.readFully(buf, 0, span << 3);
3312                     stop = off + span;
3313                     pos = 0;
3314                 } else if (end - pos < 8) {
3315                     v[off++] = din.readLong();
3316                     continue;
3317                 } else {
3318                     stop = Math.min(endoff, off + ((end - pos) >> 3));
3319                 }
3320 
3321                 while (off < stop) {
3322                     v[off++] = Bits.getLong(buf, pos);
3323                     pos += 8;
3324                 }
3325             }
3326         }
3327 
3328         void readDoubles(double[] v, int off, int len) throws IOException {
3329             int span, endoff = off + len;
3330             while (off < endoff) {
3331                 if (!blkmode) {
3332                     span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3);
3333                     in.readFully(buf, 0, span << 3);
3334                     pos = 0;
3335                 } else if (end - pos < 8) {
3336                     v[off++] = din.readDouble();
3337                     continue;
3338                 } else {
3339                     span = Math.min(endoff - off, ((end - pos) >> 3));
3340                 }
3341 
3342                 bytesToDoubles(buf, pos, v, off, span);
3343                 off += span;
3344                 pos += span << 3;
3345             }
3346         }
3347 
3348         /**
3349          * Reads in string written in "long" UTF format.  "Long" UTF format is
3350          * identical to standard UTF, except that it uses an 8 byte header
3351          * (instead of the standard 2 bytes) to convey the UTF encoding length.
3352          */
3353         String readLongUTF() throws IOException {
3354             return readUTFBody(readLong());
3355         }
3356 
3357         /**
3358          * Reads in the "body" (i.e., the UTF representation minus the 2-byte
3359          * or 8-byte length header) of a UTF encoding, which occupies the next
3360          * utflen bytes.
3361          */
3362         private String readUTFBody(long utflen) throws IOException {
3363             StringBuilder sbuf = new StringBuilder();
3364             if (!blkmode) {
3365                 end = pos = 0;
3366             }
3367 
3368             while (utflen > 0) {
3369                 int avail = end - pos;
3370                 if (avail >= 3 || (long) avail == utflen) {
3371                     utflen -= readUTFSpan(sbuf, utflen);
3372                 } else {
3373                     if (blkmode) {
3374                         // near block boundary, read one byte at a time
3375                         utflen -= readUTFChar(sbuf, utflen);
3376                     } else {
3377                         // shift and refill buffer manually
3378                         if (avail > 0) {
3379                             System.arraycopy(buf, pos, buf, 0, avail);
3380                         }
3381                         pos = 0;
3382                         end = (int) Math.min(MAX_BLOCK_SIZE, utflen);
3383                         in.readFully(buf, avail, end - avail);
3384                     }
3385                 }
3386             }
3387 
3388             return sbuf.toString();
3389         }
3390 
3391         /**
3392          * Reads span of UTF-encoded characters out of internal buffer
3393          * (starting at offset pos and ending at or before offset end),
3394          * consuming no more than utflen bytes.  Appends read characters to
3395          * sbuf.  Returns the number of bytes consumed.
3396          */
3397         private long readUTFSpan(StringBuilder sbuf, long utflen)
3398             throws IOException
3399         {
3400             int cpos = 0;
3401             int start = pos;
3402             int avail = Math.min(end - pos, CHAR_BUF_SIZE);
3403             // stop short of last char unless all of utf bytes in buffer
3404             int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen);
3405             boolean outOfBounds = false;
3406 
3407             try {
3408                 while (pos < stop) {
3409                     int b1, b2, b3;
3410                     b1 = buf[pos++] & 0xFF;
3411                     switch (b1 >> 4) {
3412                         case 0:
3413                         case 1:
3414                         case 2:
3415                         case 3:
3416                         case 4:
3417                         case 5:
3418                         case 6:
3419                         case 7:   // 1 byte format: 0xxxxxxx
3420                             cbuf[cpos++] = (char) b1;
3421                             break;
3422 
3423                         case 12:
3424                         case 13:  // 2 byte format: 110xxxxx 10xxxxxx
3425                             b2 = buf[pos++];
3426                             if ((b2 & 0xC0) != 0x80) {
3427                                 throw new UTFDataFormatException();
3428                             }
3429                             cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) |
3430                                                    ((b2 & 0x3F) << 0));
3431                             break;
3432 
3433                         case 14:  // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
3434                             b3 = buf[pos + 1];
3435                             b2 = buf[pos + 0];
3436                             pos += 2;
3437                             if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
3438                                 throw new UTFDataFormatException();
3439                             }
3440                             cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) |
3441                                                    ((b2 & 0x3F) << 6) |
3442                                                    ((b3 & 0x3F) << 0));
3443                             break;
3444 
3445                         default:  // 10xx xxxx, 1111 xxxx
3446                             throw new UTFDataFormatException();
3447                     }
3448                 }
3449             } catch (ArrayIndexOutOfBoundsException ex) {
3450                 outOfBounds = true;
3451             } finally {
3452                 if (outOfBounds || (pos - start) > utflen) {
3453                     /*
3454                      * Fix for 4450867: if a malformed utf char causes the
3455                      * conversion loop to scan past the expected end of the utf
3456                      * string, only consume the expected number of utf bytes.
3457                      */
3458                     pos = start + (int) utflen;
3459                     throw new UTFDataFormatException();
3460                 }
3461             }
3462 
3463             sbuf.append(cbuf, 0, cpos);
3464             return pos - start;
3465         }
3466 
3467         /**
3468          * Reads in single UTF-encoded character one byte at a time, appends
3469          * the character to sbuf, and returns the number of bytes consumed.
3470          * This method is used when reading in UTF strings written in block
3471          * data mode to handle UTF-encoded characters which (potentially)
3472          * straddle block-data boundaries.
3473          */
3474         private int readUTFChar(StringBuilder sbuf, long utflen)
3475             throws IOException
3476         {
3477             int b1, b2, b3;
3478             b1 = readByte() & 0xFF;
3479             switch (b1 >> 4) {
3480                 case 0:
3481                 case 1:
3482                 case 2:
3483                 case 3:
3484                 case 4:
3485                 case 5:
3486                 case 6:
3487                 case 7:     // 1 byte format: 0xxxxxxx
3488                     sbuf.append((char) b1);
3489                     return 1;
3490 
3491                 case 12:
3492                 case 13:    // 2 byte format: 110xxxxx 10xxxxxx
3493                     if (utflen < 2) {
3494                         throw new UTFDataFormatException();
3495                     }
3496                     b2 = readByte();
3497                     if ((b2 & 0xC0) != 0x80) {
3498                         throw new UTFDataFormatException();
3499                     }
3500                     sbuf.append((char) (((b1 & 0x1F) << 6) |
3501                                         ((b2 & 0x3F) << 0)));
3502                     return 2;
3503 
3504                 case 14:    // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx
3505                     if (utflen < 3) {
3506                         if (utflen == 2) {
3507                             readByte();         // consume remaining byte
3508                         }
3509                         throw new UTFDataFormatException();
3510                     }
3511                     b2 = readByte();
3512                     b3 = readByte();
3513                     if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) {
3514                         throw new UTFDataFormatException();
3515                     }
3516                     sbuf.append((char) (((b1 & 0x0F) << 12) |
3517                                         ((b2 & 0x3F) << 6) |
3518                                         ((b3 & 0x3F) << 0)));
3519                     return 3;
3520 
3521                 default:   // 10xx xxxx, 1111 xxxx
3522                     throw new UTFDataFormatException();
3523             }
3524         }
3525 
3526         /**
3527          * Returns the number of bytes read from the input stream.
3528          * @return the number of bytes read from the input stream
3529          */
3530         long getBytesRead() {
3531             return in.getBytesRead();
3532         }
3533     }
3534 
3535     /**
3536      * Unsynchronized table which tracks wire handle to object mappings, as
3537      * well as ClassNotFoundExceptions associated with deserialized objects.
3538      * This class implements an exception-propagation algorithm for
3539      * determining which objects should have ClassNotFoundExceptions associated
3540      * with them, taking into account cycles and discontinuities (e.g., skipped
3541      * fields) in the object graph.
3542      *
3543      * <p>General use of the table is as follows: during deserialization, a
3544      * given object is first assigned a handle by calling the assign method.
3545      * This method leaves the assigned handle in an "open" state, wherein
3546      * dependencies on the exception status of other handles can be registered
3547      * by calling the markDependency method, or an exception can be directly
3548      * associated with the handle by calling markException.  When a handle is
3549      * tagged with an exception, the HandleTable assumes responsibility for
3550      * propagating the exception to any other objects which depend
3551      * (transitively) on the exception-tagged object.
3552      *
3553      * <p>Once all exception information/dependencies for the handle have been
3554      * registered, the handle should be "closed" by calling the finish method
3555      * on it.  The act of finishing a handle allows the exception propagation
3556      * algorithm to aggressively prune dependency links, lessening the
3557      * performance/memory impact of exception tracking.
3558      *
3559      * <p>Note that the exception propagation algorithm used depends on handles
3560      * being assigned/finished in LIFO order; however, for simplicity as well
3561      * as memory conservation, it does not enforce this constraint.
3562      */
3563     // REMIND: add full description of exception propagation algorithm?
3564     private static class HandleTable {
3565 
3566         /* status codes indicating whether object has associated exception */
3567         private static final byte STATUS_OK = 1;
3568         private static final byte STATUS_UNKNOWN = 2;
3569         private static final byte STATUS_EXCEPTION = 3;
3570 
3571         /** array mapping handle -> object status */
3572         byte[] status;
3573         /** array mapping handle -> object/exception (depending on status) */
3574         Object[] entries;
3575         /** array mapping handle -> list of dependent handles (if any) */
3576         HandleList[] deps;
3577         /** lowest unresolved dependency */
3578         int lowDep = -1;
3579         /** number of handles in table */
3580         int size = 0;
3581 
3582         /**
3583          * Creates handle table with the given initial capacity.
3584          */
3585         HandleTable(int initialCapacity) {
3586             status = new byte[initialCapacity];
3587             entries = new Object[initialCapacity];
3588             deps = new HandleList[initialCapacity];
3589         }
3590 
3591         /**
3592          * Assigns next available handle to given object, and returns assigned
3593          * handle.  Once object has been completely deserialized (and all
3594          * dependencies on other objects identified), the handle should be
3595          * "closed" by passing it to finish().
3596          */
3597         int assign(Object obj) {
3598             if (size >= entries.length) {
3599                 grow();
3600             }
3601             status[size] = STATUS_UNKNOWN;
3602             entries[size] = obj;
3603             return size++;
3604         }
3605 
3606         /**
3607          * Registers a dependency (in exception status) of one handle on
3608          * another.  The dependent handle must be "open" (i.e., assigned, but
3609          * not finished yet).  No action is taken if either dependent or target
3610          * handle is NULL_HANDLE.
3611          */
3612         void markDependency(int dependent, int target) {
3613             if (dependent == NULL_HANDLE || target == NULL_HANDLE) {
3614                 return;
3615             }
3616             switch (status[dependent]) {
3617 
3618                 case STATUS_UNKNOWN:
3619                     switch (status[target]) {
3620                         case STATUS_OK:
3621                             // ignore dependencies on objs with no exception
3622                             break;
3623 
3624                         case STATUS_EXCEPTION:
3625                             // eagerly propagate exception
3626                             markException(dependent,
3627                                 (ClassNotFoundException) entries[target]);
3628                             break;
3629 
3630                         case STATUS_UNKNOWN:
3631                             // add to dependency list of target
3632                             if (deps[target] == null) {
3633                                 deps[target] = new HandleList();
3634                             }
3635                             deps[target].add(dependent);
3636 
3637                             // remember lowest unresolved target seen
3638                             if (lowDep < 0 || lowDep > target) {
3639                                 lowDep = target;
3640                             }
3641                             break;
3642 
3643                         default:
3644                             throw new InternalError();
3645                     }
3646                     break;
3647 
3648                 case STATUS_EXCEPTION:
3649                     break;
3650 
3651                 default:
3652                     throw new InternalError();
3653             }
3654         }
3655 
3656         /**
3657          * Associates a ClassNotFoundException (if one not already associated)
3658          * with the currently active handle and propagates it to other
3659          * referencing objects as appropriate.  The specified handle must be
3660          * "open" (i.e., assigned, but not finished yet).
3661          */
3662         void markException(int handle, ClassNotFoundException ex) {
3663             switch (status[handle]) {
3664                 case STATUS_UNKNOWN:
3665                     status[handle] = STATUS_EXCEPTION;
3666                     entries[handle] = ex;
3667 
3668                     // propagate exception to dependents
3669                     HandleList dlist = deps[handle];
3670                     if (dlist != null) {
3671                         int ndeps = dlist.size();
3672                         for (int i = 0; i < ndeps; i++) {
3673                             markException(dlist.get(i), ex);
3674                         }
3675                         deps[handle] = null;
3676                     }
3677                     break;
3678 
3679                 case STATUS_EXCEPTION:
3680                     break;
3681 
3682                 default:
3683                     throw new InternalError();
3684             }
3685         }
3686 
3687         /**
3688          * Marks given handle as finished, meaning that no new dependencies
3689          * will be marked for handle.  Calls to the assign and finish methods
3690          * must occur in LIFO order.
3691          */
3692         void finish(int handle) {
3693             int end;
3694             if (lowDep < 0) {
3695                 // no pending unknowns, only resolve current handle
3696                 end = handle + 1;
3697             } else if (lowDep >= handle) {
3698                 // pending unknowns now clearable, resolve all upward handles
3699                 end = size;
3700                 lowDep = -1;
3701             } else {
3702                 // unresolved backrefs present, can't resolve anything yet
3703                 return;
3704             }
3705 
3706             // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles
3707             for (int i = handle; i < end; i++) {
3708                 switch (status[i]) {
3709                     case STATUS_UNKNOWN:
3710                         status[i] = STATUS_OK;
3711                         deps[i] = null;
3712                         break;
3713 
3714                     case STATUS_OK:
3715                     case STATUS_EXCEPTION:
3716                         break;
3717 
3718                     default:
3719                         throw new InternalError();
3720                 }
3721             }
3722         }
3723 
3724         /**
3725          * Assigns a new object to the given handle.  The object previously
3726          * associated with the handle is forgotten.  This method has no effect
3727          * if the given handle already has an exception associated with it.
3728          * This method may be called at any time after the handle is assigned.
3729          */
3730         void setObject(int handle, Object obj) {
3731             switch (status[handle]) {
3732                 case STATUS_UNKNOWN:
3733                 case STATUS_OK:
3734                     entries[handle] = obj;
3735                     break;
3736 
3737                 case STATUS_EXCEPTION:
3738                     break;
3739 
3740                 default:
3741                     throw new InternalError();
3742             }
3743         }
3744 
3745         /**
3746          * Looks up and returns object associated with the given handle.
3747          * Returns null if the given handle is NULL_HANDLE, or if it has an
3748          * associated ClassNotFoundException.
3749          */
3750         Object lookupObject(int handle) {
3751             return (handle != NULL_HANDLE &&
3752                     status[handle] != STATUS_EXCEPTION) ?
3753                 entries[handle] : null;
3754         }
3755 
3756         /**
3757          * Looks up and returns ClassNotFoundException associated with the
3758          * given handle.  Returns null if the given handle is NULL_HANDLE, or
3759          * if there is no ClassNotFoundException associated with the handle.
3760          */
3761         ClassNotFoundException lookupException(int handle) {
3762             return (handle != NULL_HANDLE &&
3763                     status[handle] == STATUS_EXCEPTION) ?
3764                 (ClassNotFoundException) entries[handle] : null;
3765         }
3766 
3767         /**
3768          * Resets table to its initial state.
3769          */
3770         void clear() {
3771             Arrays.fill(status, 0, size, (byte) 0);
3772             Arrays.fill(entries, 0, size, null);
3773             Arrays.fill(deps, 0, size, null);
3774             lowDep = -1;
3775             size = 0;
3776         }
3777 
3778         /**
3779          * Returns number of handles registered in table.
3780          */
3781         int size() {
3782             return size;
3783         }
3784 
3785         /**
3786          * Expands capacity of internal arrays.
3787          */
3788         private void grow() {
3789             int newCapacity = (entries.length << 1) + 1;
3790 
3791             byte[] newStatus = new byte[newCapacity];
3792             Object[] newEntries = new Object[newCapacity];
3793             HandleList[] newDeps = new HandleList[newCapacity];
3794 
3795             System.arraycopy(status, 0, newStatus, 0, size);
3796             System.arraycopy(entries, 0, newEntries, 0, size);
3797             System.arraycopy(deps, 0, newDeps, 0, size);
3798 
3799             status = newStatus;
3800             entries = newEntries;
3801             deps = newDeps;
3802         }
3803 
3804         /**
3805          * Simple growable list of (integer) handles.
3806          */
3807         private static class HandleList {
3808             private int[] list = new int[4];
3809             private int size = 0;
3810 
3811             public HandleList() {
3812             }
3813 
3814             public void add(int handle) {
3815                 if (size >= list.length) {
3816                     int[] newList = new int[list.length << 1];
3817                     System.arraycopy(list, 0, newList, 0, list.length);
3818                     list = newList;
3819                 }
3820                 list[size++] = handle;
3821             }
3822 
3823             public int get(int index) {
3824                 if (index >= size) {
3825                     throw new ArrayIndexOutOfBoundsException();
3826                 }
3827                 return list[index];
3828             }
3829 
3830             public int size() {
3831                 return size;
3832             }
3833         }
3834     }
3835 
3836     /**
3837      * Method for cloning arrays in case of using unsharing reading
3838      */
3839     private static Object cloneArray(Object array) {
3840         if (array instanceof Object[]) {
3841             return ((Object[]) array).clone();
3842         } else if (array instanceof boolean[]) {
3843             return ((boolean[]) array).clone();
3844         } else if (array instanceof byte[]) {
3845             return ((byte[]) array).clone();
3846         } else if (array instanceof char[]) {
3847             return ((char[]) array).clone();
3848         } else if (array instanceof double[]) {
3849             return ((double[]) array).clone();
3850         } else if (array instanceof float[]) {
3851             return ((float[]) array).clone();
3852         } else if (array instanceof int[]) {
3853             return ((int[]) array).clone();
3854         } else if (array instanceof long[]) {
3855             return ((long[]) array).clone();
3856         } else if (array instanceof short[]) {
3857             return ((short[]) array).clone();
3858         } else {
3859             throw new AssertionError();
3860         }
3861     }
3862 
3863     private void validateDescriptor(ObjectStreamClass descriptor) {
3864         ObjectStreamClassValidator validating = validator;
3865         if (validating != null) {
3866             validating.validateDescriptor(descriptor);
3867         }
3868     }
3869 
3870     // controlled access to ObjectStreamClassValidator
3871     private volatile ObjectStreamClassValidator validator;
3872 
3873     private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) {
3874         ois.validator = validator;
3875     }
3876     static {
3877         SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
3878     }
3879 }