1 /*
2  * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  *
26  */
27 
28 import java.io.*;
29 import java.util.Vector;
30 import java.util.Stack;
31 import java.util.Hashtable;
32 import java.lang.Math;
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 import java.lang.reflect.Modifier;
36 
37 /**
38  * This abstract class enables one to subclass ObjectInputStream
39  * for the purpose of re-implementing serialization while preserving the
40  * existing public serialization API. A complimentary subclass of
41  * AbstractObjectInputStream must also be implemented.<p>
42  *
43  * Since serialization must override java access rules in order to
44  * access private, protected and package accessible Serializable fields,
45  * only trusted classes are allowed to subclass AbstractObjectInputStream.
46  * Subclasses of AbstractObjectInputStream must define SerializablePermission
47  * "enableAbstractSubclass" within a security policy file or this
48  * constructor will throw a SecurityException. Implementations of this
49  * class should protect themselves from being subclassed in a way that will
50  * provide access to object references and other sensitive info.
51  * Specifically, readObjectOverride() should be made final.
52  * <p>
53  *
54  * A subclass of AbstractObjectInputStream deserializes primitive data and
55  * objects previously written by a subclass of AbstractObjectOutputStream.
56  * The subclass ensures that the types of all objects in the graph created
57  * from the stream match the classes present in the Java Virtual Machine.
58  * Classes are loaded as required using the standard mechanisms. <p>
59  *
60  * Only objects that support the java.io.Serializable or
61  * java.io.Externalizable interface can be read from streams.
62  *
63  * The method <STRONG>readObjectOverride</STRONG> is used to read an object
64  * from the stream.  Java's safe casting should be used to get the
65  * desired type.  In Java, strings and arrays are objects and are
66  * treated as objects during serialization. When read with readObject()
67  * they need to be cast to the expected type.<p>
68  *
69  * Primitive data types can be read from the stream using the appropriate
70  * method on DataInput. <p>
71  *
72  * The default deserialization mechanism for objects restores the
73  * contents of each field to the value and type it had when it was written.
74  * References to other objects cause those
75  * objects to be read from the stream as necessary.  Graphs of objects
76  * are restored correctly using a reference sharing mechanism.  New
77  * objects are always allocated when deserializing, which prevents
78  * existing objects from being overwritten. <p>
79  *
80  * Reading an object is analogous to running the constructors of a new
81  * object.  Memory is allocated for the object and initialized to zero
82  * (NULL).  No-arg constructors are invoked for the first non-serializable
83  * super class and then the fields of the serializable classes are
84  * restored from the stream starting with the serializable class closest to
85  * java.lang.object and finishing with the object's most specifiec
86  * class. <p>
87  *
88  * Classes control how they are serialized by implementing either the
89  * java.io.Serializable or java.io.Externalizable interfaces.<P>
90  *
91  * Implementing the Serializable interface allows object serialization
92  * to save and restore the entire state of the object and it allows
93  * classes to evolve between the time the stream is written and the time it is
94  * read.  It automatically traverses references between objects,
95  * saving and restoring entire graphs.
96  *
97  * Serializable classes that require special handling during the
98  * serialization and deserialization process should implement both
99  * of these methods:<p>
100  *
101  * <PRE>
102  * private void writeObject(java.io.ObjectOutputStream stream)
103  *     throws IOException;
104  * private void readObject(java.io.ObjectInputStream stream)
105  *     throws IOException, ClassNotFoundException;
106  * </PRE><p>
107  *
108  * The readObject method is responsible for reading and restoring the
109  * state of the object for its particular class using data written to
110  * the stream by the corresponding writeObject method.  The method
111  * does not need to concern itself with the state belonging to its
112  * superclasses or subclasses.  State is restored by reading data from
113  * the ObjectInputStream for the individual fields and making
114  * assignments to the appropriate fields of the object.  Reading
115  * primitive data types is supported by DataInput. <p>
116  *
117  * Serialization does not read or assign values to the fields of any
118  * object that does not implement the java.io.Serializable interface.
119  * Subclasses of Objects that are not serializable can be
120  * serializable. In this case the non-serializable class must have an
121  * accessible no-arg constructor to allow its fields to be initialized.
122  * In this case it is the responsibility of the subclass to save and restore
123  * the state of the non-serializable class. It is frequently the case that
124  * the fields of that class are accessible (public, package, or
125  * protected) or that there are get and set methods that can be used
126  * to restore the state. <p>
127  *
128  * Implementing the Externalizable interface allows the object to
129  * assume complete control over the contents and format of the object's
130  * serialized form.  The methods of the Externalizable interface,
131  * writeExternal and readExternal, are called to save and restore the
132  * objects state.  When implemented by a class they can write and read
133  * their own state using all of the methods of ObjectOutput and
134  * ObjectInput.  It is the responsibility of the objects to handle any
135  * versioning that occurs.
136  *
137  * @author  Joe Fialli
138  *
139  * @see java.io.ObjectInputStream
140  * @see java.io.DataInput
141  * @see java.io.Serializable
142  * @see java.io.Externalizable
143  * @see java.io.ext.AbstractObjectOutputStream
144  * @since   JDK1.2
145  */
146 abstract public class AbstractObjectInputStream extends ObjectInputStream
147 {
148     protected InputStream in;
149     /**
150      * Create an ObjectInputStream that reads from the specified InputStream.<p>
151      *
152      * Add the following line to the security policy file to enable
153      * subclassing.
154      *
155      * <PRE>
156      *     permission SerializablePermission "enableAbstractSubclass" ;
157      * </PRE><p>
158      *
159      * @exception StreamCorruptedException The version or magic number are incorrect.
160      * @exception IOException An exception occurred in the underlying stream.
161      * @exception SecurityException if subclass does not have SerializablePermiision
162      *            "enableAbstractSubclass".
163      */
AbstractObjectInputStream(InputStream in)164     public AbstractObjectInputStream(InputStream in)
165         throws IOException, StreamCorruptedException
166         {
167             this.in = in;
168         }
169 
close()170     abstract public void close() throws IOException;
171 
172     /***************************************************************/
173     /* Read an object from the stream. */
174 
175     /**
176      * Read an object from the ObjectInputStream.<p>
177      *
178      * NOTE: The override method of this class should have the modifier final.<p>
179      *
180      * Default deserializing for a class can be
181      * overriden by defining a readObject method for the Serializable class.
182      * Objects referenced by this object are read transitively so
183      * that a complete equivalent graph of objects is reconstructed by
184      * readObject. <p>
185      *
186      * The root object is completely restored when all of its fields
187      * and the objects it references are completely restored. At this
188      * point the object validation callbacks are executed in order
189      * based on their registered priorities. The callbacks are
190      * registered by objects (in the readObject special methods)
191      * as they are individually restored. <p>
192      *
193      * For security's sake, any overrides of this method should be final.
194      * Serialization typically needs to disable java access rules
195      * to serialize private, protected and package accessible Serializable
196      * fields. This method gets called for ALL Serializable objects.
197      *
198      * @exception java.lang.ClassNotFoundException Class of a serialized object
199      *      cannot be found.
200      * @exception InvalidClassException Something is wrong with a class used by
201      *     serialization.
202      * @exception StreamCorruptedException Control information in the
203      *     stream is inconsistent.
204      * @exception OptionalDataException Primitive data was found in the
205      * stream instead of objects.
206      * @exception IOException Any of the usual Input/Output related exceptions.
207      *
208      * @see java.io.ObjectInputStream#resolveObject(Object)
209      * @see java.io.Resolvable
210      * @see java.io.Externalizable
211      * @see java.io.ObjectInputValidation
212      * @see #registerValidation(ObjectInputValidation, int)
213      * @see java.io.ObjectInputStream#resolveClass(ObjectStreamClass)
214      */
readObjectOverride()215     protected Object readObjectOverride()
216         throws OptionalDataException, ClassNotFoundException, IOException {
217             return null;
218     }
219 
220     /**
221      * Read the Serializable fields of the current object from this stream.<p>
222      *
223      * Note: The object being deserialized is not passed to this method.
224      *       For security purposes, the initial implementation maintained
225      *       the state of the last object to be read by readObject
226      *       only allowed this method to be invoked for this object.<p>
227      *
228      * @exception NotActiveException  Thrown if a readObject method is not
229      *                                active.
230      * @exception ClassNotFoundException if no corresponding local class can be
231      *                                   found in the local JVM.
232      */
defaultReadObject()233     abstract public void defaultReadObject()
234         throws IOException, ClassNotFoundException, NotActiveException;
235 
236     /**
237      * Enable allocation for subclass reimplementing serialization.<p>
238      *
239      * Note: Default allocation does not have the java access priviledges
240      * to invoke package and protected constructors.<p>
241      *
242      * Security alert: this JVM native method is private within ObjectInputStream; however,
243      *                 it was anticipated that re-implementors of serialization would need
244      *                 access to this method. Is this allocator considered a security problem? <p>
245      *
246      * @param ctorClass  is the same class or a superclass of <STRONG>ofClass</STRONG>
247      * @param ofClass    the type of the object to allocate.
248      * @return   an object of <STRONG>ofClass</STRONG> type.
249      *
250      * @exception IllegalAccessException if no-arg constructor of
251      *            <STRONG>ctorClass</STRONG> is not accessible from
252      *            <STRONG>ofClass</STRONG>.
253      * @exception InstantiationException  TBD.
254      */
255     final protected native Object
allocateNewObject(Class ofClass, Class ctorClass)256         allocateNewObject(Class ofClass, Class ctorClass)
257         throws InstantiationException, IllegalAccessException;
258 
259     /**
260      * Enable allocation for subclass reimplementing serialization.<p>
261      *
262      * Note: Default allocation does not have the java access priviledges
263      * to invoke package and protected constructors.<p>
264      *
265      * Security alert: this JVM native method is private within ObjectInputStream; however,
266      *                 it was anticipated that re-implementors of serialization would need
267      *                 access to this method. Is this allocator considered a security problem?<p>
268      *
269      *
270      * @exception IllegalAccessException  TBD.
271      * @exception InstantiationException  TBD.
272      */
273     final protected native Object
allocateNewArray(Class componentClass, int length)274         allocateNewArray(Class componentClass, int length)
275         throws InstantiationException, IllegalAccessException;
276 
277     /**
278      * Reads the Serializable fields from the stream into a buffer
279      * and makes the fields available by name.
280      *
281      * @exception java.lang.ClassNotFoundException if the class of a serialized
282      *              object could not be found.
283      * @exception IOException        if an I/O error occurs.
284      * @exception NotActiveException if readObject() is not currently active.
285      */
readFields()286     abstract public ObjectInputStream.GetField readFields()
287         throws IOException, ClassNotFoundException, NotActiveException;
288 
enableResolveObject(boolean enable)289     abstract protected boolean enableResolveObject(boolean enable) throws SecurityException;
290 
registerValidation(ObjectInputValidation obj, int prio)291     abstract public void registerValidation(ObjectInputValidation obj,
292                                             int prio)
293         throws NotActiveException, InvalidObjectException;
294 
295 
296     /****************************************************************/
297 
298     /* Use DataInput methods to read primitive data from the stream. */
299 
read()300     abstract public int read() throws IOException;
read(byte[] data, int offset, int length)301     abstract public int read(byte[] data, int offset, int length)
302         throws IOException;
readBoolean()303     abstract public boolean readBoolean() throws IOException;
readByte()304     abstract public byte readByte() throws IOException;
readUnsignedByte()305     abstract public int readUnsignedByte()  throws IOException;
readShort()306     abstract public short readShort()  throws IOException;
readUnsignedShort()307     abstract public int readUnsignedShort() throws IOException;
readChar()308     abstract public char readChar()  throws IOException;
readInt()309     abstract public int readInt()  throws IOException;
readLong()310     abstract public long readLong()  throws IOException;
readFloat()311     abstract public float readFloat() throws IOException;
readDouble()312     abstract public double readDouble() throws IOException;
readFully(byte[] data)313     abstract public void readFully(byte[] data) throws IOException;
readFully(byte[] data, int offset, int size)314     abstract public void readFully(byte[] data, int offset, int size) throws IOException;
readUTF()315     abstract public String readUTF() throws IOException;
available()316     abstract public int available() throws IOException;
skipBytes(int len)317     abstract public int skipBytes(int len) throws IOException;
318 
319     /* @deprecated */
readLine()320     abstract public String readLine() throws IOException;
321 };
322