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)
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
396 * cannot be found.
397 * @throws OptionalDataException Primitive data was found in the stream
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.
486 * @throws IOException if an I/O error occurs.
487 * @throws NotActiveException if the stream is not currently reading
1861 * CNFException, then the stream is probably in an inconsistent state,
1862 * since some (or all) of the externalizable data may not have been
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.
1913 * readFields(); clear it to restore normal read behavior.
1914 */
1915 defaultDataEnd = false;
1916 } else {
1917 defaultReadFields(obj, slotDesc);
1918 }
1919 if (slotDesc.hasWriteObjectData()) {
1920 skipCustomData();
1921 } else {
1922 bin.setBlockDataMode(false);
1923 }
1924 } else {
1925 if (obj != null &&
1926 slotDesc.hasReadObjectNoDataMethod() &&
1927 handles.lookupException(passHandle) == null)
1928 {
1929 slotDesc.invokeReadObjectNoData(obj);
1930 }
1931 }
1932 }
1933 }
1934
1935 /**
1936 * Skips over all block data and objects until TC_ENDBLOCKDATA is
1937 * encountered.
1938 */
1939 private void skipCustomData() throws IOException {
1940 int oldHandle = passHandle;
1941 for (;;) {
1942 if (bin.getBlockDataMode()) {
1943 bin.skipBlockData();
1944 bin.setBlockDataMode(false);
1945 }
1946 switch (bin.peekByte()) {
1947 case TC_BLOCKDATA:
1948 case TC_BLOCKDATALONG:
1949 bin.setBlockDataMode(true);
1950 break;
1951
1952 case TC_ENDBLOCKDATA:
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 */
2378 private static final int HEADER_BLOCKED = -2;
2379
|
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 deserialization of an object in the graph may have set
273 * a final field, and therefore requires a freeze action before returning
274 * the graph of objects from the topmost readObject call.
275 * Nested calls to readObject do not issue freeze actions because the
276 * sub-graph returned from a nested call is not guaranteed to be fully
277 * initialized yet (possible cycles).
278 */
279 private boolean requiresFreeze;
280
281 /**
282 * Creates an ObjectInputStream that reads from the specified InputStream.
283 * A serialization stream header is read from the stream and verified.
284 * This constructor will block until the corresponding ObjectOutputStream
285 * has written and flushed the header.
286 *
287 * <p>If a security manager is installed, this constructor will check for
288 * the "enableSubclassImplementation" SerializablePermission when invoked
289 * directly or indirectly by the constructor of a subclass which overrides
290 * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
291 * methods.
292 *
293 * @param in input stream to read from
294 * @throws StreamCorruptedException if the stream header is incorrect
295 * @throws IOException if an I/O error occurs while reading stream header
296 * @throws SecurityException if untrusted subclass illegally overrides
297 * security-sensitive methods
298 * @throws NullPointerException if <code>in</code> is <code>null</code>
299 * @see ObjectInputStream#ObjectInputStream()
300 * @see ObjectInputStream#readFields()
301 * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
369 * @throws IOException Any of the usual Input/Output related exceptions.
370 */
371 public final Object readObject()
372 throws IOException, ClassNotFoundException
373 {
374 if (enableOverride) {
375 return readObjectOverride();
376 }
377
378 // if nested read, passHandle contains handle of enclosing object
379 int outerHandle = passHandle;
380 try {
381 Object obj = readObject0(false);
382 handles.markDependency(outerHandle, passHandle);
383 ClassNotFoundException ex = handles.lookupException(passHandle);
384 if (ex != null) {
385 throw ex;
386 }
387 if (depth == 0) {
388 vlist.doCallbacks();
389 if (requiresFreeze) {
390 freeze();
391 }
392 }
393 return obj;
394 } finally {
395 passHandle = outerHandle;
396 if (closed && depth == 0) {
397 clear();
398 }
399 }
400 }
401
402 /**
403 * This method is called by trusted subclasses of ObjectOutputStream that
404 * constructed ObjectOutputStream using the protected no-arg constructor.
405 * The subclass is expected to provide an override method with the modifier
406 * "final".
407 *
408 * @return the Object read from the stream.
409 * @throws ClassNotFoundException Class definition of a serialized object
410 * cannot be found.
411 * @throws OptionalDataException Primitive data was found in the stream
462 * @throws StreamCorruptedException if control information in the stream
463 * is inconsistent
464 * @throws ObjectStreamException if object to deserialize has already
465 * appeared in stream
466 * @throws OptionalDataException if primitive data is next in stream
467 * @throws IOException if an I/O error occurs during deserialization
468 * @since 1.4
469 */
470 public Object readUnshared() throws IOException, ClassNotFoundException {
471 // if nested read, passHandle contains handle of enclosing object
472 int outerHandle = passHandle;
473 try {
474 Object obj = readObject0(true);
475 handles.markDependency(outerHandle, passHandle);
476 ClassNotFoundException ex = handles.lookupException(passHandle);
477 if (ex != null) {
478 throw ex;
479 }
480 if (depth == 0) {
481 vlist.doCallbacks();
482 if (requiresFreeze) {
483 freeze();
484 }
485 }
486 return obj;
487 } finally {
488 passHandle = outerHandle;
489 if (closed && depth == 0) {
490 clear();
491 }
492 }
493 }
494
495 /**
496 * Read the non-static and non-transient fields of the current class from
497 * this stream. This may only be called from the readObject method of the
498 * class being deserialized. It will throw the NotActiveException if it is
499 * called otherwise.
500 *
501 * @throws ClassNotFoundException if the class of a serialized object
502 * could not be found.
503 * @throws IOException if an I/O error occurs.
504 * @throws NotActiveException if the stream is not currently reading
1878 * CNFException, then the stream is probably in an inconsistent state,
1879 * since some (or all) of the externalizable data may not have been
1880 * consumed. Since there's no "correct" action to take in this case,
1881 * we mimic the behavior of past serialization implementations and
1882 * blindly hope that the stream is in sync; if it isn't and additional
1883 * externalizable data remains in the stream, a subsequent read will
1884 * most likely throw a StreamCorruptedException.
1885 */
1886 }
1887
1888 /**
1889 * Reads (or attempts to skip, if obj is null or is tagged with a
1890 * ClassNotFoundException) instance data for each serializable class of
1891 * object in stream, from superclass to subclass. Expects that passHandle
1892 * is set to obj's handle before this method is called.
1893 */
1894 private void readSerialData(Object obj, ObjectStreamClass desc)
1895 throws IOException
1896 {
1897 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1898 boolean freeze = false;
1899 for (int i = 0; i < slots.length; i++) {
1900 ObjectStreamClass slotDesc = slots[i].desc;
1901 if (!freeze && slotDesc.hasFinalField()) {
1902 freeze = true;
1903 }
1904
1905 if (slots[i].hasData) {
1906 if (obj != null &&
1907 slotDesc.hasReadObjectMethod() &&
1908 handles.lookupException(passHandle) == null)
1909 {
1910 SerialCallbackContext oldContext = curContext;
1911
1912 try {
1913 curContext = new SerialCallbackContext(obj, slotDesc);
1914
1915 bin.setBlockDataMode(true);
1916 slotDesc.invokeReadObject(obj, this);
1917 } catch (ClassNotFoundException ex) {
1918 /*
1919 * In most cases, the handle table has already
1920 * propagated a CNFException to passHandle at this
1921 * point; this mark call is included to address cases
1922 * where the custom readObject method has cons'ed and
1923 * thrown a new CNFException of its own.
1934 * readFields(); clear it to restore normal read behavior.
1935 */
1936 defaultDataEnd = false;
1937 } else {
1938 defaultReadFields(obj, slotDesc);
1939 }
1940 if (slotDesc.hasWriteObjectData()) {
1941 skipCustomData();
1942 } else {
1943 bin.setBlockDataMode(false);
1944 }
1945 } else {
1946 if (obj != null &&
1947 slotDesc.hasReadObjectNoDataMethod() &&
1948 handles.lookupException(passHandle) == null)
1949 {
1950 slotDesc.invokeReadObjectNoData(obj);
1951 }
1952 }
1953 }
1954 requiresFreeze = freeze;
1955 }
1956
1957 /**
1958 * Skips over all block data and objects until TC_ENDBLOCKDATA is
1959 * encountered.
1960 */
1961 private void skipCustomData() throws IOException {
1962 int oldHandle = passHandle;
1963 for (;;) {
1964 if (bin.getBlockDataMode()) {
1965 bin.skipBlockData();
1966 bin.setBlockDataMode(false);
1967 }
1968 switch (bin.peekByte()) {
1969 case TC_BLOCKDATA:
1970 case TC_BLOCKDATALONG:
1971 bin.setBlockDataMode(true);
1972 break;
1973
1974 case TC_ENDBLOCKDATA:
2362 return 0;
2363 }
2364 int skipped = 0;
2365 if (peekb >= 0) {
2366 peekb = -1;
2367 skipped++;
2368 n--;
2369 }
2370 return skipped + in.skip(n);
2371 }
2372
2373 public int available() throws IOException {
2374 return in.available() + ((peekb >= 0) ? 1 : 0);
2375 }
2376
2377 public void close() throws IOException {
2378 in.close();
2379 }
2380 }
2381
2382 private static final Unsafe UNSAFE = Unsafe.getUnsafe();
2383
2384 private void freeze() {
2385 // Issue a storestore|storeload fence, which is at least sufficient
2386 // to provide final-freeze semantics.
2387 UNSAFE.storeFence();
2388 requiresFreeze = false;
2389 }
2390
2391 /**
2392 * Input stream with two modes: in default mode, inputs data written in the
2393 * same format as DataOutputStream; in "block data" mode, inputs data
2394 * bracketed by block data markers (see object serialization specification
2395 * for details). Buffering depends on block data mode: when in default
2396 * mode, no data is buffered in advance; when in block data mode, all data
2397 * for the current data block is read in at once (and buffered).
2398 */
2399 private class BlockDataInputStream
2400 extends InputStream implements DataInput
2401 {
2402 /** maximum data block length */
2403 private static final int MAX_BLOCK_SIZE = 1024;
2404 /** maximum data block header length */
2405 private static final int MAX_HEADER_SIZE = 5;
2406 /** (tunable) length of char buffer (for reading strings) */
2407 private static final int CHAR_BUF_SIZE = 256;
2408 /** readBlockHeader() return value indicating header read may block */
2409 private static final int HEADER_BLOCKED = -2;
2410
|