# HG changeset patch # User skoppar # Date 1285393334 25200 # Node ID b2fff4b7e8cd52db94377205b77eb6c30cee0fb4 # Parent cc67fdc4fee9a5b25caee4e71b51a8ff24ae7d1a 6891766: Vulnerabilities in use of reflection in CORBA Reviewed-by: hawtin diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java --- a/src/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Fri Sep 24 16:38:05 2010 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2721 +0,0 @@ -/* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -/* - * Licensed Materials - Property of IBM - * RMI-IIOP v1.0 - * Copyright IBM Corp. 1998 1999 All Rights Reserved - * - */ - -package com.sun.corba.se.impl.io; - -import java.io.InputStream; -import java.io.IOException; -import java.io.StreamCorruptedException; -import java.io.ObjectInputValidation; -import java.io.NotActiveException; -import java.io.InvalidObjectException; -import java.io.InvalidClassException; -import java.io.DataInputStream; -import java.io.OptionalDataException; -import java.io.WriteAbortedException; -import java.io.Externalizable; -import java.io.EOFException; -import java.lang.reflect.*; -import java.util.Vector; -import java.util.Stack; -import java.util.Hashtable; -import java.util.Enumeration; - -import sun.corba.Bridge ; - -import java.security.AccessController ; -import java.security.PrivilegedAction ; - -import com.sun.corba.se.impl.io.ObjectStreamClass; -import com.sun.corba.se.impl.util.Utility; - -import org.omg.CORBA.portable.ValueInputStream; - -import org.omg.CORBA.ValueMember; -import org.omg.CORBA.SystemException; -import org.omg.CORBA.TCKind; -import org.omg.CORBA.ORB; -import org.omg.CORBA.CompletionStatus; -import org.omg.CORBA.portable.IndirectionException; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.TypeCode; - -import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription; -import com.sun.org.omg.SendingContext.CodeBase; - -import javax.rmi.PortableRemoteObject; -import javax.rmi.CORBA.Util; -import javax.rmi.CORBA.ValueHandler; - -import java.security.*; -import java.util.*; - -import com.sun.corba.se.impl.orbutil.ObjectUtility ; -import com.sun.corba.se.impl.logging.OMGSystemException ; -import com.sun.corba.se.impl.logging.UtilSystemException ; - -import com.sun.corba.se.spi.logging.CORBALogDomains ; - -/** - * IIOPInputStream is used by the ValueHandlerImpl to handle Java serialization - * input semantics. - * - * @author Stephen Lewallen - * @since JDK1.1.6 - */ - -public class IIOPInputStream - extends com.sun.corba.se.impl.io.InputStreamHook -{ - private static Bridge bridge = - (Bridge)AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - return Bridge.get() ; - } - } - ) ; - - private static OMGSystemException omgWrapper = OMGSystemException.get( - CORBALogDomains.RPC_ENCODING ) ; - private static UtilSystemException utilWrapper = UtilSystemException.get( - CORBALogDomains.RPC_ENCODING ) ; - - // Necessary to pass the appropriate fields into the - // defaultReadObjectDelegate method (which takes no - // parameters since it's called from - // java.io.ObjectInpuStream defaultReadObject() - // which we can't change). - // - // This is only used in the case where the fields had - // to be obtained remotely because of a serializable - // version difference. Set in inputObjectUsingFVD. - // Part of serialization evolution fixes for Ladybird, - // bug 4365188. - private ValueMember defaultReadObjectFVDMembers[] = null; - - private org.omg.CORBA_2_3.portable.InputStream orbStream; - - private CodeBase cbSender; - - private ValueHandlerImpl vhandler; //d4365188 - - private Object currentObject = null; - - private ObjectStreamClass currentClassDesc = null; - - private Class currentClass = null; - - private int recursionDepth = 0; - - private int simpleReadDepth = 0; - - // The ActiveRecursionManager replaces the old RecursionManager which - // used to record how many recursions were made, and resolve them after - // an object was completely deserialized. - // - // That created problems (as in bug 4414154) because when custom - // unmarshaling in readObject, there can be recursive references - // to one of the objects currently being unmarshaled, and the - // passive recursion system failed. - ActiveRecursionManager activeRecursionMgr = new ActiveRecursionManager(); - - private IOException abortIOException = null; - - /* Remember the first exception that stopped this stream. */ - private ClassNotFoundException abortClassNotFoundException = null; - - /* Vector of validation callback objects - * The vector is created as needed. The vector is maintained in - * order of highest (first) priority to lowest - */ - private Vector callbacks; - - // Serialization machinery fields - /* Arrays used to keep track of classes and ObjectStreamClasses - * as they are being merged; used in inputObject. - * spClass is the stack pointer for both. */ - ObjectStreamClass[] classdesc; - Class[] classes; - int spClass; - - private static final String kEmptyStr = ""; - - // TCKind TypeCodes used in FVD inputClassFields - //public static final TypeCode kRemoteTypeCode = new TypeCodeImpl(TCKind._tk_objref); - //public static final TypeCode kValueTypeCode = new TypeCodeImpl(TCKind._tk_value); - // removed TypeCodeImpl dependency - public static final TypeCode kRemoteTypeCode = ORB.init().get_primitive_tc(TCKind.tk_objref); - public static final TypeCode kValueTypeCode = ORB.init().get_primitive_tc(TCKind.tk_value); - - // TESTING CODE - useFVDOnly should be made final before FCS in order to - // optimize out the check. - private static final boolean useFVDOnly = false; - - private byte streamFormatVersion; - - // Since java.io.OptionalDataException's constructors are - // package private, but we need to throw it in some special - // cases, we try to do it by reflection. - private static final Constructor OPT_DATA_EXCEPTION_CTOR; - - private Object[] readObjectArgList = { this } ; - - static { - OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor(); - } - - // Grab the OptionalDataException boolean ctor and make - // it accessible. Note that any exceptions - // will be wrapped in ExceptionInInitializerErrors. - private static Constructor getOptDataExceptionCtor() { - - try { - - Constructor result = - - (Constructor) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public java.lang.Object run() - throws NoSuchMethodException, - SecurityException { - - Constructor boolCtor - = OptionalDataException.class.getDeclaredConstructor( - new Class[] { - Boolean.TYPE }); - - boolCtor.setAccessible(true); - - return boolCtor; - }}); - - if (result == null) - // XXX I18N, logging needed. - throw new Error("Unable to find OptionalDataException constructor"); - - return result; - - } catch (Exception ex) { - // XXX I18N, logging needed. - throw new ExceptionInInitializerError(ex); - } - } - - // Create a new OptionalDataException with the EOF marker - // set to true. See handleOptionalDataMarshalException. - private OptionalDataException createOptionalDataException() { - try { - OptionalDataException result - = (OptionalDataException) - OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] { - Boolean.TRUE }); - - if (result == null) - // XXX I18N, logging needed. - throw new Error("Created null OptionalDataException"); - - return result; - - } catch (Exception ex) { - // XXX I18N, logging needed. - throw new Error("Couldn't create OptionalDataException", ex); - } - } - - // Return the stream format version currently being used - // to deserialize an object - protected byte getStreamFormatVersion() { - return streamFormatVersion; - } - - // At the beginning of data sent by a writeObject or - // writeExternal method there is a byte telling the - // reader the stream format version. - private void readFormatVersion() throws IOException { - - streamFormatVersion = orbStream.read_octet(); - - if (streamFormatVersion < 1 || - streamFormatVersion > vhandler.getMaximumStreamFormatVersion()) { - SystemException sysex = omgWrapper.unsupportedFormatVersion( - CompletionStatus.COMPLETED_MAYBE); - // XXX I18N? Logging for IOException? - IOException result = new IOException("Unsupported format version: " - + streamFormatVersion); - result.initCause( sysex ) ; - throw result ; - } - - if (streamFormatVersion == 2) { - if (!(orbStream instanceof ValueInputStream)) { - SystemException sysex = omgWrapper.notAValueinputstream( - CompletionStatus.COMPLETED_MAYBE); - // XXX I18N? Logging for IOException? - IOException result = new IOException("Not a ValueInputStream"); - result.initCause( sysex ) ; - throw result; - } - } - } - - public static void setTestFVDFlag(boolean val){ - // useFVDOnly = val; - } - - /** - * Dummy constructor; passes upper stream a dummy stream; - **/ - public IIOPInputStream() - throws java.io.IOException { - super(); - resetStream(); - } - - public final void setOrbStream(org.omg.CORBA_2_3.portable.InputStream os) { - orbStream = os; - } - - public final org.omg.CORBA_2_3.portable.InputStream getOrbStream() { - return orbStream; - } - - //added setSender and getSender - public final void setSender(CodeBase cb) { - cbSender = cb; - } - - public final CodeBase getSender() { - return cbSender; - } - - // 4365188 this is added to enable backward compatability w/ wrong - // rep-ids - public final void setValueHandler(ValueHandler vh) { - vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh; - } - - public final ValueHandler getValueHandler() { - return (javax.rmi.CORBA.ValueHandler) vhandler; - } - - public final void increaseRecursionDepth(){ - recursionDepth++; - } - - public final int decreaseRecursionDepth(){ - return --recursionDepth; - } - - /** - * Override the actions of the final method "readObject()" - * in ObjectInputStream. - * @since JDK1.1.6 - * - * Read an object from the ObjectInputStream. - * The class of the object, the signature of the class, and the values - * of the non-transient and non-static fields of the class and all - * of its supertypes are read. Default deserializing for a class can be - * overriden using the writeObject and readObject methods. - * Objects referenced by this object are read transitively so - * that a complete equivalent graph of objects is reconstructed by readObject.

