236 static final ReferenceQueue<Class<?>> subclassAuditsQueue =
237 new ReferenceQueue<>();
238 }
239
240 /** filter stream for handling block data conversion */
241 private final BlockDataInputStream bin;
242 /** validation callback list */
243 private final ValidationList vlist;
244 /** recursion depth */
245 private int depth;
246 /** whether stream is closed */
247 private boolean closed;
248
249 /** wire handle -> obj/exception map */
250 private final HandleTable handles;
251 /** scratch field for passing handle values up/down call stack */
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 * Creates an ObjectInputStream that reads from the specified InputStream.
273 * A serialization stream header is read from the stream and verified.
274 * This constructor will block until the corresponding ObjectOutputStream
275 * has written and flushed the header.
276 *
277 * <p>If a security manager is installed, this constructor will check for
278 * the "enableSubclassImplementation" SerializablePermission when invoked
483 * this stream. This may only be called from the readObject method of the
484 * class being deserialized. It will throw the NotActiveException if it is
485 * called otherwise.
486 *
487 * @throws ClassNotFoundException if the class of a serialized object
488 * could not be found.
489 * @throws IOException if an I/O error occurs.
490 * @throws NotActiveException if the stream is not currently reading
491 * objects.
492 */
493 public void defaultReadObject()
494 throws IOException, ClassNotFoundException
495 {
496 SerialCallbackContext ctx = curContext;
497 if (ctx == null) {
498 throw new NotActiveException("not in call to readObject");
499 }
500 Object curObj = ctx.getObj();
501 ObjectStreamClass curDesc = ctx.getDesc();
502 bin.setBlockDataMode(false);
503 defaultReadFields(curObj, curDesc);
504 bin.setBlockDataMode(true);
505 if (!curDesc.hasWriteObjectData()) {
506 /*
507 * Fix for 4360508: since stream does not contain terminating
508 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
509 * knows to simulate end-of-custom-data behavior.
510 */
511 defaultDataEnd = true;
512 }
513 ClassNotFoundException ex = handles.lookupException(passHandle);
514 if (ex != null) {
515 throw ex;
516 }
517 }
518
519 /**
520 * Reads the persistent fields from the stream and makes them available by
521 * name.
522 *
523 * @return the <code>GetField</code> object representing the persistent
1864 * CNFException, then the stream is probably in an inconsistent state,
1865 * since some (or all) of the externalizable data may not have been
1866 * consumed. Since there's no "correct" action to take in this case,
1867 * we mimic the behavior of past serialization implementations and
1868 * blindly hope that the stream is in sync; if it isn't and additional
1869 * externalizable data remains in the stream, a subsequent read will
1870 * most likely throw a StreamCorruptedException.
1871 */
1872 }
1873
1874 /**
1875 * Reads (or attempts to skip, if obj is null or is tagged with a
1876 * ClassNotFoundException) instance data for each serializable class of
1877 * object in stream, from superclass to subclass. Expects that passHandle
1878 * is set to obj's handle before this method is called.
1879 */
1880 private void readSerialData(Object obj, ObjectStreamClass desc)
1881 throws IOException
1882 {
1883 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1884 for (int i = 0; i < slots.length; i++) {
1885 ObjectStreamClass slotDesc = slots[i].desc;
1886
1887 if (slots[i].hasData) {
1888 if (obj != null &&
1889 slotDesc.hasReadObjectMethod() &&
1890 handles.lookupException(passHandle) == null)
1891 {
1892 SerialCallbackContext oldContext = curContext;
1893
1894 try {
1895 curContext = new SerialCallbackContext(obj, slotDesc);
1896
1897 bin.setBlockDataMode(true);
1898 slotDesc.invokeReadObject(obj, this);
1899 } catch (ClassNotFoundException ex) {
1900 /*
1901 * In most cases, the handle table has already
1902 * propagated a CNFException to passHandle at this
1903 * point; this mark call is included to address cases
1904 * where the custom readObject method has cons'ed and
1905 * thrown a new CNFException of its own.
1906 */
1907 handles.markException(passHandle, ex);
1908 } finally {
1909 curContext.setUsed();
1910 curContext = oldContext;
1911 }
1912
1913 /*
1914 * defaultDataEnd may have been set indirectly by custom
1915 * readObject() method when calling defaultReadObject() or
1916 * readFields(); clear it to restore normal read behavior.
1917 */
1918 defaultDataEnd = false;
1919 } else {
1920 defaultReadFields(obj, slotDesc);
1921 }
1922 if (slotDesc.hasWriteObjectData()) {
1923 skipCustomData();
1924 } else {
1925 bin.setBlockDataMode(false);
1926 }
1927 } else {
1928 if (obj != null &&
1929 slotDesc.hasReadObjectNoDataMethod() &&
1930 handles.lookupException(passHandle) == null)
1931 {
1932 slotDesc.invokeReadObjectNoData(obj);
1933 }
1934 }
1935 }
1936 }
1937
1938 /**
1939 * Skips over all block data and objects until TC_ENDBLOCKDATA is
1940 * encountered.
1941 */
1942 private void skipCustomData() throws IOException {
1943 int oldHandle = passHandle;
1944 for (;;) {
1945 if (bin.getBlockDataMode()) {
1946 bin.skipBlockData();
1947 bin.setBlockDataMode(false);
1948 }
1949 switch (bin.peekByte()) {
1950 case TC_BLOCKDATA:
1951 case TC_BLOCKDATALONG:
1952 bin.setBlockDataMode(true);
1953 break;
1954
1955 case TC_ENDBLOCKDATA:
1956 bin.readByte();
1957 passHandle = oldHandle;
1958 return;
1959
1960 default:
1961 readObject0(false);
1962 break;
1963 }
1964 }
1965 }
1966
1967 /**
1968 * Reads in values of serializable fields declared by given class
1969 * descriptor. If obj is non-null, sets field values in obj. Expects that
1970 * passHandle is set to obj's handle before this method is called.
1971 */
1972 private void defaultReadFields(Object obj, ObjectStreamClass desc)
1973 throws IOException
1974 {
1975 Class<?> cl = desc.forClass();
1976 if (cl != null && obj != null && !cl.isInstance(obj)) {
1977 throw new ClassCastException();
1978 }
1979
1980 int primDataSize = desc.getPrimDataSize();
1981 if (primDataSize > 0) {
1982 if (primVals == null || primVals.length < primDataSize) {
1983 primVals = new byte[primDataSize];
1984 }
1985 bin.readFully(primVals, 0, primDataSize, false);
1986 if (obj != null) {
1987 desc.setPrimFieldValues(obj, primVals);
1988 }
1989 }
1990
1991 int numObjFields = desc.getNumObjFields();
1992 if (numObjFields > 0) {
1993 int objHandle = passHandle;
1994 ObjectStreamField[] fields = desc.getFields(false);
1995 Object[] objVals = new Object[numObjFields];
1996 int numPrimFields = fields.length - objVals.length;
1997 for (int i = 0; i < objVals.length; i++) {
1998 ObjectStreamField f = fields[numPrimFields + i];
1999 objVals[i] = readObject0(f.isUnshared());
2000 if (f.getField() != null) {
2001 handles.markDependency(objHandle, passHandle);
2002 }
2003 }
2004 if (obj != null) {
2005 desc.setObjFieldValues(obj, objVals);
2006 }
2007 passHandle = objHandle;
2008 }
2009 }
2010
2011 /**
2012 * Reads in and returns IOException that caused serialization to abort.
2013 * All stream state is discarded prior to reading in fatal exception. Sets
2014 * passHandle to fatal exception's handle.
2015 */
2016 private IOException readFatalException() throws IOException {
2017 if (bin.readByte() != TC_EXCEPTION) {
2018 throw new InternalError();
2019 }
2020 clear();
2021 return (IOException) readObject0(false);
2022 }
2023
2024 /**
2025 * If recursion depth is 0, clears internal data structures; otherwise,
2026 * throws a StreamCorruptedException. This method is called when a
2027 * TC_RESET typecode is encountered.
2028 */
|
236 static final ReferenceQueue<Class<?>> subclassAuditsQueue =
237 new ReferenceQueue<>();
238 }
239
240 /** filter stream for handling block data conversion */
241 private final BlockDataInputStream bin;
242 /** validation callback list */
243 private final ValidationList vlist;
244 /** recursion depth */
245 private int depth;
246 /** whether stream is closed */
247 private boolean closed;
248
249 /** wire handle -> obj/exception map */
250 private final HandleTable handles;
251 /** scratch field for passing handle values up/down call stack */
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 /** if true, invoke readObjectOverride() instead of readObject() */
257 private final boolean enableOverride;
258 /** if true, invoke resolveObject() */
259 private boolean enableResolve;
260
261 /**
262 * Context during upcalls to class-defined readObject methods; holds
263 * object currently being deserialized and descriptor for current class.
264 * Null when not during readObject upcall.
265 */
266 private SerialCallbackContext curContext;
267
268 /**
269 * Creates an ObjectInputStream that reads from the specified InputStream.
270 * A serialization stream header is read from the stream and verified.
271 * This constructor will block until the corresponding ObjectOutputStream
272 * has written and flushed the header.
273 *
274 * <p>If a security manager is installed, this constructor will check for
275 * the "enableSubclassImplementation" SerializablePermission when invoked
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
488 * objects.
489 */
490 public void defaultReadObject()
491 throws IOException, ClassNotFoundException
492 {
493 SerialCallbackContext ctx = curContext;
494 if (ctx == null) {
495 throw new NotActiveException("not in call to readObject");
496 }
497 Object curObj = ctx.getObj();
498 ObjectStreamClass curDesc = ctx.getDesc();
499 bin.setBlockDataMode(false);
500 StreamFieldValues vals = defaultReadFields(curObj, curDesc);
501 if (curObj != null) {
502 defaultCheckFieldValues(curObj, curDesc, vals);
503 defaultSetFieldValues(curObj, curDesc, vals);
504 }
505 bin.setBlockDataMode(true);
506 if (!curDesc.hasWriteObjectData()) {
507 /*
508 * Fix for 4360508: since stream does not contain terminating
509 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
510 * knows to simulate end-of-custom-data behavior.
511 */
512 defaultDataEnd = true;
513 }
514 ClassNotFoundException ex = handles.lookupException(passHandle);
515 if (ex != null) {
516 throw ex;
517 }
518 }
519
520 /**
521 * Reads the persistent fields from the stream and makes them available by
522 * name.
523 *
524 * @return the <code>GetField</code> object representing the persistent
1865 * CNFException, then the stream is probably in an inconsistent state,
1866 * since some (or all) of the externalizable data may not have been
1867 * consumed. Since there's no "correct" action to take in this case,
1868 * we mimic the behavior of past serialization implementations and
1869 * blindly hope that the stream is in sync; if it isn't and additional
1870 * externalizable data remains in the stream, a subsequent read will
1871 * most likely throw a StreamCorruptedException.
1872 */
1873 }
1874
1875 /**
1876 * Reads (or attempts to skip, if obj is null or is tagged with a
1877 * ClassNotFoundException) instance data for each serializable class of
1878 * object in stream, from superclass to subclass. Expects that passHandle
1879 * is set to obj's handle before this method is called.
1880 */
1881 private void readSerialData(Object obj, ObjectStreamClass desc)
1882 throws IOException
1883 {
1884 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1885
1886 // Best effort Failure Atomicity; Each element in 'slotFieldValues'
1887 // contains the stream field values for the same element in 'slots',
1888 // up to the first slot with a readObject(NoData) method ( a user
1889 // visible effect ).
1890 int index = 1;
1891 for (; index < slots.length; index++) {
1892 ObjectStreamClass slotDesc = slots[index].desc;
1893 if (slotDesc.hasReadObjectMethod()
1894 || slotDesc.hasReadObjectNoDataMethod()) {
1895 break;
1896 }
1897 }
1898 // Store, and defer setting, values for index slots, ignore if just one.
1899 StreamFieldValues[] slotFieldValues = null;
1900 if (index > 1 && obj != null)
1901 slotFieldValues = new StreamFieldValues[index];
1902
1903 for (int i = 0; i < slots.length; i++) {
1904 ObjectStreamClass slotDesc = slots[i].desc;
1905
1906 if (slots[i].hasData) {
1907 if (obj != null &&
1908 slotDesc.hasReadObjectMethod() &&
1909 handles.lookupException(passHandle) == null)
1910 {
1911 SerialCallbackContext oldContext = curContext;
1912
1913 try {
1914 curContext = new SerialCallbackContext(obj, slotDesc);
1915
1916 bin.setBlockDataMode(true);
1917 slotDesc.invokeReadObject(obj, this);
1918 } catch (ClassNotFoundException ex) {
1919 /*
1920 * In most cases, the handle table has already
1921 * propagated a CNFException to passHandle at this
1922 * point; this mark call is included to address cases
1923 * where the custom readObject method has cons'ed and
1924 * thrown a new CNFException of its own.
1925 */
1926 handles.markException(passHandle, ex);
1927 } finally {
1928 curContext.setUsed();
1929 curContext = oldContext;
1930 }
1931
1932 /*
1933 * defaultDataEnd may have been set indirectly by custom
1934 * readObject() method when calling defaultReadObject() or
1935 * readFields(); clear it to restore normal read behavior.
1936 */
1937 defaultDataEnd = false;
1938 } else {
1939 StreamFieldValues vals = defaultReadFields(obj, slotDesc);
1940 if (obj != null)
1941 defaultCheckFieldValues(obj, slotDesc, vals);
1942 if (slotFieldValues != null) {
1943 slotFieldValues[i] = vals;
1944 } else if (obj != null) {
1945 defaultSetFieldValues(obj, slotDesc, vals);
1946 }
1947 }
1948 if (slotDesc.hasWriteObjectData()) {
1949 skipCustomData();
1950 } else {
1951 bin.setBlockDataMode(false);
1952 }
1953 } else {
1954 if (obj != null &&
1955 slotDesc.hasReadObjectNoDataMethod() &&
1956 handles.lookupException(passHandle) == null)
1957 {
1958 slotDesc.invokeReadObjectNoData(obj);
1959 }
1960 }
1961
1962 if (slotFieldValues != null && i == (index - 1) && obj != null) {
1963 assert slotFieldValues.length == index;
1964 assert slots.length >= index;
1965 setSlotFieldValues(obj, slots, slotFieldValues);
1966 slotFieldValues = null; // remaining slots will be set when read
1967 }
1968 }
1969 }
1970
1971 /** Sets slot field values in the given obj. */
1972 private void setSlotFieldValues(Object obj,
1973 ObjectStreamClass.ClassDataSlot[] slots,
1974 StreamFieldValues[] slotFieldValues) {
1975 int length = slotFieldValues.length;
1976 for (int i = 0; i < length; i++) {
1977 if (slotFieldValues[i] != null)
1978 defaultSetFieldValues(obj, slots[i].desc, slotFieldValues[i]);
1979 }
1980 }
1981
1982 /**
1983 * Skips over all block data and objects until TC_ENDBLOCKDATA is
1984 * encountered.
1985 */
1986 private void skipCustomData() throws IOException {
1987 int oldHandle = passHandle;
1988 for (;;) {
1989 if (bin.getBlockDataMode()) {
1990 bin.skipBlockData();
1991 bin.setBlockDataMode(false);
1992 }
1993 switch (bin.peekByte()) {
1994 case TC_BLOCKDATA:
1995 case TC_BLOCKDATALONG:
1996 bin.setBlockDataMode(true);
1997 break;
1998
1999 case TC_ENDBLOCKDATA:
2000 bin.readByte();
2001 passHandle = oldHandle;
2002 return;
2003
2004 default:
2005 readObject0(false);
2006 break;
2007 }
2008 }
2009 }
2010
2011 /** A holder for field values read from the stream. */
2012 private class StreamFieldValues {
2013 final byte[] primValues;
2014 final Object[] objValues;
2015 StreamFieldValues(byte[] primValues, Object[] objValues) {
2016 this.primValues = primValues;
2017 this.objValues = objValues;
2018 }
2019 }
2020
2021 /**
2022 * Reads in and returns the values of serializable fields declared by the
2023 * given class descriptor. Expects that passHandle is set to obj's handle
2024 * before this method is called.
2025 */
2026 private StreamFieldValues defaultReadFields(Object obj, ObjectStreamClass desc)
2027 throws IOException
2028 {
2029 Class<?> cl = desc.forClass();
2030 if (cl != null && obj != null && !cl.isInstance(obj)) {
2031 throw new ClassCastException();
2032 }
2033
2034 byte[] primVals = null;
2035 int primDataSize = desc.getPrimDataSize();
2036 if (primDataSize > 0) {
2037 primVals = new byte[primDataSize];
2038 bin.readFully(primVals, 0, primDataSize, false);
2039 }
2040
2041 Object[] objVals = null;
2042 int numObjFields = desc.getNumObjFields();
2043 if (numObjFields > 0) {
2044 int objHandle = passHandle;
2045 ObjectStreamField[] fields = desc.getFields(false);
2046 objVals = new Object[numObjFields];
2047 int numPrimFields = fields.length - objVals.length;
2048 for (int i = 0; i < objVals.length; i++) {
2049 ObjectStreamField f = fields[numPrimFields + i];
2050 objVals[i] = readObject0(f.isUnshared());
2051 if (f.getField() != null) {
2052 handles.markDependency(objHandle, passHandle);
2053 }
2054 }
2055 passHandle = objHandle;
2056 }
2057
2058 return new StreamFieldValues(primVals, objVals);
2059 }
2060
2061 /** Throws ClassCastException if any value is not assignable. */
2062 private void defaultCheckFieldValues(Object obj, ObjectStreamClass desc,
2063 StreamFieldValues values) {
2064 Object[] objectValues = values.objValues;
2065 if (objectValues != null)
2066 desc.checkObjFieldValueTypes(obj, objectValues);
2067 }
2068
2069 /** Sets field values in obj. */
2070 private void defaultSetFieldValues(Object obj, ObjectStreamClass desc,
2071 StreamFieldValues values) {
2072 byte[] primValues = values.primValues;
2073 Object[] objectValues = values.objValues;
2074
2075 if (primValues != null)
2076 desc.setPrimFieldValues(obj, primValues);
2077 if (objectValues != null)
2078 desc.setObjFieldValues(obj, objectValues);
2079 }
2080
2081 /**
2082 * Reads in and returns IOException that caused serialization to abort.
2083 * All stream state is discarded prior to reading in fatal exception. Sets
2084 * passHandle to fatal exception's handle.
2085 */
2086 private IOException readFatalException() throws IOException {
2087 if (bin.readByte() != TC_EXCEPTION) {
2088 throw new InternalError();
2089 }
2090 clear();
2091 return (IOException) readObject0(false);
2092 }
2093
2094 /**
2095 * If recursion depth is 0, clears internal data structures; otherwise,
2096 * throws a StreamCorruptedException. This method is called when a
2097 * TC_RESET typecode is encountered.
2098 */
|