23 * questions.
24 */
25
26 package java.io;
27
28 import java.io.ObjectStreamClass.WeakClassKey;
29 import java.lang.ref.ReferenceQueue;
30 import java.lang.reflect.Array;
31 import java.lang.reflect.Modifier;
32 import java.lang.reflect.Proxy;
33 import java.security.AccessControlContext;
34 import java.security.AccessController;
35 import java.security.PrivilegedAction;
36 import java.security.PrivilegedActionException;
37 import java.security.PrivilegedExceptionAction;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.ConcurrentMap;
42 import static java.io.ObjectStreamClass.processQueue;
43 import sun.reflect.misc.ReflectUtil;
44
45 /**
46 * An ObjectInputStream deserializes primitive data and objects previously
47 * written using an ObjectOutputStream.
48 *
49 * <p>ObjectOutputStream and ObjectInputStream can provide an application with
50 * persistent storage for graphs of objects when used with a FileOutputStream
51 * and FileInputStream respectively. ObjectInputStream is used to recover
52 * those objects previously serialized. Other uses include passing objects
53 * between hosts using a socket stream or for marshaling and unmarshaling
54 * arguments and parameters in a remote communication system.
55 *
56 * <p>ObjectInputStream ensures that the types of all objects in the graph
57 * created from the stream match the classes present in the Java Virtual
58 * Machine. Classes are loaded as required using the standard mechanisms.
59 *
60 * <p>Only objects that support the java.io.Serializable or
61 * java.io.Externalizable interface can be read from streams.
62 *
251 private int passHandle = NULL_HANDLE;
252 /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
253 private boolean defaultDataEnd = false;
254
255 /** buffer for reading primitive field values */
256 private byte[] primVals;
257
258 /** if true, invoke readObjectOverride() instead of readObject() */
259 private final boolean enableOverride;
260 /** if true, invoke resolveObject() */
261 private boolean enableResolve;
262
263 /**
264 * Context during upcalls to class-defined readObject methods; holds
265 * object currently being deserialized and descriptor for current class.
266 * Null when not during readObject upcall.
267 */
268 private SerialCallbackContext curContext;
269
270 /**
271 * Creates an ObjectInputStream that reads from the specified InputStream.
272 * A serialization stream header is read from the stream and verified.
273 * This constructor will block until the corresponding ObjectOutputStream
274 * has written and flushed the header.
275 *
276 * <p>If a security manager is installed, this constructor will check for
277 * the "enableSubclassImplementation" SerializablePermission when invoked
278 * directly or indirectly by the constructor of a subclass which overrides
279 * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
280 * methods.
281 *
282 * @param in input stream to read from
283 * @throws StreamCorruptedException if the stream header is incorrect
284 * @throws IOException if an I/O error occurs while reading stream header
285 * @throws SecurityException if untrusted subclass illegally overrides
286 * security-sensitive methods
287 * @throws NullPointerException if <code>in</code> is <code>null</code>
288 * @see ObjectInputStream#ObjectInputStream()
289 * @see ObjectInputStream#readFields()
290 * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
356 * @throws OptionalDataException Primitive data was found in the
357 * stream instead of objects.
358 * @throws IOException Any of the usual Input/Output related exceptions.
359 */
360 public final Object readObject()
361 throws IOException, ClassNotFoundException
362 {
363 if (enableOverride) {
364 return readObjectOverride();
365 }
366
367 // if nested read, passHandle contains handle of enclosing object
368 int outerHandle = passHandle;
369 try {
370 Object obj = readObject0(false);
371 handles.markDependency(outerHandle, passHandle);
372 ClassNotFoundException ex = handles.lookupException(passHandle);
373 if (ex != null) {
374 throw ex;
375 }
376 if (depth == 0) {
377 vlist.doCallbacks();
378 }
379 return obj;
380 } finally {
381 passHandle = outerHandle;
382 if (closed && depth == 0) {
383 clear();
384 }
385 }
386 }
387
388 /**
389 * This method is called by trusted subclasses of ObjectOutputStream that
390 * constructed ObjectOutputStream using the protected no-arg constructor.
391 * The subclass is expected to provide an override method with the modifier
392 * "final".
393 *
394 * @return the Object read from the stream.
395 * @throws ClassNotFoundException Class definition of a serialized object
446 * @throws ClassNotFoundException if class of an object to deserialize
447 * cannot be found
448 * @throws StreamCorruptedException if control information in the stream
449 * is inconsistent
450 * @throws ObjectStreamException if object to deserialize has already
451 * appeared in stream
452 * @throws OptionalDataException if primitive data is next in stream
453 * @throws IOException if an I/O error occurs during deserialization
454 * @since 1.4
455 */
456 public Object readUnshared() throws IOException, ClassNotFoundException {
457 // if nested read, passHandle contains handle of enclosing object
458 int outerHandle = passHandle;
459 try {
460 Object obj = readObject0(true);
461 handles.markDependency(outerHandle, passHandle);
462 ClassNotFoundException ex = handles.lookupException(passHandle);
463 if (ex != null) {
464 throw ex;
465 }
466 if (depth == 0) {
467 vlist.doCallbacks();
468 }
469 return obj;
470 } finally {
471 passHandle = outerHandle;
472 if (closed && depth == 0) {
473 clear();
474 }
475 }
476 }
477
478 /**
479 * Read the non-static and non-transient fields of the current class from
480 * this stream. This may only be called from the readObject method of the
481 * class being deserialized. It will throw the NotActiveException if it is
482 * called otherwise.
483 *
484 * @throws ClassNotFoundException if the class of a serialized object
485 * could not be found.
1863 * consumed. Since there's no "correct" action to take in this case,
1864 * we mimic the behavior of past serialization implementations and
1865 * blindly hope that the stream is in sync; if it isn't and additional
1866 * externalizable data remains in the stream, a subsequent read will
1867 * most likely throw a StreamCorruptedException.
1868 */
1869 }
1870
1871 /**
1872 * Reads (or attempts to skip, if obj is null or is tagged with a
1873 * ClassNotFoundException) instance data for each serializable class of
1874 * object in stream, from superclass to subclass. Expects that passHandle
1875 * is set to obj's handle before this method is called.
1876 */
1877 private void readSerialData(Object obj, ObjectStreamClass desc)
1878 throws IOException
1879 {
1880 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1881 for (int i = 0; i < slots.length; i++) {
1882 ObjectStreamClass slotDesc = slots[i].desc;
1883
1884 if (slots[i].hasData) {
1885 if (obj != null &&
1886 slotDesc.hasReadObjectMethod() &&
1887 handles.lookupException(passHandle) == null)
1888 {
1889 SerialCallbackContext oldContext = curContext;
1890
1891 try {
1892 curContext = new SerialCallbackContext(obj, slotDesc);
1893
1894 bin.setBlockDataMode(true);
1895 slotDesc.invokeReadObject(obj, this);
1896 } catch (ClassNotFoundException ex) {
1897 /*
1898 * In most cases, the handle table has already
1899 * propagated a CNFException to passHandle at this
1900 * point; this mark call is included to address cases
1901 * where the custom readObject method has cons'ed and
1902 * thrown a new CNFException of its own.
2338 public long skip(long n) throws IOException {
2339 if (n <= 0) {
2340 return 0;
2341 }
2342 int skipped = 0;
2343 if (peekb >= 0) {
2344 peekb = -1;
2345 skipped++;
2346 n--;
2347 }
2348 return skipped + in.skip(n);
2349 }
2350
2351 public int available() throws IOException {
2352 return in.available() + ((peekb >= 0) ? 1 : 0);
2353 }
2354
2355 public void close() throws IOException {
2356 in.close();
2357 }
2358 }
2359
2360 /**
2361 * Input stream with two modes: in default mode, inputs data written in the
2362 * same format as DataOutputStream; in "block data" mode, inputs data
2363 * bracketed by block data markers (see object serialization specification
2364 * for details). Buffering depends on block data mode: when in default
2365 * mode, no data is buffered in advance; when in block data mode, all data
2366 * for the current data block is read in at once (and buffered).
2367 */
2368 private class BlockDataInputStream
2369 extends InputStream implements DataInput
2370 {
2371 /** maximum data block length */
2372 private static final int MAX_BLOCK_SIZE = 1024;
2373 /** maximum data block header length */
2374 private static final int MAX_HEADER_SIZE = 5;
2375 /** (tunable) length of char buffer (for reading strings) */
2376 private static final int CHAR_BUF_SIZE = 256;
2377 /** readBlockHeader() return value indicating header read may block */
|
23 * questions.
24 */
25
26 package java.io;
27
28 import java.io.ObjectStreamClass.WeakClassKey;
29 import java.lang.ref.ReferenceQueue;
30 import java.lang.reflect.Array;
31 import java.lang.reflect.Modifier;
32 import java.lang.reflect.Proxy;
33 import java.security.AccessControlContext;
34 import java.security.AccessController;
35 import java.security.PrivilegedAction;
36 import java.security.PrivilegedActionException;
37 import java.security.PrivilegedExceptionAction;
38 import java.util.Arrays;
39 import java.util.HashMap;
40 import java.util.concurrent.ConcurrentHashMap;
41 import java.util.concurrent.ConcurrentMap;
42 import static java.io.ObjectStreamClass.processQueue;
43 import sun.misc.Unsafe;
44 import sun.reflect.misc.ReflectUtil;
45
46 /**
47 * An ObjectInputStream deserializes primitive data and objects previously
48 * written using an ObjectOutputStream.
49 *
50 * <p>ObjectOutputStream and ObjectInputStream can provide an application with
51 * persistent storage for graphs of objects when used with a FileOutputStream
52 * and FileInputStream respectively. ObjectInputStream is used to recover
53 * those objects previously serialized. Other uses include passing objects
54 * between hosts using a socket stream or for marshaling and unmarshaling
55 * arguments and parameters in a remote communication system.
56 *
57 * <p>ObjectInputStream ensures that the types of all objects in the graph
58 * created from the stream match the classes present in the Java Virtual
59 * Machine. Classes are loaded as required using the standard mechanisms.
60 *
61 * <p>Only objects that support the java.io.Serializable or
62 * java.io.Externalizable interface can be read from streams.
63 *
252 private int passHandle = NULL_HANDLE;
253 /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
254 private boolean defaultDataEnd = false;
255
256 /** buffer for reading primitive field values */
257 private byte[] primVals;
258
259 /** if true, invoke readObjectOverride() instead of readObject() */
260 private final boolean enableOverride;
261 /** if true, invoke resolveObject() */
262 private boolean enableResolve;
263
264 /**
265 * Context during upcalls to class-defined readObject methods; holds
266 * object currently being deserialized and descriptor for current class.
267 * Null when not during readObject upcall.
268 */
269 private SerialCallbackContext curContext;
270
271 /**
272 * Tracks whether any object in the graph has a final field, and therefore
273 * requires a freeze action before publishing.
274 */
275 private boolean requiresFreeze;
276
277 /**
278 * Creates an ObjectInputStream that reads from the specified InputStream.
279 * A serialization stream header is read from the stream and verified.
280 * This constructor will block until the corresponding ObjectOutputStream
281 * has written and flushed the header.
282 *
283 * <p>If a security manager is installed, this constructor will check for
284 * the "enableSubclassImplementation" SerializablePermission when invoked
285 * directly or indirectly by the constructor of a subclass which overrides
286 * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
287 * methods.
288 *
289 * @param in input stream to read from
290 * @throws StreamCorruptedException if the stream header is incorrect
291 * @throws IOException if an I/O error occurs while reading stream header
292 * @throws SecurityException if untrusted subclass illegally overrides
293 * security-sensitive methods
294 * @throws NullPointerException if <code>in</code> is <code>null</code>
295 * @see ObjectInputStream#ObjectInputStream()
296 * @see ObjectInputStream#readFields()
297 * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
363 * @throws OptionalDataException Primitive data was found in the
364 * stream instead of objects.
365 * @throws IOException Any of the usual Input/Output related exceptions.
366 */
367 public final Object readObject()
368 throws IOException, ClassNotFoundException
369 {
370 if (enableOverride) {
371 return readObjectOverride();
372 }
373
374 // if nested read, passHandle contains handle of enclosing object
375 int outerHandle = passHandle;
376 try {
377 Object obj = readObject0(false);
378 handles.markDependency(outerHandle, passHandle);
379 ClassNotFoundException ex = handles.lookupException(passHandle);
380 if (ex != null) {
381 throw ex;
382 }
383 if (requiresFreeze) {
384 freeze();
385 }
386 if (depth == 0) {
387 vlist.doCallbacks();
388 }
389 return obj;
390 } finally {
391 passHandle = outerHandle;
392 if (closed && depth == 0) {
393 clear();
394 }
395 }
396 }
397
398 /**
399 * This method is called by trusted subclasses of ObjectOutputStream that
400 * constructed ObjectOutputStream using the protected no-arg constructor.
401 * The subclass is expected to provide an override method with the modifier
402 * "final".
403 *
404 * @return the Object read from the stream.
405 * @throws ClassNotFoundException Class definition of a serialized object
456 * @throws ClassNotFoundException if class of an object to deserialize
457 * cannot be found
458 * @throws StreamCorruptedException if control information in the stream
459 * is inconsistent
460 * @throws ObjectStreamException if object to deserialize has already
461 * appeared in stream
462 * @throws OptionalDataException if primitive data is next in stream
463 * @throws IOException if an I/O error occurs during deserialization
464 * @since 1.4
465 */
466 public Object readUnshared() throws IOException, ClassNotFoundException {
467 // if nested read, passHandle contains handle of enclosing object
468 int outerHandle = passHandle;
469 try {
470 Object obj = readObject0(true);
471 handles.markDependency(outerHandle, passHandle);
472 ClassNotFoundException ex = handles.lookupException(passHandle);
473 if (ex != null) {
474 throw ex;
475 }
476 if (requiresFreeze) {
477 freeze();
478 }
479 if (depth == 0) {
480 vlist.doCallbacks();
481 }
482 return obj;
483 } finally {
484 passHandle = outerHandle;
485 if (closed && depth == 0) {
486 clear();
487 }
488 }
489 }
490
491 /**
492 * Read the non-static and non-transient fields of the current class from
493 * this stream. This may only be called from the readObject method of the
494 * class being deserialized. It will throw the NotActiveException if it is
495 * called otherwise.
496 *
497 * @throws ClassNotFoundException if the class of a serialized object
498 * could not be found.
1876 * consumed. Since there's no "correct" action to take in this case,
1877 * we mimic the behavior of past serialization implementations and
1878 * blindly hope that the stream is in sync; if it isn't and additional
1879 * externalizable data remains in the stream, a subsequent read will
1880 * most likely throw a StreamCorruptedException.
1881 */
1882 }
1883
1884 /**
1885 * Reads (or attempts to skip, if obj is null or is tagged with a
1886 * ClassNotFoundException) instance data for each serializable class of
1887 * object in stream, from superclass to subclass. Expects that passHandle
1888 * is set to obj's handle before this method is called.
1889 */
1890 private void readSerialData(Object obj, ObjectStreamClass desc)
1891 throws IOException
1892 {
1893 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1894 for (int i = 0; i < slots.length; i++) {
1895 ObjectStreamClass slotDesc = slots[i].desc;
1896 if (!requiresFreeze && slotDesc.hasFinalField()) {
1897 requiresFreeze = true;
1898 }
1899
1900 if (slots[i].hasData) {
1901 if (obj != null &&
1902 slotDesc.hasReadObjectMethod() &&
1903 handles.lookupException(passHandle) == null)
1904 {
1905 SerialCallbackContext oldContext = curContext;
1906
1907 try {
1908 curContext = new SerialCallbackContext(obj, slotDesc);
1909
1910 bin.setBlockDataMode(true);
1911 slotDesc.invokeReadObject(obj, this);
1912 } catch (ClassNotFoundException ex) {
1913 /*
1914 * In most cases, the handle table has already
1915 * propagated a CNFException to passHandle at this
1916 * point; this mark call is included to address cases
1917 * where the custom readObject method has cons'ed and
1918 * thrown a new CNFException of its own.
2354 public long skip(long n) throws IOException {
2355 if (n <= 0) {
2356 return 0;
2357 }
2358 int skipped = 0;
2359 if (peekb >= 0) {
2360 peekb = -1;
2361 skipped++;
2362 n--;
2363 }
2364 return skipped + in.skip(n);
2365 }
2366
2367 public int available() throws IOException {
2368 return in.available() + ((peekb >= 0) ? 1 : 0);
2369 }
2370
2371 public void close() throws IOException {
2372 in.close();
2373 }
2374 }
2375
2376 private static final Unsafe UNSAFE = Unsafe.getUnsafe();
2377
2378 private void freeze() {
2379 // Issue a storestore|storeload fence, which is at least sufficient
2380 // to provide final-freeze semantics.
2381 UNSAFE.storeFence();
2382 requiresFreeze = false;
2383 }
2384
2385 /**
2386 * Input stream with two modes: in default mode, inputs data written in the
2387 * same format as DataOutputStream; in "block data" mode, inputs data
2388 * bracketed by block data markers (see object serialization specification
2389 * for details). Buffering depends on block data mode: when in default
2390 * mode, no data is buffered in advance; when in block data mode, all data
2391 * for the current data block is read in at once (and buffered).
2392 */
2393 private class BlockDataInputStream
2394 extends InputStream implements DataInput
2395 {
2396 /** maximum data block length */
2397 private static final int MAX_BLOCK_SIZE = 1024;
2398 /** maximum data block header length */
2399 private static final int MAX_HEADER_SIZE = 5;
2400 /** (tunable) length of char buffer (for reading strings) */
2401 private static final int CHAR_BUF_SIZE = 256;
2402 /** readBlockHeader() return value indicating header read may block */
|