- * - * The root object is completly restored when all of its fields - * and the objects it references are completely restored. At this - * point the object validation callbacks are executed in order - * based on their registered priorities. The callbacks are - * registered by objects (in the readObject special methods) - * as they are individually restored. - * - * Exceptions are thrown for problems with the InputStream and for classes - * that should not be deserialized. All exceptions are fatal to the - * InputStream and leave it in an indeterminate state; it is up to the caller - * to ignore or recover the stream state. - * @exception java.lang.ClassNotFoundException Class of a serialized object - * cannot be found. - * @exception InvalidClassException Something is wrong with a class used by - * serialization. - * @exception StreamCorruptedException Control information in the - * stream is inconsistent. - * @exception OptionalDataException Primitive data was found in the - * stream instead of objects. - * @exception IOException Any of the usual Input/Output related exceptions. - * @since JDK1.1 - */ - public final Object readObjectDelegate() throws IOException - { - try { - - readObjectState.readData(this); - - return orbStream.read_abstract_interface(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, true); - throw marshalException; - } catch(IndirectionException cdrie) - { - // The CDR stream had never seen the given offset before, - // so check the recursion manager (it will throw an - // IOException if it doesn't have a reference, either). - return activeRecursionMgr.getObject(cdrie.offset); - } - } - - final Object simpleReadObject(Class clz, - String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender, - int offset) - /* throws OptionalDataException, ClassNotFoundException, IOException */ - { - - /* Save the current state and get ready to read an object. */ - Object prevObject = currentObject; - ObjectStreamClass prevClassDesc = currentClassDesc; - Class prevClass = currentClass; - byte oldStreamFormatVersion = streamFormatVersion; - - simpleReadDepth++; // Entering - Object obj = null; - - /* - * Check for reset, handle it before reading an object. - */ - try { - // d4365188: backward compatability - if (vhandler.useFullValueDescription(clz, repositoryID)) { - obj = inputObjectUsingFVD(clz, repositoryID, sender, offset); - } else { - obj = inputObject(clz, repositoryID, sender, offset); - } - - obj = currentClassDesc.readResolve(obj); - } - catch(ClassNotFoundException cnfe) - { - bridge.throwException( cnfe ) ; - return null; - } - catch(IOException ioe) - { - // System.out.println("CLZ = " + clz + "; " + ioe.toString()); - bridge.throwException(ioe) ; - return null; - } - finally { - simpleReadDepth --; - currentObject = prevObject; - currentClassDesc = prevClassDesc; - currentClass = prevClass; - streamFormatVersion = oldStreamFormatVersion; - } - - - /* Check for thrown exceptions and re-throw them, clearing them if - * this is the last recursive call . - */ - IOException exIOE = abortIOException; - if (simpleReadDepth == 0) - abortIOException = null; - if (exIOE != null){ - bridge.throwException( exIOE ) ; - return null; - } - - - ClassNotFoundException exCNF = abortClassNotFoundException; - if (simpleReadDepth == 0) - abortClassNotFoundException = null; - if (exCNF != null) { - bridge.throwException( exCNF ) ; - return null; - } - - return obj; - } - - public final void simpleSkipObject(String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender) - /* throws OptionalDataException, ClassNotFoundException, IOException */ - { - - /* Save the current state and get ready to read an object. */ - Object prevObject = currentObject; - ObjectStreamClass prevClassDesc = currentClassDesc; - Class prevClass = currentClass; - byte oldStreamFormatVersion = streamFormatVersion; - - simpleReadDepth++; // Entering - Object obj = null; - - /* - * Check for reset, handle it before reading an object. - */ - try { - skipObjectUsingFVD(repositoryID, sender); - } - catch(ClassNotFoundException cnfe) - { - bridge.throwException( cnfe ) ; - return; - } - catch(IOException ioe) - { - bridge.throwException( ioe ) ; - return; - } - finally { - simpleReadDepth --; - streamFormatVersion = oldStreamFormatVersion; - currentObject = prevObject; - currentClassDesc = prevClassDesc; - currentClass = prevClass; - } - - - /* Check for thrown exceptions and re-throw them, clearing them if - * this is the last recursive call . - */ - IOException exIOE = abortIOException; - if (simpleReadDepth == 0) - abortIOException = null; - if (exIOE != null){ - bridge.throwException( exIOE ) ; - return; - } - - - ClassNotFoundException exCNF = abortClassNotFoundException; - if (simpleReadDepth == 0) - abortClassNotFoundException = null; - if (exCNF != null) { - bridge.throwException( exCNF ) ; - return; - } - - return; - } - ///////////////// - - /** - * This method is called by trusted subclasses of ObjectOutputStream - * that constructed ObjectOutputStream using the - * protected no-arg constructor. The subclass is expected to provide - * an override method with the modifier "final". - * - * @return the Object read from the stream. - * - * @see #ObjectInputStream() - * @see #readObject - * @since JDK 1.2 - */ - protected final Object readObjectOverride() - throws OptionalDataException, ClassNotFoundException, IOException - { - return readObjectDelegate(); - } - - /** - * Override the actions of the final method "defaultReadObject()" - * in ObjectInputStream. - * @since JDK1.1.6 - * - * Read the non-static and non-transient fields of the current class - * from this stream. This may only be called from the readObject method - * of the class being deserialized. It will throw the NotActiveException - * if it is called otherwise. - * - * @exception java.lang.ClassNotFoundException if the class of a serialized - * object could not be found. - * @exception IOException if an I/O error occurs. - * @exception NotActiveException if the stream is not currently reading - * objects. - * @since JDK1.1 - */ - public final void defaultReadObjectDelegate() - /* throws IOException, ClassNotFoundException, NotActiveException */ - { - try { - if (currentObject == null || currentClassDesc == null) - // XXX I18N, logging needed. - throw new NotActiveException("defaultReadObjectDelegate"); - - // The array will be null unless fields were retrieved - // remotely because of a serializable version difference. - // Bug fix for 4365188. See the definition of - // defaultReadObjectFVDMembers for more information. - if (defaultReadObjectFVDMembers != null && - defaultReadObjectFVDMembers.length > 0) { - - // WARNING: Be very careful! What if some of - // these fields actually have to do this, too? - // This works because the defaultReadObjectFVDMembers - // reference is passed to inputClassFields, but - // there is no guarantee that - // defaultReadObjectFVDMembers will point to the - // same array after calling inputClassFields. - - // Use the remote fields to unmarshal. - inputClassFields(currentObject, - currentClass, - currentClassDesc, - defaultReadObjectFVDMembers, - cbSender); - - } else { - - // Use the local fields to unmarshal. - ObjectStreamField[] fields = - currentClassDesc.getFieldsNoCopy(); - if (fields.length > 0) { - inputClassFields(currentObject, currentClass, fields, cbSender); - } - } - } - catch(NotActiveException nae) - { - bridge.throwException( nae ) ; - } - catch(IOException ioe) - { - bridge.throwException( ioe ) ; - } - catch(ClassNotFoundException cnfe) - { - bridge.throwException( cnfe ) ; - } - - } - - /** - * Override the actions of the final method "enableResolveObject()" - * in ObjectInputStream. - * @since JDK1.1.6 - * - * Enable the stream to allow objects read from the stream to be replaced. - * If the stream is a trusted class it is allowed to enable replacment. - * Trusted classes are those classes with a classLoader equals null.

- * - * When enabled the resolveObject method is called for every object - * being deserialized. - * - * @exception SecurityException The classloader of this stream object is non-null. - * @since JDK1.1 - */ - public final boolean enableResolveObjectDelegate(boolean enable) - /* throws SecurityException */ - { - return false; - } - - // The following three methods allow the implementing orbStream - // to provide mark/reset behavior as defined in java.io.InputStream. - - public final void mark(int readAheadLimit) { - orbStream.mark(readAheadLimit); - } - - public final boolean markSupported() { - return orbStream.markSupported(); - } - - public final void reset() throws IOException { - try { - orbStream.reset(); - } catch (Error e) { - IOException err = new IOException(e.getMessage()); - err.initCause(e) ; - throw err ; - } - } - - public final int available() throws IOException{ - return 0; // unreliable - } - - public final void close() throws IOException{ - // no op - } - - public final int read() throws IOException{ - try{ - readObjectState.readData(this); - - return (orbStream.read_octet() << 0) & 0x000000FF; - } catch (MARSHAL marshalException) { - if (marshalException.minor - == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) { - setState(IN_READ_OBJECT_NO_MORE_OPT_DATA); - return -1; - } - - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e) ; - throw exc ; - } - } - - public final int read(byte data[], int offset, int length) throws IOException{ - try{ - readObjectState.readData(this); - - orbStream.read_octet_array(data, offset, length); - return length; - } catch (MARSHAL marshalException) { - if (marshalException.minor - == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) { - setState(IN_READ_OBJECT_NO_MORE_OPT_DATA); - return -1; - } - - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e) ; - throw exc ; - } - - } - - public final boolean readBoolean() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_boolean(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final byte readByte() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_octet(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final char readChar() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_wchar(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final double readDouble() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_double(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final float readFloat() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_float(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final void readFully(byte data[]) throws IOException{ -// d11623 : implement readFully, required for serializing some core classes - - readFully(data, 0, data.length); - } - - public final void readFully(byte data[], int offset, int size) throws IOException{ -// d11623 : implement readFully, required for serializing some core classes - try{ - readObjectState.readData(this); - - orbStream.read_octet_array(data, offset, size); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final int readInt() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_long(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final String readLine() throws IOException{ - // XXX I18N, logging needed. - throw new IOException("Method readLine not supported"); - } - - public final long readLong() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_longlong(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final short readShort() throws IOException{ - try{ - readObjectState.readData(this); - - return orbStream.read_short(); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - protected final void readStreamHeader() throws IOException, StreamCorruptedException{ - // no op - } - - public final int readUnsignedByte() throws IOException{ - try{ - readObjectState.readData(this); - - return (orbStream.read_octet() << 0) & 0x000000FF; - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - public final int readUnsignedShort() throws IOException{ - try{ - readObjectState.readData(this); - - return (orbStream.read_ushort() << 0) & 0x0000FFFF; - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - /** - * Helper method for correcting the Kestrel bug 4367783 (dealing - * with larger than 8-bit chars). The old behavior is preserved - * in orbutil.IIOPInputStream_1_3 in order to interoperate with - * our legacy ORBs. - */ - protected String internalReadUTF(org.omg.CORBA.portable.InputStream stream) - { - return stream.read_wstring(); - } - - public final String readUTF() throws IOException{ - try{ - readObjectState.readData(this); - - return internalReadUTF(orbStream); - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e); - throw exc ; - } - } - - // If the ORB stream detects an incompatibility between what's - // on the wire and what our Serializable's readObject wants, - // it throws a MARSHAL exception with a specific minor code. - // This is rethrown to the readObject as an OptionalDataException. - // So far in RMI-IIOP, this process isn't specific enough to - // tell the readObject how much data is available, so we always - // set the OptionalDataException's EOF marker to true. - private void handleOptionalDataMarshalException(MARSHAL marshalException, - boolean objectRead) - throws IOException { - - // Java Object Serialization spec 3.4: "If the readObject method - // of the class attempts to read more data than is present in the - // optional part of the stream for this class, the stream will - // return -1 for bytewise reads, throw an EOFException for - // primitive data reads, or throw an OptionalDataException - // with the eof field set to true for object reads." - if (marshalException.minor - == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) { - - IOException result; - - if (!objectRead) - result = new EOFException("No more optional data"); - else - result = createOptionalDataException(); - - result.initCause(marshalException); - - setState(IN_READ_OBJECT_NO_MORE_OPT_DATA); - - throw result; - } - } - - public final synchronized void registerValidation(ObjectInputValidation obj, - int prio) - throws NotActiveException, InvalidObjectException{ - // XXX I18N, logging needed. - throw new Error("Method registerValidation not supported"); - } - - protected final Class resolveClass(ObjectStreamClass v) - throws IOException, ClassNotFoundException{ - // XXX I18N, logging needed. - throw new IOException("Method resolveClass not supported"); - } - - protected final Object resolveObject(Object obj) throws IOException{ - // XXX I18N, logging needed. - throw new IOException("Method resolveObject not supported"); - } - - public final int skipBytes(int len) throws IOException{ - try{ - readObjectState.readData(this); - - byte buf[] = new byte[len]; - orbStream.read_octet_array(buf, 0, len); - return len; - } catch (MARSHAL marshalException) { - handleOptionalDataMarshalException(marshalException, false); - - throw marshalException; - } catch(Error e) { - IOException exc = new IOException(e.getMessage()); - exc.initCause(e) ; - throw exc ; - } - } - - private Object inputObject(Class clz, - String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender, - int offset) - throws IOException, ClassNotFoundException - { - - /* - * Get the descriptor and then class of the incoming object. - */ - - currentClassDesc = ObjectStreamClass.lookup(clz); - currentClass = currentClassDesc.forClass(); - //currentClassDesc.setClass(currentClass); - if (currentClass == null) - // XXX I18N, logging needed. - throw new ClassNotFoundException(currentClassDesc.getName()); - - try { - /* If Externalizable, - * Create an instance and tell it to read its data. - * else, - * Handle it as a serializable class. - */ - if (currentClassDesc.isExternalizable()) { - try { - currentObject = (currentClass == null) ? - null : currentClassDesc.newInstance(); - if (currentObject != null) { - - // Store this object and its beginning position - // since there might be indirections to it while - // it's been unmarshalled. - activeRecursionMgr.addObject(offset, currentObject); - - // Read format version - readFormatVersion(); - - Externalizable ext = (Externalizable)currentObject; - ext.readExternal(this); - } - } catch (InvocationTargetException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InvocationTargetException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (UnsupportedOperationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "UnsupportedOperationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (InstantiationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InstantiationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } - } // end : if (currentClassDesc.isExternalizable()) - else { - /* Count number of classes and descriptors we might have - * to work on. - */ - - ObjectStreamClass currdesc = currentClassDesc; - Class currclass = currentClass; - - int spBase = spClass; // current top of stack - - /* The object's classes should be processed from supertype to subtype - * Push all the clases of the current object onto a stack. - * Note that only the serializable classes are represented - * in the descriptor list. - * - * Handle versioning where one or more supertypes of - * have been inserted or removed. The stack will - * contain pairs of descriptors and the corresponding - * class. If the object has a class that did not occur in - * the original the descriptor will be null. If the - * original object had a descriptor for a class not - * present in the local hierarchy of the object the class will be - * null. - * - */ - - /* - * This is your basic diff pattern, made simpler - * because reordering is not allowed. - */ - // sun.4296963 ibm.11861 - // d11861 we should stop when we find the highest serializable class - // We need this so that when we allocate the new object below, we - // can call the constructor of the non-serializable superclass. - // Note that in the JRMP variant of this code the - // ObjectStreamClass.lookup() method handles this, but we've put - // this fix here rather than change lookup because the new behaviour - // is needed in other cases. - - for (currdesc = currentClassDesc, currclass = currentClass; - currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/ - currdesc = currdesc.getSuperclass()) { - - /* - * Search the classes to see if the class of this - * descriptor appears further up the hierarchy. Until - * it's found assume its an inserted class. If it's - * not found, its the descriptor's class that has been - * removed. - */ - Class cc = currdesc.forClass(); - Class cl; - for (cl = currclass; cl != null; cl = cl.getSuperclass()) { - if (cc == cl) { - // found a superclass that matches this descriptor - break; - } else { - /* Ignore a class that doesn't match. No - * action is needed since it is already - * initialized. - */ - } - } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass()) - /* Test if there is room for this new entry. - * If not, double the size of the arrays and copy the contents. - */ - spClass++; - if (spClass >= classes.length) { - int newlen = classes.length * 2; - Class[] newclasses = new Class[newlen]; - ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen]; - - System.arraycopy(classes, 0, - newclasses, 0, - classes.length); - System.arraycopy(classdesc, 0, - newclassdesc, 0, - classes.length); - - classes = newclasses; - classdesc = newclassdesc; - } - - if (cl == null) { - /* Class not found corresponding to this descriptor. - * Pop off all the extra classes pushed. - * Push the descriptor and a null class. - */ - classdesc[spClass] = currdesc; - classes[spClass] = null; - } else { - /* Current class descriptor matches current class. - * Some classes may have been inserted. - * Record the match and advance the class, continue - * with the next descriptor. - */ - classdesc[spClass] = currdesc; - classes[spClass] = cl; - currclass = cl.getSuperclass(); - } - } // end : for (currdesc = currentClassDesc, currclass = currentClass; - - /* Allocate a new object. The object is only constructed - * above the highest serializable class and is set to - * default values for all more specialized classes. - */ - try { - currentObject = (currentClass == null) ? - null : currentClassDesc.newInstance() ; - - // Store this object and its beginning position - // since there might be indirections to it while - // it's been unmarshalled. - activeRecursionMgr.addObject(offset, currentObject); - } catch (InvocationTargetException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InvocationTargetException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (UnsupportedOperationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "UnsupportedOperationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (InstantiationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InstantiationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } - - /* - * For all the pushed descriptors and classes. - * if the class has its own writeObject and readObject methods - * call the readObject method - * else - * invoke the defaultReadObject method - */ - try { - for (spClass = spClass; spClass > spBase; spClass--) { - /* - * Set current descriptor and corresponding class - */ - currentClassDesc = classdesc[spClass]; - currentClass = classes[spClass]; - if (classes[spClass] != null) { - /* Read the data from the stream described by the - * descriptor and store into the matching class. - */ - - ReadObjectState oldState = readObjectState; - setState(DEFAULT_STATE); - - try { - - // Changed since invokeObjectReader no longer does this. - if (currentClassDesc.hasWriteObject()) { - - // Read format version - readFormatVersion(); - - // Read defaultWriteObject indicator - boolean calledDefaultWriteObject = readBoolean(); - - readObjectState.beginUnmarshalCustomValue(this, - calledDefaultWriteObject, - (currentClassDesc.readObjectMethod - != null)); - } else { - if (currentClassDesc.hasReadObject()) - setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED); - } - - if (!invokeObjectReader(currentClassDesc, currentObject, currentClass) || - readObjectState == IN_READ_OBJECT_DEFAULTS_SENT) { - - // Error case of no readObject and didn't call - // defaultWriteObject handled in default state - - ObjectStreamField[] fields = - currentClassDesc.getFieldsNoCopy(); - if (fields.length > 0) { - inputClassFields(currentObject, currentClass, fields, sender); - } - } - - if (currentClassDesc.hasWriteObject()) - readObjectState.endUnmarshalCustomValue(this); - - } finally { - setState(oldState); - } - - } else { - - // _REVISIT_ : Can we ever get here? - /* No local class for this descriptor, - * Skip over the data for this class. - * like defaultReadObject with a null currentObject. - * The code will read the values but discard them. - */ - ObjectStreamField[] fields = - currentClassDesc.getFieldsNoCopy(); - if (fields.length > 0) { - inputClassFields(null, currentClass, fields, sender); - } - - } - - } - } finally { - // Make sure we exit at the same stack level as when we started. - spClass = spBase; - } - } - } finally { - // We've completed deserializing this object. Any - // future indirections will be handled correctly at the - // CDR level. The ActiveRecursionManager only deals with - // objects currently being deserialized. - activeRecursionMgr.removeObject(offset); - } - - return currentObject; - } - - // This retrieves a vector of FVD's for the hierarchy of serializable classes stemming from - // repositoryID. It is assumed that the sender will not provide base_value id's for non-serializable - // classes! - private Vector getOrderedDescriptions(String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender) { - Vector descs = new Vector(); - - if (sender == null) { - return descs; - } - - FullValueDescription aFVD = sender.meta(repositoryID); - while (aFVD != null) { - descs.insertElementAt(aFVD, 0); - if ((aFVD.base_value != null) && !kEmptyStr.equals(aFVD.base_value)) { - aFVD = sender.meta(aFVD.base_value); - } - else return descs; - } - - return descs; - } - - /** - * This input method uses FullValueDescriptions retrieved from the sender's runtime to - * read in the data. This method is capable of throwing out data not applicable to client's fields. - * This method handles instances where the reader has a class not sent by the sender, the sender sent - * a class not present on the reader, and/or the reader's class does not match the sender's class. - * - * NOTE : If the local description indicates custom marshaling and the remote type's FVD also - * indicates custom marsahling than the local type is used to read the data off the wire. However, - * if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is - * a form of custom marshaling. - * - */ - private Object inputObjectUsingFVD(Class clz, - String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender, - int offset) - throws IOException, ClassNotFoundException - { - int spBase = spClass; // current top of stack - try{ - - /* - * Get the descriptor and then class of the incoming object. - */ - - ObjectStreamClass currdesc = currentClassDesc = ObjectStreamClass.lookup(clz); - Class currclass = currentClass = clz; - - /* If Externalizable, - * Create an instance and tell it to read its data. - * else, - * Handle it as a serializable class. - */ - if (currentClassDesc.isExternalizable()) { - try { - currentObject = (currentClass == null) ? - null : currentClassDesc.newInstance(); - if (currentObject != null) { - // Store this object and its beginning position - // since there might be indirections to it while - // it's been unmarshalled. - activeRecursionMgr.addObject(offset, currentObject); - - // Read format version - readFormatVersion(); - - Externalizable ext = (Externalizable)currentObject; - ext.readExternal(this); - } - } catch (InvocationTargetException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InvocationTargetException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (UnsupportedOperationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "UnsupportedOperationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (InstantiationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InstantiationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } - } else { - /* - * This is your basic diff pattern, made simpler - * because reordering is not allowed. - */ - for (currdesc = currentClassDesc, currclass = currentClass; - currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/ - - currdesc = currdesc.getSuperclass()) { - - /* - * Search the classes to see if the class of this - * descriptor appears further up the hierarchy. Until - * it's found assume its an inserted class. If it's - * not found, its the descriptor's class that has been - * removed. - */ - Class cc = currdesc.forClass(); - Class cl; - for (cl = currclass; cl != null; cl = cl.getSuperclass()) { - if (cc == cl) { - // found a superclass that matches this descriptor - break; - } else { - /* Ignore a class that doesn't match. No - * action is needed since it is already - * initialized. - */ - } - } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass()) - /* Test if there is room for this new entry. - * If not, double the size of the arrays and copy the contents. - */ - spClass++; - if (spClass >= classes.length) { - int newlen = classes.length * 2; - Class[] newclasses = new Class[newlen]; - ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen]; - - System.arraycopy(classes, 0, - newclasses, 0, - classes.length); - System.arraycopy(classdesc, 0, - newclassdesc, 0, - classes.length); - - classes = newclasses; - classdesc = newclassdesc; - } - - if (cl == null) { - /* Class not found corresponding to this descriptor. - * Pop off all the extra classes pushed. - * Push the descriptor and a null class. - */ - classdesc[spClass] = currdesc; - classes[spClass] = null; - } else { - /* Current class descriptor matches current class. - * Some classes may have been inserted. - * Record the match and advance the class, continue - * with the next descriptor. - */ - classdesc[spClass] = currdesc; - classes[spClass] = cl; - currclass = cl.getSuperclass(); - } - } // end : for (currdesc = currentClassDesc, currclass = currentClass; - - /* Allocate a new object. - */ - try { - currentObject = (currentClass == null) ? - null : currentClassDesc.newInstance(); - - // Store this object and its beginning position - // since there might be indirections to it while - // it's been unmarshalled. - activeRecursionMgr.addObject(offset, currentObject); - } catch (InvocationTargetException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InvocationTargetException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (UnsupportedOperationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "UnsupportedOperationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } catch (InstantiationException e) { - InvalidClassException exc = new InvalidClassException( - currentClass.getName(), - "InstantiationException accessing no-arg constructor"); - exc.initCause( e ) ; - throw exc ; - } - - Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements(); - - while((fvdsList.hasMoreElements()) && (spClass > spBase)) { - FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement(); - // d4365188: backward compatability - String repIDForFVD = vhandler.getClassName(fvd.id); - String repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass)); - - while ((spClass > spBase) && - (!repIDForFVD.equals(repIDForClass))) { - int pos = findNextClass(repIDForFVD, classes, spClass, spBase); - if (pos != -1) { - spClass = pos; - currclass = currentClass = classes[spClass]; - repIDForClass = vhandler.getClassName(vhandler.getRMIRepositoryID(currentClass)); - } - else { // Read and throw away one level of the fvdslist - - // This seems to mean that the sender had a superclass that - // we don't have - - if (fvd.is_custom) { - - readFormatVersion(); - boolean calledDefaultWriteObject = readBoolean(); - - if (calledDefaultWriteObject) - inputClassFields(null, null, null, fvd.members, sender); - - if (getStreamFormatVersion() == 2) { - - ((ValueInputStream)getOrbStream()).start_value(); - ((ValueInputStream)getOrbStream()).end_value(); - } - - // WARNING: If stream format version is 1 and there's - // optional data, we'll get some form of exception down - // the line or data corruption. - - } else { - - inputClassFields(null, currentClass, null, fvd.members, sender); - } - - if (fvdsList.hasMoreElements()){ - fvd = (FullValueDescription)fvdsList.nextElement(); - repIDForFVD = vhandler.getClassName(fvd.id); - } - else return currentObject; - } - } - - currdesc = currentClassDesc = ObjectStreamClass.lookup(currentClass); - - if (!repIDForClass.equals("java.lang.Object")) { - - // If the sender used custom marshaling, then it should have put - // the two bytes on the wire indicating stream format version - // and whether or not the writeObject method called - // defaultWriteObject/writeFields. - - ReadObjectState oldState = readObjectState; - setState(DEFAULT_STATE); - - try { - - if (fvd.is_custom) { - - // Read format version - readFormatVersion(); - - // Read defaultWriteObject indicator - boolean calledDefaultWriteObject = readBoolean(); - - readObjectState.beginUnmarshalCustomValue(this, - calledDefaultWriteObject, - (currentClassDesc.readObjectMethod - != null)); - } - - boolean usedReadObject = false; - - // Always use readObject if it exists, and fall back to default - // unmarshaling if it doesn't. - try { - - if (!fvd.is_custom && currentClassDesc.hasReadObject()) - setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED); - - // See the definition of defaultReadObjectFVDMembers - // for more information. This concerns making sure - // we use the remote FVD's members in defaultReadObject. - defaultReadObjectFVDMembers = fvd.members; - usedReadObject = invokeObjectReader(currentClassDesc, - currentObject, - currentClass); - - } finally { - defaultReadObjectFVDMembers = null; - } - - // Note that the !usedReadObject !calledDefaultWriteObject - // case is handled by the beginUnmarshalCustomValue method - // of the default state - if (!usedReadObject || readObjectState == IN_READ_OBJECT_DEFAULTS_SENT) - inputClassFields(currentObject, currentClass, currdesc, fvd.members, sender); - - if (fvd.is_custom) - readObjectState.endUnmarshalCustomValue(this); - - } finally { - setState(oldState); - } - - currclass = currentClass = classes[--spClass]; - - } else { - - // The remaining hierarchy of the local class does not match the sender's FVD. - // So, use remaining FVDs to read data off wire. If any remaining FVDs indicate - // custom marshaling, throw MARSHAL error. - inputClassFields(null, currentClass, null, fvd.members, sender); - - while (fvdsList.hasMoreElements()){ - fvd = (FullValueDescription)fvdsList.nextElement(); - - if (fvd.is_custom) - skipCustomUsingFVD(fvd.members, sender); - else - inputClassFields(null, currentClass, null, fvd.members, sender); - } - - } - - } // end : while(fvdsList.hasMoreElements()) - while (fvdsList.hasMoreElements()){ - - FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement(); - if (fvd.is_custom) - skipCustomUsingFVD(fvd.members, sender); - else - throwAwayData(fvd.members, sender); - } - } - - return currentObject; - } - finally { - // Make sure we exit at the same stack level as when we started. - spClass = spBase; - - // We've completed deserializing this object. Any - // future indirections will be handled correctly at the - // CDR level. The ActiveRecursionManager only deals with - // objects currently being deserialized. - activeRecursionMgr.removeObject(offset); - } - - } - - /** - * This input method uses FullValueDescriptions retrieved from the sender's runtime to - * read in the data. This method is capable of throwing out data not applicable to client's fields. - * - * NOTE : If the local description indicates custom marshaling and the remote type's FVD also - * indicates custom marsahling than the local type is used to read the data off the wire. However, - * if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is - * a form of custom marshaling. - * - */ - private Object skipObjectUsingFVD(String repositoryID, - com.sun.org.omg.SendingContext.CodeBase sender) - throws IOException, ClassNotFoundException - { - - Enumeration fvdsList = getOrderedDescriptions(repositoryID, sender).elements(); - - while(fvdsList.hasMoreElements()) { - FullValueDescription fvd = (FullValueDescription)fvdsList.nextElement(); - String repIDForFVD = vhandler.getClassName(fvd.id); - - if (!repIDForFVD.equals("java.lang.Object")) { - if (fvd.is_custom) { - - readFormatVersion(); - - boolean calledDefaultWriteObject = readBoolean(); - - if (calledDefaultWriteObject) - inputClassFields(null, null, null, fvd.members, sender); - - if (getStreamFormatVersion() == 2) { - - ((ValueInputStream)getOrbStream()).start_value(); - ((ValueInputStream)getOrbStream()).end_value(); - } - - // WARNING: If stream format version is 1 and there's - // optional data, we'll get some form of exception down - // the line. - - } else { - // Use default marshaling - inputClassFields(null, null, null, fvd.members, sender); - } - } - - } // end : while(fvdsList.hasMoreElements()) - return null; - - } - - /////////////////// - - private int findNextClass(String classname, Class classes[], int _spClass, int _spBase){ - - for (int i = _spClass; i > _spBase; i--){ - if (classname.equals(classes[i].getName())) { - return i; - } - } - - return -1; - } - - /* - * Invoke the readObject method if present. Assumes that in the case of custom - * marshaling, the format version and defaultWriteObject indicator were already - * removed. - */ - private boolean invokeObjectReader(ObjectStreamClass osc, Object obj, Class aclass) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException - { - if (osc.readObjectMethod == null) { - return false; - } - - try { - osc.readObjectMethod.invoke( obj, readObjectArgList ) ; - return true; - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof ClassNotFoundException) - throw (ClassNotFoundException)t; - else if (t instanceof IOException) - throw (IOException)t; - else if (t instanceof RuntimeException) - throw (RuntimeException) t; - else if (t instanceof Error) - throw (Error) t; - else - // XXX I18N, logging needed. - throw new Error("internal error"); - } catch (IllegalAccessException e) { - return false; - } - } - - /* - * Reset the stream to be just like it was after the constructor. - */ - private void resetStream() throws IOException { - - if (classes == null) - classes = new Class[20]; - else { - for (int i = 0; i < classes.length; i++) - classes[i] = null; - } - if (classdesc == null) - classdesc = new ObjectStreamClass[20]; - else { - for (int i = 0; i < classdesc.length; i++) - classdesc[i] = null; - } - spClass = 0; - - if (callbacks != null) - callbacks.setSize(0); // discard any pending callbacks - } - - /** - * Factored out of inputClassFields This reads a primitive value and sets it - * in the field of o described by the ObjectStreamField field. - * - * Note that reflection cannot be used here, because reflection cannot be used - * to set final fields. - */ - private void inputPrimitiveField(Object o, Class cl, ObjectStreamField field) - throws InvalidClassException, IOException { - - try { - switch (field.getTypeCode()) { - case 'B': - byte byteValue = orbStream.read_octet(); - bridge.putByte( o, field.getFieldID(), byteValue ) ; - //reflective code: field.getField().setByte( o, byteValue ) ; - break; - case 'Z': - boolean booleanValue = orbStream.read_boolean(); - bridge.putBoolean( o, field.getFieldID(), booleanValue ) ; - //reflective code: field.getField().setBoolean( o, booleanValue ) ; - break; - case 'C': - char charValue = orbStream.read_wchar(); - bridge.putChar( o, field.getFieldID(), charValue ) ; - //reflective code: field.getField().setChar( o, charValue ) ; - break; - case 'S': - short shortValue = orbStream.read_short(); - bridge.putShort( o, field.getFieldID(), shortValue ) ; - //reflective code: field.getField().setShort( o, shortValue ) ; - break; - case 'I': - int intValue = orbStream.read_long(); - bridge.putInt( o, field.getFieldID(), intValue ) ; - //reflective code: field.getField().setInt( o, intValue ) ; - break; - case 'J': - long longValue = orbStream.read_longlong(); - bridge.putLong( o, field.getFieldID(), longValue ) ; - //reflective code: field.getField().setLong( o, longValue ) ; - break; - case 'F' : - float floatValue = orbStream.read_float(); - bridge.putFloat( o, field.getFieldID(), floatValue ) ; - //reflective code: field.getField().setFloat( o, floatValue ) ; - break; - case 'D' : - double doubleValue = orbStream.read_double(); - bridge.putDouble( o, field.getFieldID(), doubleValue ) ; - //reflective code: field.getField().setDouble( o, doubleValue ) ; - break; - default: - // XXX I18N, logging needed. - throw new InvalidClassException(cl.getName()); - } - } catch (IllegalArgumentException e) { - /* This case should never happen. If the field types - are not the same, InvalidClassException is raised when - matching the local class to the serialized ObjectStreamClass. */ - ClassCastException cce = new ClassCastException("Assigning instance of class " + - field.getType().getName() + - " to field " + - currentClassDesc.getName() + '#' + - field.getField().getName()); - cce.initCause( e ) ; - throw cce ; - } - } - - private Object inputObjectField(org.omg.CORBA.ValueMember field, - com.sun.org.omg.SendingContext.CodeBase sender) - throws IndirectionException, ClassNotFoundException, IOException, - StreamCorruptedException { - - Object objectValue = null; - Class type = null; - String id = field.id; - - try { - type = vhandler.getClassFromType(id); - } catch(ClassNotFoundException cnfe) { - // Make sure type = null - type = null; - } - - String signature = null; - if (type != null) - signature = ValueUtility.getSignature(field); - - if (signature != null && (signature.equals("Ljava/lang/Object;") || - signature.equals("Ljava/io/Serializable;") || - signature.equals("Ljava/io/Externalizable;"))) { - objectValue = javax.rmi.CORBA.Util.readAny(orbStream); - } else { - // Decide what method call to make based on the type. If - // it is a type for which we need to load a stub, convert - // the type to the correct stub type. - // - // NOTE : Since FullValueDescription does not allow us - // to ask whether something is an interface we do not - // have the ability to optimize this check. - - int callType = ValueHandlerImpl.kValueType; - - if (!vhandler.isSequence(id)) { - - if (field.type.kind().value() == kRemoteTypeCode.kind().value()) { - - // RMI Object reference... - callType = ValueHandlerImpl.kRemoteType; - - } else { - - // REVISIT. If we don't have the local class, - // we should probably verify that it's an RMI type, - // query the remote FVD, and use is_abstract. - // Our FVD seems to get NullPointerExceptions for any - // non-RMI types. - - // This uses the local class in the same way as - // inputObjectField(ObjectStreamField) does. REVISIT - // inputObjectField(ObjectStreamField)'s loadStubClass - // logic. Assumption is that the given type cannot - // evolve to become a CORBA abstract interface or - // a RMI abstract interface. - - if (type != null && type.isInterface() && - (vhandler.isAbstractBase(type) || - ObjectStreamClassCorbaExt.isAbstractInterface(type))) { - - callType = ValueHandlerImpl.kAbstractType; - } - } - } - - // Now that we have used the FVD of the field to determine the proper course - // of action, it is ok to use the type (Class) from this point forward since - // the rep. id for this read will also follow on the wire. - - switch (callType) { - case ValueHandlerImpl.kRemoteType: - if (type != null) - objectValue = Utility.readObjectAndNarrow(orbStream, type); - else - objectValue = orbStream.read_Object(); - break; - case ValueHandlerImpl.kAbstractType: - if (type != null) - objectValue = Utility.readAbstractAndNarrow(orbStream, type); - else - objectValue = orbStream.read_abstract_interface(); - break; - case ValueHandlerImpl.kValueType: - if (type != null) - objectValue = orbStream.read_value(type); - else - objectValue = orbStream.read_value(); - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown callType: " + callType); - } - } - - return objectValue; - } - - /** - * Factored out of inputClassFields and reused in - * inputCurrentClassFieldsForReadFields. - * - * Reads the field (which of an Object type as opposed to a primitive) - * described by ObjectStreamField field and returns it. - */ - private Object inputObjectField(ObjectStreamField field) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IndirectionException, IOException { - - if (ObjectStreamClassCorbaExt.isAny(field.getTypeString())) { - return javax.rmi.CORBA.Util.readAny(orbStream); - } - - Object objectValue = null; - - // fields have an API to provide the actual class - // corresponding to the data type - // Class type = osc.forClass(); - Class fieldType = field.getType(); - Class actualType = fieldType; // This may change if stub loaded. - - // Decide what method call to make based on the fieldType. If - // it is a type for which we need to load a stub, convert - // the type to the correct stub type. - - int callType = ValueHandlerImpl.kValueType; - boolean narrow = false; - - if (fieldType.isInterface()) { - boolean loadStubClass = false; - - if (java.rmi.Remote.class.isAssignableFrom(fieldType)) { - - // RMI Object reference... - callType = ValueHandlerImpl.kRemoteType; - - } else if (org.omg.CORBA.Object.class.isAssignableFrom(fieldType)){ - - // IDL Object reference... - callType = ValueHandlerImpl.kRemoteType; - loadStubClass = true; - - } else if (vhandler.isAbstractBase(fieldType)) { - // IDL Abstract Object reference... - - callType = ValueHandlerImpl.kAbstractType; - loadStubClass = true; - } else if (ObjectStreamClassCorbaExt.isAbstractInterface(fieldType)) { - // RMI Abstract Object reference... - - callType = ValueHandlerImpl.kAbstractType; - } - - if (loadStubClass) { - try { - String codebase = Util.getCodebase(fieldType); - String repID = vhandler.createForAnyType(fieldType); - Class stubType = - Utility.loadStubClass(repID, codebase, fieldType); - actualType = stubType; - } catch (ClassNotFoundException e) { - narrow = true; - } - } else { - narrow = true; - } - } - - switch (callType) { - case ValueHandlerImpl.kRemoteType: - if (!narrow) - objectValue = (Object)orbStream.read_Object(actualType); - else - objectValue = Utility.readObjectAndNarrow(orbStream, actualType); - break; - case ValueHandlerImpl.kAbstractType: - if (!narrow) - objectValue = (Object)orbStream.read_abstract_interface(actualType); - else - objectValue = Utility.readAbstractAndNarrow(orbStream, actualType); - break; - case ValueHandlerImpl.kValueType: - objectValue = (Object)orbStream.read_value(actualType); - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown callType: " + callType); - } - - return objectValue; - } - - private final boolean mustUseRemoteValueMembers() { - return defaultReadObjectFVDMembers != null; - } - - void readFields(java.util.Map fieldToValueMap) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException { - - if (mustUseRemoteValueMembers()) { - inputRemoteMembersForReadFields(fieldToValueMap); - } else - inputCurrentClassFieldsForReadFields(fieldToValueMap); - } - - private final void inputRemoteMembersForReadFields(java.util.Map fieldToValueMap) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException { - - // Must have this local variable since defaultReadObjectFVDMembers - // may get mangled by recursion. - ValueMember fields[] = defaultReadObjectFVDMembers; - - try { - - for (int i = 0; i < fields.length; i++) { - - switch (fields[i].type.kind().value()) { - - case TCKind._tk_octet: - byte byteValue = orbStream.read_octet(); - fieldToValueMap.put(fields[i].name, new Byte(byteValue)); - break; - case TCKind._tk_boolean: - boolean booleanValue = orbStream.read_boolean(); - fieldToValueMap.put(fields[i].name, new Boolean(booleanValue)); - break; - case TCKind._tk_char: - // Backwards compatibility. Older Sun ORBs sent - // _tk_char even though they read and wrote wchars - // correctly. - // - // Fall through to the _tk_wchar case. - case TCKind._tk_wchar: - char charValue = orbStream.read_wchar(); - fieldToValueMap.put(fields[i].name, new Character(charValue)); - break; - case TCKind._tk_short: - short shortValue = orbStream.read_short(); - fieldToValueMap.put(fields[i].name, new Short(shortValue)); - break; - case TCKind._tk_long: - int intValue = orbStream.read_long(); - fieldToValueMap.put(fields[i].name, new Integer(intValue)); - break; - case TCKind._tk_longlong: - long longValue = orbStream.read_longlong(); - fieldToValueMap.put(fields[i].name, new Long(longValue)); - break; - case TCKind._tk_float: - float floatValue = orbStream.read_float(); - fieldToValueMap.put(fields[i].name, new Float(floatValue)); - break; - case TCKind._tk_double: - double doubleValue = orbStream.read_double(); - fieldToValueMap.put(fields[i].name, new Double(doubleValue)); - break; - case TCKind._tk_value: - case TCKind._tk_objref: - case TCKind._tk_value_box: - Object objectValue = null; - try { - objectValue = inputObjectField(fields[i], - cbSender); - - } catch (IndirectionException cdrie) { - // The CDR stream had never seen the given offset before, - // so check the recursion manager (it will throw an - // IOException if it doesn't have a reference, either). - objectValue = activeRecursionMgr.getObject(cdrie.offset); - } - - fieldToValueMap.put(fields[i].name, objectValue); - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown kind: " - + fields[i].type.kind().value()); - } - } - } catch (Throwable t) { - StreamCorruptedException result = new StreamCorruptedException(t.getMessage()); - result.initCause(t); - throw result; - } - } - - /** - * Called from InputStreamHook. - * - * Reads the fields of the current class (could be the ones - * queried from the remote FVD) and puts them in - * the given Map, name to value. Wraps primitives in the - * corresponding java.lang Objects. - */ - private final void inputCurrentClassFieldsForReadFields(java.util.Map fieldToValueMap) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException { - - ObjectStreamField[] fields = currentClassDesc.getFieldsNoCopy(); - - int primFields = fields.length - currentClassDesc.objFields; - - // Handle the primitives first - for (int i = 0; i < primFields; ++i) { - - switch (fields[i].getTypeCode()) { - case 'B': - byte byteValue = orbStream.read_octet(); - fieldToValueMap.put(fields[i].getName(), - new Byte(byteValue)); - break; - case 'Z': - boolean booleanValue = orbStream.read_boolean(); - fieldToValueMap.put(fields[i].getName(), - new Boolean(booleanValue)); - break; - case 'C': - char charValue = orbStream.read_wchar(); - fieldToValueMap.put(fields[i].getName(), - new Character(charValue)); - break; - case 'S': - short shortValue = orbStream.read_short(); - fieldToValueMap.put(fields[i].getName(), - new Short(shortValue)); - break; - case 'I': - int intValue = orbStream.read_long(); - fieldToValueMap.put(fields[i].getName(), - new Integer(intValue)); - break; - case 'J': - long longValue = orbStream.read_longlong(); - fieldToValueMap.put(fields[i].getName(), - new Long(longValue)); - break; - case 'F' : - float floatValue = orbStream.read_float(); - fieldToValueMap.put(fields[i].getName(), - new Float(floatValue)); - break; - case 'D' : - double doubleValue = orbStream.read_double(); - fieldToValueMap.put(fields[i].getName(), - new Double(doubleValue)); - break; - default: - // XXX I18N, logging needed. - throw new InvalidClassException(currentClassDesc.getName()); - } - } - - /* Read and set object fields from the input stream. */ - if (currentClassDesc.objFields > 0) { - for (int i = primFields; i < fields.length; i++) { - Object objectValue = null; - try { - objectValue = inputObjectField(fields[i]); - } catch(IndirectionException cdrie) { - // The CDR stream had never seen the given offset before, - // so check the recursion manager (it will throw an - // IOException if it doesn't have a reference, either). - objectValue = activeRecursionMgr.getObject(cdrie.offset); - } - - fieldToValueMap.put(fields[i].getName(), objectValue); - } - } - } - - /* - * Read the fields of the specified class from the input stream and set - * the values of the fields in the specified object. If the specified - * object is null, just consume the fields without setting any values. If - * any ObjectStreamField does not have a reflected Field, don't try to set - * that field in the object. - * - * REVISIT -- This code doesn't do what the comment says to when - * getField() is null! - */ - private void inputClassFields(Object o, Class cl, - ObjectStreamField[] fields, - com.sun.org.omg.SendingContext.CodeBase sender) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException - { - - int primFields = fields.length - currentClassDesc.objFields; - - if (o != null) { - for (int i = 0; i < primFields; ++i) { - if (fields[i].getField() == null) - continue; - - inputPrimitiveField(o, cl, fields[i]); - } - } - - /* Read and set object fields from the input stream. */ - if (currentClassDesc.objFields > 0) { - for (int i = primFields; i < fields.length; i++) { - Object objectValue = null; - - try { - objectValue = inputObjectField(fields[i]); - } catch(IndirectionException cdrie) { - // The CDR stream had never seen the given offset before, - // so check the recursion manager (it will throw an - // IOException if it doesn't have a reference, either). - objectValue = activeRecursionMgr.getObject(cdrie.offset); - } - - if ((o == null) || (fields[i].getField() == null)) { - continue; - } - - try { - bridge.putObject( o, fields[i].getFieldID(), objectValue ) ; - // reflective code: fields[i].getField().set( o, objectValue ) ; - } catch (IllegalArgumentException e) { - ClassCastException exc = new ClassCastException("Assigning instance of class " + - objectValue.getClass().getName() + - " to field " + - currentClassDesc.getName() + - '#' + - fields[i].getField().getName()); - exc.initCause( e ) ; - throw exc ; - } - } // end : for loop - } - } - - /* - * Read the fields of the specified class from the input stream and set - * the values of the fields in the specified object. If the specified - * object is null, just consume the fields without setting any values. If - * any ObjectStreamField does not have a reflected Field, don't try to set - * that field in the object. - */ - private void inputClassFields(Object o, Class cl, - ObjectStreamClass osc, - ValueMember[] fields, - com.sun.org.omg.SendingContext.CodeBase sender) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException - { - try{ - for (int i = 0; i < fields.length; ++i) { - try { - switch (fields[i].type.kind().value()) { - case TCKind._tk_octet: - byte byteValue = orbStream.read_octet(); - if ((o != null) && osc.hasField(fields[i])) - setByteField(o, cl, fields[i].name, byteValue); - break; - case TCKind._tk_boolean: - boolean booleanValue = orbStream.read_boolean(); - if ((o != null) && osc.hasField(fields[i])) - setBooleanField(o, cl, fields[i].name, booleanValue); - break; - case TCKind._tk_char: - // Backwards compatibility. Older Sun ORBs sent - // _tk_char even though they read and wrote wchars - // correctly. - // - // Fall through to the _tk_wchar case. - case TCKind._tk_wchar: - char charValue = orbStream.read_wchar(); - if ((o != null) && osc.hasField(fields[i])) - setCharField(o, cl, fields[i].name, charValue); - break; - case TCKind._tk_short: - short shortValue = orbStream.read_short(); - if ((o != null) && osc.hasField(fields[i])) - setShortField(o, cl, fields[i].name, shortValue); - break; - case TCKind._tk_long: - int intValue = orbStream.read_long(); - if ((o != null) && osc.hasField(fields[i])) - setIntField(o, cl, fields[i].name, intValue); - break; - case TCKind._tk_longlong: - long longValue = orbStream.read_longlong(); - if ((o != null) && osc.hasField(fields[i])) - setLongField(o, cl, fields[i].name, longValue); - break; - case TCKind._tk_float: - float floatValue = orbStream.read_float(); - if ((o != null) && osc.hasField(fields[i])) - setFloatField(o, cl, fields[i].name, floatValue); - break; - case TCKind._tk_double: - double doubleValue = orbStream.read_double(); - if ((o != null) && osc.hasField(fields[i])) - setDoubleField(o, cl, fields[i].name, doubleValue); - break; - case TCKind._tk_value: - case TCKind._tk_objref: - case TCKind._tk_value_box: - Object objectValue = null; - try { - objectValue = inputObjectField(fields[i], sender); - } catch (IndirectionException cdrie) { - // The CDR stream had never seen the given offset before, - // so check the recursion manager (it will throw an - // IOException if it doesn't have a reference, either). - objectValue = activeRecursionMgr.getObject(cdrie.offset); - } - - if (o == null) - continue; - try { - if (osc.hasField(fields[i])){ - setObjectField(o, - cl, - fields[i].name, - objectValue); - } else { - // REVISIT. Convert to a log message. - // This is a normal case when fields have - // been added as part of evolution, but - // silently skipping can make it hard to - // debug if there's an error -// System.out.println("**** warning, not setting field: " -// + fields[i].name -// + " since not on class " -// + osc.getName()); - - } - } catch (IllegalArgumentException e) { - // XXX I18N, logging needed. - ClassCastException cce = new ClassCastException("Assigning instance of class " + - objectValue.getClass().getName() + " to field " + fields[i].name); - cce.initCause(e) ; - throw cce ; - } - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown kind: " - + fields[i].type.kind().value()); - } - } catch (IllegalArgumentException e) { - /* This case should never happen. If the field types - are not the same, InvalidClassException is raised when - matching the local class to the serialized ObjectStreamClass. */ - // XXX I18N, logging needed. - ClassCastException cce = new ClassCastException("Assigning instance of class " + fields[i].id + - " to field " + currentClassDesc.getName() + '#' + fields[i].name); - cce.initCause( e ) ; - throw cce ; - } - } - } catch(Throwable t){ - // XXX I18N, logging needed. - StreamCorruptedException sce = new StreamCorruptedException(t.getMessage()); - sce.initCause(t) ; - throw sce ; - } - } - - private void skipCustomUsingFVD(ValueMember[] fields, - com.sun.org.omg.SendingContext.CodeBase sender) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException - { - readFormatVersion(); - boolean calledDefaultWriteObject = readBoolean(); - - if (calledDefaultWriteObject) - throwAwayData(fields, sender); - - if (getStreamFormatVersion() == 2) { - - ((ValueInputStream)getOrbStream()).start_value(); - ((ValueInputStream)getOrbStream()).end_value(); - } - } - - /* - * Read the fields of the specified class from the input stream throw data away. - * This must handle same switch logic as above. - */ - private void throwAwayData(ValueMember[] fields, - com.sun.org.omg.SendingContext.CodeBase sender) - throws InvalidClassException, StreamCorruptedException, - ClassNotFoundException, IOException - { - for (int i = 0; i < fields.length; ++i) { - - try { - - switch (fields[i].type.kind().value()) { - case TCKind._tk_octet: - orbStream.read_octet(); - break; - case TCKind._tk_boolean: - orbStream.read_boolean(); - break; - case TCKind._tk_char: - // Backwards compatibility. Older Sun ORBs sent - // _tk_char even though they read and wrote wchars - // correctly. - // - // Fall through to the _tk_wchar case. - case TCKind._tk_wchar: - orbStream.read_wchar(); - break; - case TCKind._tk_short: - orbStream.read_short(); - break; - case TCKind._tk_long: - orbStream.read_long(); - break; - case TCKind._tk_longlong: - orbStream.read_longlong(); - break; - case TCKind._tk_float: - orbStream.read_float(); - break; - case TCKind._tk_double: - orbStream.read_double(); - break; - case TCKind._tk_value: - case TCKind._tk_objref: - case TCKind._tk_value_box: - Class type = null; - String id = fields[i].id; - - try { - type = vhandler.getClassFromType(id); - } - catch(ClassNotFoundException cnfe){ - // Make sure type = null - type = null; - } - String signature = null; - if (type != null) - signature = ValueUtility.getSignature(fields[i]); - - // Read value - try { - if ((signature != null) && ( signature.equals("Ljava/lang/Object;") || - signature.equals("Ljava/io/Serializable;") || - signature.equals("Ljava/io/Externalizable;")) ) { - javax.rmi.CORBA.Util.readAny(orbStream); - } - else { - // Decide what method call to make based on the type. - // - // NOTE : Since FullValueDescription does not allow us - // to ask whether something is an interface we do not - // have the ability to optimize this check. - - int callType = ValueHandlerImpl.kValueType; - - if (!vhandler.isSequence(id)) { - FullValueDescription fieldFVD = sender.meta(fields[i].id); - if (kRemoteTypeCode == fields[i].type) { - - // RMI Object reference... - callType = ValueHandlerImpl.kRemoteType; - } else if (fieldFVD.is_abstract) { - // RMI Abstract Object reference... - - callType = ValueHandlerImpl.kAbstractType; - } - } - - // Now that we have used the FVD of the field to determine the proper course - // of action, it is ok to use the type (Class) from this point forward since - // the rep. id for this read will also follow on the wire. - - switch (callType) { - case ValueHandlerImpl.kRemoteType: - orbStream.read_Object(); - break; - case ValueHandlerImpl.kAbstractType: - orbStream.read_abstract_interface(); - break; - case ValueHandlerImpl.kValueType: - if (type != null) { - orbStream.read_value(type); - } else { - orbStream.read_value(); - } - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown callType: " - + callType); - } - } - - } - catch(IndirectionException cdrie) { - // Since we are throwing this away, don't bother handling recursion. - continue; - } - - break; - default: - // XXX I18N, logging needed. - throw new StreamCorruptedException("Unknown kind: " - + fields[i].type.kind().value()); - - } - } catch (IllegalArgumentException e) { - /* This case should never happen. If the field types - are not the same, InvalidClassException is raised when - matching the local class to the serialized ObjectStreamClass. */ - // XXX I18N, logging needed. - ClassCastException cce = new ClassCastException("Assigning instance of class " + - fields[i].id + " to field " + currentClassDesc.getName() + - '#' + fields[i].name); - cce.initCause(e) ; - throw cce ; - } - } - - } - - private static void setObjectField(Object o, Class c, String fieldName, Object v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putObject( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetObjectField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - ObjectUtility.compactObjectToString( v )) ; - } - } - - private static void setBooleanField(Object o, Class c, String fieldName, boolean v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putBoolean( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetBooleanField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Boolean(v) ) ; - } - } - - private static void setByteField(Object o, Class c, String fieldName, byte v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putByte( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetByteField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Byte(v) ) ; - } - } - - private static void setCharField(Object o, Class c, String fieldName, char v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putChar( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetCharField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Character(v) ) ; - } - } - - private static void setShortField(Object o, Class c, String fieldName, short v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putShort( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetShortField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Short(v) ) ; - } - } - - private static void setIntField(Object o, Class c, String fieldName, int v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putInt( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetIntField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Integer(v) ) ; - } - } - - private static void setLongField(Object o, Class c, String fieldName, long v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putLong( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetLongField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Long(v) ) ; - } - } - - private static void setFloatField(Object o, Class c, String fieldName, float v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putFloat( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetFloatField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Float(v) ) ; - } - } - - private static void setDoubleField(Object o, Class c, String fieldName, double v) - { - try { - Field fld = c.getDeclaredField( fieldName ) ; - long key = bridge.objectFieldOffset( fld ) ; - bridge.putDouble( o, key, v ) ; - } catch (Exception e) { - throw utilWrapper.errorSetDoubleField( e, fieldName, - ObjectUtility.compactObjectToString( o ), - new Double(v) ) ; - } - } - - /** - * This class maintains a map of stream position to - * an Object currently being deserialized. It is used - * to handle the cases where the are indirections to - * an object on the recursion stack. The CDR level - * handles indirections to objects previously seen - * (and completely deserialized) in the stream. - */ - static class ActiveRecursionManager - { - private Map offsetToObjectMap; - - public ActiveRecursionManager() { - // A hash map is unsynchronized and allows - // null values - offsetToObjectMap = new HashMap(); - } - - // Called right after allocating a new object. - // Offset is the starting position in the stream - // of the object. - public void addObject(int offset, Object value) { - offsetToObjectMap.put(new Integer(offset), value); - } - - // If the given starting position doesn't refer - // to the beginning of an object currently being - // deserialized, this throws an IOException. - // Otherwise, it returns a reference to the - // object. - public Object getObject(int offset) throws IOException { - Integer position = new Integer(offset); - - if (!offsetToObjectMap.containsKey(position)) - // XXX I18N, logging needed. - throw new IOException("Invalid indirection to offset " - + offset); - - return offsetToObjectMap.get(position); - } - - // Called when an object has been completely - // deserialized, so it should no longer be in - // this mapping. The CDR level can handle - // further indirections. - public void removeObject(int offset) { - offsetToObjectMap.remove(new Integer(offset)); - } - - // If the given offset doesn't map to an Object, - // then it isn't an indirection to an object - // currently being deserialized. - public boolean containsObject(int offset) { - return offsetToObjectMap.containsKey(new Integer(offset)); - } - } -} diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java --- a/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java Fri Sep 24 16:38:05 2010 -0700 +++ b/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java Fri Sep 24 22:42:14 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,32 +32,22 @@ package com.sun.corba.se.impl.io; import javax.rmi.CORBA.Util; -import javax.rmi.PortableRemoteObject; import java.util.Hashtable; -import java.util.Stack; import java.io.IOException; -import java.util.EmptyStackException; -import com.sun.corba.se.impl.util.Utility; -import com.sun.corba.se.impl.io.IIOPInputStream; -import com.sun.corba.se.impl.io.IIOPOutputStream; import com.sun.corba.se.impl.util.RepositoryId; import com.sun.corba.se.impl.util.Utility; import org.omg.CORBA.TCKind; -import org.omg.CORBA.MARSHAL; -import org.omg.CORBA.BAD_PARAM; -import org.omg.CORBA.CompletionStatus; import org.omg.CORBA.portable.IndirectionException; import com.sun.org.omg.SendingContext.CodeBase; import com.sun.org.omg.SendingContext.CodeBaseHelper; import java.security.AccessController; import java.security.PrivilegedAction; - -import com.sun.corba.se.impl.io.IIOPInputStream.ActiveRecursionManager; +import java.security.PrivilegedExceptionAction; import com.sun.corba.se.spi.logging.CORBALogDomains; import com.sun.corba.se.impl.logging.OMGSystemException; @@ -809,65 +799,163 @@ return "com.sun.corba.se.impl.io.IIOPOutputStream"; } - private com.sun.corba.se.impl.io.IIOPOutputStream createOutputStream() { - return (com.sun.corba.se.impl.io.IIOPOutputStream)AccessController.doPrivileged( - new StreamFactory(getOutputStreamClassName())); + private IIOPOutputStream createOutputStream() { + final String name = getOutputStreamClassName(); + try { + IIOPOutputStream stream = createOutputStreamBuiltIn(name); + if (stream != null) { + return stream; + } + return createCustom(IIOPOutputStream.class, name); + } catch (Throwable t) { + // Throw exception under the carpet. + InternalError ie = new InternalError( + "Error loading " + name + ); + ie.initCause(t); + throw ie; + } + } + + /** + * Construct a built in implementation with priveleges. + * Returning null indicates a non-built is specified. + */ + private IIOPOutputStream createOutputStreamBuiltIn( + final String name + ) throws Throwable { + try { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public IIOPOutputStream run() throws IOException { + return createOutputStreamBuiltInNoPriv(name); + } + } + ); + } catch (java.security.PrivilegedActionException exc) { + throw exc.getCause(); + } + } + + /** + * Returning null indicates a non-built is specified. + */ + private IIOPOutputStream createOutputStreamBuiltInNoPriv( + final String name + ) throws IOException { + return + name.equals( + IIOPOutputStream + .class.getName() + ) ? + new IIOPOutputStream() : + + name.equals( + com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3 + .class.getName() + ) ? + new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3() : + + name.equals( + com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1 + .class.getName() + ) ? + new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1() : + + null; } protected String getInputStreamClassName() { return "com.sun.corba.se.impl.io.IIOPInputStream"; } - private com.sun.corba.se.impl.io.IIOPInputStream createInputStream() { - return (com.sun.corba.se.impl.io.IIOPInputStream)AccessController.doPrivileged( - new StreamFactory(getInputStreamClassName())); + private IIOPInputStream createInputStream() { + final String name = getInputStreamClassName(); + try { + IIOPInputStream stream = createInputStreamBuiltIn(name); + if (stream != null) { + return stream; + } + return createCustom(IIOPInputStream.class, name); + } catch (Throwable t) { + // Throw exception under the carpet. + InternalError ie = new InternalError( + "Error loading " + name + ); + ie.initCause(t); + throw ie; + } } /** - * Instantiates a class of the given name using the system ClassLoader - * as part of a PrivilegedAction. - * - * It's private final so hopefully people can't grab it outside of - * this class. - * - * If you're worried that someone could subclass ValueHandlerImpl, - * install his own streams, and snoop what's on the wire: - * Someone can do that only if he's allowed to use the feature - * of installing his own javax.rmi.CORBA.Util delegate (via a - * JVM property or orb.properties file, read the first time the - * Util class is used). If he can do that, he can snoop - * anything on the wire, anyway, without abusing the - * StreamFactory class. + * Construct a built in implementation with priveleges. + * Returning null indicates a non-built is specified. */ - private static final class StreamFactory implements PrivilegedAction { - private String className; + private IIOPInputStream createInputStreamBuiltIn( + final String name + ) throws Throwable { + try { + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public IIOPInputStream run() throws IOException { + return createInputStreamBuiltInNoPriv(name); + } + } + ); + } catch (java.security.PrivilegedActionException exc) { + throw exc.getCause(); + } + } - public StreamFactory (String _className) { - className = _className; - } + /** + * Returning null indicates a non-built is specified. + */ + private IIOPInputStream createInputStreamBuiltInNoPriv( + final String name + ) throws IOException { + return + name.equals( + IIOPInputStream + .class.getName() + ) ? + new IIOPInputStream() : - public Object run() { - try { - // Note: We must use the system ClassLoader here - // since we want to load classes outside of the - // core JDK when running J2EE Pure ORB and - // talking to Kestrel. + name.equals( + com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3 + .class.getName() + ) ? + new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3() : + + name.equals( + com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1 + .class.getName() + ) ? + new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1() : + + null; + } + + /** + * Create a custom implementation without privileges. + */ + private T createCustom( + final Class type, final String className + ) throws Throwable { + // Note: We use the thread context or system ClassLoader here + // since we want to load classes outside of the + // core JDK when running J2EE Pure ORB and + // talking to Kestrel. ClassLoader cl = Thread.currentThread().getContextClassLoader(); if (cl == null) cl = ClassLoader.getSystemClassLoader(); - Class streamClass = cl.loadClass(className); + Class clazz = cl.loadClass(className); + Class streamClass = clazz.asSubclass(type); // Since the ClassLoader should cache the class, this isn't // as expensive as it looks. return streamClass.newInstance(); - } catch(Throwable t) { - InternalError ie = new InternalError( "Error loading " + className ) ; - ie.initCause( t ) ; - throw ie ; - } - } } /** diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/impl/orb/PrefixParserAction.java --- a/src/share/classes/com/sun/corba/se/impl/orb/PrefixParserAction.java Fri Sep 24 16:38:05 2010 -0700 +++ b/src/share/classes/com/sun/corba/se/impl/orb/PrefixParserAction.java Fri Sep 24 22:42:14 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -110,7 +110,7 @@ throw wrapper.couldNotSetArray( thr, getPropertyName(), new Integer(ctr), componentType, new Integer(size), - ObjectUtility.compactObjectToString( obj )) ; + obj.toString() ) ; } ctr++ ; } diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java --- a/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java Fri Sep 24 16:38:05 2010 -0700 +++ b/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectUtility.java Fri Sep 24 22:42:14 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,103 +50,8 @@ import java.math.BigDecimal ; public final class ObjectUtility { - private boolean useToString ; - private boolean isIndenting ; - private int initialLevel ; - private int increment ; - private ClassMap classToPrinter = new ClassMap() ; + private ObjectUtility() {} - private static ObjectUtility standard = new ObjectUtility( false, true, - 0, 4 ) ; - private static ObjectUtility compact = new ObjectUtility( true, false, - 0, 4 ) ; - - private ObjectUtility( boolean useToString, boolean isIndenting, - int initialLevel, int increment ) - { - this.useToString = useToString ; - this.isIndenting = isIndenting ; - this.initialLevel = initialLevel ; - this.increment = increment ; - classToPrinter.put( Properties.class, propertiesPrinter ) ; - classToPrinter.put( Collection.class, collectionPrinter ) ; - classToPrinter.put( Map.class, mapPrinter ) ; - } - - /** Construct an Utility instance with the desired objectToString - * behavior. - */ - public static ObjectUtility make( boolean useToString, boolean isIndenting, - int initialLevel, int increment ) - { - return new ObjectUtility( useToString, isIndenting, initialLevel, - increment ) ; - } - - /** Construct an Utility instance with the desired objectToString - * behavior. - */ - public static ObjectUtility make( boolean useToString, boolean isIndenting ) - { - return new ObjectUtility( useToString, isIndenting, 0, 4 ) ; - } - - /** Get the standard Utility object that supports objectToString with - * indented display and no use of toString() methods. - */ - public static ObjectUtility make() - { - return standard ; - } - - /** A convenience method that gives the default behavior: use indenting - * to display the object's structure and do not use built-in toString - * methods. - */ - public static String defaultObjectToString( java.lang.Object object ) - { - return standard.objectToString( object ) ; - } - - public static String compactObjectToString( java.lang.Object object ) - { - return compact.objectToString( object ) ; - } - - /** objectToString handles display of arbitrary objects. It correctly - * handles objects whose elements form an arbitrary graph. It uses - * reflection to display the contents of any kind of object. - * An object's toString() method may optionally be used, but the default - * is to ignore all toString() methods except for those defined for - * primitive types, primitive type wrappers, and strings. - */ - public String objectToString(java.lang.Object obj) - { - IdentityHashMap printed = new IdentityHashMap() ; - ObjectWriter result = ObjectWriter.make( isIndenting, initialLevel, - increment ) ; - objectToStringHelper( printed, result, obj ) ; - return result.toString() ; - } - - // Perform a deep structural equality comparison of the two objects. - // This handles all arrays, maps, and sets specially, otherwise - // it just calls the object's equals() method. - public static boolean equals( java.lang.Object obj1, java.lang.Object obj2 ) - { - // Set of pairs of objects that have been (or are being) considered for - // equality. Such pairs are presumed to be equals. If they are not, - // this will be detected eventually and the equals method will return - // false. - Set considered = new HashSet() ; - - // Map that gives the corresponding component of obj2 for a component - // of obj1. This is used to check for the same aliasing and use of - // equal objects in both objects. - Map counterpart = new IdentityHashMap() ; - - return equalsHelper( counterpart, considered, obj1, obj2 ) ; - } /** If arr1 and arr2 are both arrays of the same component type, * return an array of that component type that consists of the @@ -179,544 +84,4 @@ return result ; } -//=========================================================================== -// Implementation -//=========================================================================== - - private void objectToStringHelper( IdentityHashMap printed, - ObjectWriter result, java.lang.Object obj) - { - if (obj==null) { - result.append( "null" ) ; - result.endElement() ; - } else { - Class cls = obj.getClass() ; - result.startObject( obj ) ; - - if (printed.keySet().contains( obj )) { - result.endObject( "*VISITED*" ) ; - } else { - printed.put( obj, null ) ; - - if (mustUseToString(cls)) { - result.endObject( obj.toString() ) ; - } else { - // First, handle any classes that have special printer - // methods defined. This is useful when the class - // overrides toString with something that - // is not sufficiently detailed. - ObjectPrinter printer = (ObjectPrinter)(classToPrinter.get( - cls )) ; - if (printer != null) { - printer.print( printed, result, obj ) ; - result.endObject() ; - } else { - Class compClass = cls.getComponentType() ; - - if (compClass == null) - // handleObject always calls endObject - handleObject( printed, result, obj ) ; - else { - handleArray( printed, result, obj ) ; - result.endObject() ; - } - } - } - } - } - } - - private static interface ObjectPrinter { - void print( IdentityHashMap printed, ObjectWriter buff, - java.lang.Object obj ) ; - } - - private ObjectPrinter propertiesPrinter = new ObjectPrinter() { - public void print( IdentityHashMap printed, ObjectWriter buff, - java.lang.Object obj ) - { - if (!(obj instanceof Properties)) - throw new Error() ; - - Properties props = (Properties)obj ; - Enumeration keys = props.propertyNames() ; - while (keys.hasMoreElements()) { - String key = (String)(keys.nextElement()) ; - String value = props.getProperty( key ) ; - buff.startElement() ; - buff.append( key ) ; - buff.append( "=" ) ; - buff.append( value ) ; - buff.endElement() ; - } - } - } ; - - private ObjectPrinter collectionPrinter = new ObjectPrinter() { - public void print( IdentityHashMap printed, ObjectWriter buff, - java.lang.Object obj ) - { - if (!(obj instanceof Collection)) - throw new Error() ; - - Collection coll = (Collection)obj ; - Iterator iter = coll.iterator() ; - while (iter.hasNext()) { - java.lang.Object element = iter.next() ; - buff.startElement() ; - objectToStringHelper( printed, buff, element ) ; - buff.endElement() ; - } - } - } ; - - private ObjectPrinter mapPrinter = new ObjectPrinter() { - public void print( IdentityHashMap printed, ObjectWriter buff, - java.lang.Object obj ) - { - if (!(obj instanceof Map)) - throw new Error() ; - - Map map = (Map)obj ; - Iterator iter = map.entrySet().iterator() ; - while (iter.hasNext()) { - Entry entry = (Entry)(iter.next()) ; - buff.startElement() ; - objectToStringHelper( printed, buff, entry.getKey() ) ; - buff.append( "=>" ) ; - objectToStringHelper( printed, buff, entry.getValue() ) ; - buff.endElement() ; - } - } - } ; - - private static class ClassMap { - ArrayList data ; - - public ClassMap() - { - data = new ArrayList() ; - } - - /** Return the first element of the ClassMap that is assignable to cls. - * The order is determined by the order in which the put method was - * called. Returns null if there is no match. - */ - public java.lang.Object get( Class cls ) - { - Iterator iter = data.iterator() ; - while (iter.hasNext()) { - java.lang.Object[] arr = (java.lang.Object[])(iter.next()) ; - Class key = (Class)(arr[0]) ; - if (key.isAssignableFrom( cls )) - return arr[1] ; - } - - return null ; - } - - /** Add obj to the map with key cls. Note that order matters, - * as the first match is returned. - */ - public void put( Class cls, java.lang.Object obj ) - { - java.lang.Object[] pair = { cls, obj } ; - data.add( pair ) ; - } - } - - private boolean mustUseToString( Class cls ) - { - // These probably never occur - if (cls.isPrimitive()) - return true ; - - // We must use toString for all primitive wrappers, since - // otherwise the code recurses endlessly (access value field - // inside Integer, returns another Integer through reflection). - if ((cls == Integer.class) || - (cls == BigInteger.class) || - (cls == BigDecimal.class) || - (cls == String.class) || - (cls == StringBuffer.class) || - (cls == Long.class) || - (cls == Short.class) || - (cls == Byte.class) || - (cls == Character.class) || - (cls == Float.class) || - (cls == Double.class) || - (cls == Boolean.class)) - return true ; - - if (useToString) { - try { - cls.getDeclaredMethod( "toString", (Class[])null ) ; - return true ; - } catch (Exception exc) { - return false ; - } - } - - return false ; - } - - private void handleObject( IdentityHashMap printed, ObjectWriter result, - java.lang.Object obj ) - { - Class cls = obj.getClass() ; - - try { - Field[] fields; - SecurityManager security = System.getSecurityManager(); - if (security != null && !Modifier.isPublic(cls.getModifiers())) { - fields = new Field[0]; - } else { - fields = cls.getDeclaredFields(); - } - - for (int ctr=0; ctr: " + this); } if (selectionKey.isAcceptable()) { - AccessController.doPrivileged(new PrivilegedAction() { - public java.lang.Object run() { accept(); - return null; - } - }); } else { if (orb.transportDebugFlag) { dprint(".doWork: ! selectionKey.isAcceptable: " + this); diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java --- a/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java Fri Sep 24 16:38:05 2010 -0700 +++ b/src/share/classes/com/sun/corba/se/spi/orb/OperationFactory.java Fri Sep 24 22:42:14 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package com.sun.corba.se.spi.orb ; import java.util.StringTokenizer ; +import java.util.Arrays ; import java.lang.reflect.Array ; @@ -446,7 +447,7 @@ public String toString() { return "sequenceAction(separator=\"" + sep + "\",actions=" + - ObjectUtility.compactObjectToString(actions) + ")" ; + Arrays.toString(actions) + ")" ; } } @@ -533,7 +534,7 @@ public String toString() { return "mapSequenceAction(" + - ObjectUtility.compactObjectToString(op) + ")" ; + Arrays.toString(op) + ")" ; } } diff -r cc67fdc4fee9 -r b2fff4b7e8cd src/share/classes/com/sun/corba/se/spi/orb/ParserImplBase.java --- a/src/share/classes/com/sun/corba/se/spi/orb/ParserImplBase.java Fri Sep 24 16:38:05 2010 -0700 +++ b/src/share/classes/com/sun/corba/se/spi/orb/ParserImplBase.java Fri Sep 24 22:42:14 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -125,7 +125,7 @@ // Since exc wraps the actual exception, use exc.getCause() // instead of exc. throw wrapper.errorSettingField( exc.getCause(), name, - ObjectUtility.compactObjectToString(value) ) ; + value.toString() ) ; } }