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