1. /*
  2. * @(#)IIOPInputStream.java 1.74 04/06/21
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.impl.io;
  16. import java.io.InputStream;
  17. import java.io.IOException;
  18. import java.io.StreamCorruptedException;
  19. import java.io.ObjectInputValidation;
  20. import java.io.NotActiveException;
  21. import java.io.InvalidObjectException;
  22. import java.io.InvalidClassException;
  23. import java.io.DataInputStream;
  24. import java.io.OptionalDataException;
  25. import java.io.WriteAbortedException;
  26. import java.io.Externalizable;
  27. import java.io.EOFException;
  28. import java.lang.reflect.*;
  29. import java.util.Vector;
  30. import java.util.Stack;
  31. import java.util.Hashtable;
  32. import java.util.Enumeration;
  33. import sun.corba.Bridge ;
  34. import java.security.AccessController ;
  35. import java.security.PrivilegedAction ;
  36. import com.sun.corba.se.impl.io.ObjectStreamClass;
  37. import com.sun.corba.se.impl.util.Utility;
  38. import org.omg.CORBA.portable.ValueInputStream;
  39. import org.omg.CORBA.ValueMember;
  40. import org.omg.CORBA.SystemException;
  41. import org.omg.CORBA.TCKind;
  42. import org.omg.CORBA.ORB;
  43. import org.omg.CORBA.CompletionStatus;
  44. import org.omg.CORBA.portable.IndirectionException;
  45. import org.omg.CORBA.MARSHAL;
  46. import org.omg.CORBA.TypeCode;
  47. import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
  48. import com.sun.org.omg.SendingContext.CodeBase;
  49. import javax.rmi.PortableRemoteObject;
  50. import javax.rmi.CORBA.Util;
  51. import javax.rmi.CORBA.ValueHandler;
  52. import java.security.*;
  53. import java.util.*;
  54. import com.sun.corba.se.impl.orbutil.ObjectUtility ;
  55. import com.sun.corba.se.impl.logging.OMGSystemException ;
  56. import com.sun.corba.se.impl.logging.UtilSystemException ;
  57. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  58. /**
  59. * IIOPInputStream is used by the ValueHandlerImpl to handle Java serialization
  60. * input semantics.
  61. *
  62. * @author Stephen Lewallen
  63. * @since JDK1.1.6
  64. */
  65. public class IIOPInputStream
  66. extends com.sun.corba.se.impl.io.InputStreamHook
  67. {
  68. private static Bridge bridge =
  69. (Bridge)AccessController.doPrivileged(
  70. new PrivilegedAction() {
  71. public Object run() {
  72. return Bridge.get() ;
  73. }
  74. }
  75. ) ;
  76. private static OMGSystemException omgWrapper = OMGSystemException.get(
  77. CORBALogDomains.RPC_ENCODING ) ;
  78. private static UtilSystemException utilWrapper = UtilSystemException.get(
  79. CORBALogDomains.RPC_ENCODING ) ;
  80. // Necessary to pass the appropriate fields into the
  81. // defaultReadObjectDelegate method (which takes no
  82. // parameters since it's called from
  83. // java.io.ObjectInpuStream defaultReadObject()
  84. // which we can't change).
  85. //
  86. // This is only used in the case where the fields had
  87. // to be obtained remotely because of a serializable
  88. // version difference. Set in inputObjectUsingFVD.
  89. // Part of serialization evolution fixes for Ladybird,
  90. // bug 4365188.
  91. private ValueMember defaultReadObjectFVDMembers[] = null;
  92. private org.omg.CORBA_2_3.portable.InputStream orbStream;
  93. private CodeBase cbSender;
  94. private ValueHandlerImpl vhandler; //d4365188
  95. private Object currentObject = null;
  96. private ObjectStreamClass currentClassDesc = null;
  97. private Class currentClass = null;
  98. private int recursionDepth = 0;
  99. private int simpleReadDepth = 0;
  100. // The ActiveRecursionManager replaces the old RecursionManager which
  101. // used to record how many recursions were made, and resolve them after
  102. // an object was completely deserialized.
  103. //
  104. // That created problems (as in bug 4414154) because when custom
  105. // unmarshaling in readObject, there can be recursive references
  106. // to one of the objects currently being unmarshaled, and the
  107. // passive recursion system failed.
  108. ActiveRecursionManager activeRecursionMgr = new ActiveRecursionManager();
  109. private IOException abortIOException = null;
  110. /* Remember the first exception that stopped this stream. */
  111. private ClassNotFoundException abortClassNotFoundException = null;
  112. /* Vector of validation callback objects
  113. * The vector is created as needed. The vector is maintained in
  114. * order of highest (first) priority to lowest
  115. */
  116. private Vector callbacks;
  117. // Serialization machinery fields
  118. /* Arrays used to keep track of classes and ObjectStreamClasses
  119. * as they are being merged; used in inputObject.
  120. * spClass is the stack pointer for both. */
  121. ObjectStreamClass[] classdesc;
  122. Class[] classes;
  123. int spClass;
  124. private static final String kEmptyStr = "";
  125. // TCKind TypeCodes used in FVD inputClassFields
  126. //public static final TypeCode kRemoteTypeCode = new TypeCodeImpl(TCKind._tk_objref);
  127. //public static final TypeCode kValueTypeCode = new TypeCodeImpl(TCKind._tk_value);
  128. // removed TypeCodeImpl dependency
  129. public static final TypeCode kRemoteTypeCode = ORB.init().get_primitive_tc(TCKind.tk_objref);
  130. public static final TypeCode kValueTypeCode = ORB.init().get_primitive_tc(TCKind.tk_value);
  131. // TESTING CODE - useFVDOnly should be made final before FCS in order to
  132. // optimize out the check.
  133. private static final boolean useFVDOnly = false;
  134. private byte streamFormatVersion;
  135. // Since java.io.OptionalDataException's constructors are
  136. // package private, but we need to throw it in some special
  137. // cases, we try to do it by reflection.
  138. private static final Constructor OPT_DATA_EXCEPTION_CTOR;
  139. private Object[] readObjectArgList = { this } ;
  140. static {
  141. OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
  142. }
  143. // Grab the OptionalDataException boolean ctor and make
  144. // it accessible. Note that any exceptions
  145. // will be wrapped in ExceptionInInitializerErrors.
  146. private static Constructor getOptDataExceptionCtor() {
  147. try {
  148. Constructor result =
  149. (Constructor) AccessController.doPrivileged(
  150. new PrivilegedExceptionAction() {
  151. public java.lang.Object run()
  152. throws NoSuchMethodException,
  153. SecurityException {
  154. Constructor boolCtor
  155. = OptionalDataException.class.getDeclaredConstructor(
  156. new Class[] {
  157. Boolean.TYPE });
  158. boolCtor.setAccessible(true);
  159. return boolCtor;
  160. }});
  161. if (result == null)
  162. // XXX I18N, logging needed.
  163. throw new Error("Unable to find OptionalDataException constructor");
  164. return result;
  165. } catch (Exception ex) {
  166. // XXX I18N, logging needed.
  167. throw new ExceptionInInitializerError(ex);
  168. }
  169. }
  170. // Create a new OptionalDataException with the EOF marker
  171. // set to true. See handleOptionalDataMarshalException.
  172. private OptionalDataException createOptionalDataException() {
  173. try {
  174. OptionalDataException result
  175. = (OptionalDataException)
  176. OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
  177. Boolean.TRUE });
  178. if (result == null)
  179. // XXX I18N, logging needed.
  180. throw new Error("Created null OptionalDataException");
  181. return result;
  182. } catch (Exception ex) {
  183. // XXX I18N, logging needed.
  184. throw new Error("Couldn't create OptionalDataException", ex);
  185. }
  186. }
  187. // Return the stream format version currently being used
  188. // to deserialize an object
  189. protected byte getStreamFormatVersion() {
  190. return streamFormatVersion;
  191. }
  192. // At the beginning of data sent by a writeObject or
  193. // writeExternal method there is a byte telling the
  194. // reader the stream format version.
  195. private void readFormatVersion() throws IOException {
  196. streamFormatVersion = orbStream.read_octet();
  197. if (streamFormatVersion < 1 ||
  198. streamFormatVersion > vhandler.getMaximumStreamFormatVersion()) {
  199. SystemException sysex = omgWrapper.unsupportedFormatVersion(
  200. CompletionStatus.COMPLETED_MAYBE);
  201. // XXX I18N? Logging for IOException?
  202. IOException result = new IOException("Unsupported format version: "
  203. + streamFormatVersion);
  204. result.initCause( sysex ) ;
  205. throw result ;
  206. }
  207. if (streamFormatVersion == 2) {
  208. if (!(orbStream instanceof ValueInputStream)) {
  209. SystemException sysex = omgWrapper.notAValueinputstream(
  210. CompletionStatus.COMPLETED_MAYBE);
  211. // XXX I18N? Logging for IOException?
  212. IOException result = new IOException("Not a ValueInputStream");
  213. result.initCause( sysex ) ;
  214. throw result;
  215. }
  216. }
  217. }
  218. public static void setTestFVDFlag(boolean val){
  219. // useFVDOnly = val;
  220. }
  221. /**
  222. * Dummy constructor; passes upper stream a dummy stream;
  223. **/
  224. public IIOPInputStream()
  225. throws java.io.IOException {
  226. super();
  227. resetStream();
  228. }
  229. public final void setOrbStream(org.omg.CORBA_2_3.portable.InputStream os) {
  230. orbStream = os;
  231. }
  232. public final org.omg.CORBA_2_3.portable.InputStream getOrbStream() {
  233. return orbStream;
  234. }
  235. //added setSender and getSender
  236. public final void setSender(CodeBase cb) {
  237. cbSender = cb;
  238. }
  239. public final CodeBase getSender() {
  240. return cbSender;
  241. }
  242. // 4365188 this is added to enable backward compatability w/ wrong
  243. // rep-ids
  244. public final void setValueHandler(ValueHandler vh) {
  245. vhandler = (com.sun.corba.se.impl.io.ValueHandlerImpl) vh;
  246. }
  247. public final ValueHandler getValueHandler() {
  248. return (javax.rmi.CORBA.ValueHandler) vhandler;
  249. }
  250. public final void increaseRecursionDepth(){
  251. recursionDepth++;
  252. }
  253. public final int decreaseRecursionDepth(){
  254. return --recursionDepth;
  255. }
  256. /**
  257. * Override the actions of the final method "readObject()"
  258. * in ObjectInputStream.
  259. * @since JDK1.1.6
  260. *
  261. * Read an object from the ObjectInputStream.
  262. * The class of the object, the signature of the class, and the values
  263. * of the non-transient and non-static fields of the class and all
  264. * of its supertypes are read. Default deserializing for a class can be
  265. * overriden using the writeObject and readObject methods.
  266. * Objects referenced by this object are read transitively so
  267. * that a complete equivalent graph of objects is reconstructed by readObject. <p>
  268. *
  269. * The root object is completly restored when all of its fields
  270. * and the objects it references are completely restored. At this
  271. * point the object validation callbacks are executed in order
  272. * based on their registered priorities. The callbacks are
  273. * registered by objects (in the readObject special methods)
  274. * as they are individually restored.
  275. *
  276. * Exceptions are thrown for problems with the InputStream and for classes
  277. * that should not be deserialized. All exceptions are fatal to the
  278. * InputStream and leave it in an indeterminate state; it is up to the caller
  279. * to ignore or recover the stream state.
  280. * @exception java.lang.ClassNotFoundException Class of a serialized object
  281. * cannot be found.
  282. * @exception InvalidClassException Something is wrong with a class used by
  283. * serialization.
  284. * @exception StreamCorruptedException Control information in the
  285. * stream is inconsistent.
  286. * @exception OptionalDataException Primitive data was found in the
  287. * stream instead of objects.
  288. * @exception IOException Any of the usual Input/Output related exceptions.
  289. * @since JDK1.1
  290. */
  291. public final Object readObjectDelegate() throws IOException
  292. {
  293. try {
  294. readObjectState.readData(this);
  295. return orbStream.read_abstract_interface();
  296. } catch (MARSHAL marshalException) {
  297. handleOptionalDataMarshalException(marshalException, true);
  298. throw marshalException;
  299. } catch(IndirectionException cdrie)
  300. {
  301. // The CDR stream had never seen the given offset before,
  302. // so check the recursion manager (it will throw an
  303. // IOException if it doesn't have a reference, either).
  304. return activeRecursionMgr.getObject(cdrie.offset);
  305. }
  306. }
  307. final Object simpleReadObject(Class clz,
  308. String repositoryID,
  309. com.sun.org.omg.SendingContext.CodeBase sender,
  310. int offset)
  311. /* throws OptionalDataException, ClassNotFoundException, IOException */
  312. {
  313. /* Save the current state and get ready to read an object. */
  314. Object prevObject = currentObject;
  315. ObjectStreamClass prevClassDesc = currentClassDesc;
  316. Class prevClass = currentClass;
  317. byte oldStreamFormatVersion = streamFormatVersion;
  318. simpleReadDepth++; // Entering
  319. Object obj = null;
  320. /*
  321. * Check for reset, handle it before reading an object.
  322. */
  323. try {
  324. // d4365188: backward compatability
  325. if (vhandler.useFullValueDescription(clz, repositoryID)) {
  326. obj = inputObjectUsingFVD(clz, repositoryID, sender, offset);
  327. } else {
  328. obj = inputObject(clz, repositoryID, sender, offset);
  329. }
  330. obj = currentClassDesc.readResolve(obj);
  331. }
  332. catch(ClassNotFoundException cnfe)
  333. {
  334. bridge.throwException( cnfe ) ;
  335. return null;
  336. }
  337. catch(IOException ioe)
  338. {
  339. // System.out.println("CLZ = " + clz + "; " + ioe.toString());
  340. bridge.throwException(ioe) ;
  341. return null;
  342. }
  343. finally {
  344. simpleReadDepth --;
  345. currentObject = prevObject;
  346. currentClassDesc = prevClassDesc;
  347. currentClass = prevClass;
  348. streamFormatVersion = oldStreamFormatVersion;
  349. }
  350. /* Check for thrown exceptions and re-throw them, clearing them if
  351. * this is the last recursive call .
  352. */
  353. IOException exIOE = abortIOException;
  354. if (simpleReadDepth == 0)
  355. abortIOException = null;
  356. if (exIOE != null){
  357. bridge.throwException( exIOE ) ;
  358. return null;
  359. }
  360. ClassNotFoundException exCNF = abortClassNotFoundException;
  361. if (simpleReadDepth == 0)
  362. abortClassNotFoundException = null;
  363. if (exCNF != null) {
  364. bridge.throwException( exCNF ) ;
  365. return null;
  366. }
  367. return obj;
  368. }
  369. public final void simpleSkipObject(String repositoryID,
  370. com.sun.org.omg.SendingContext.CodeBase sender)
  371. /* throws OptionalDataException, ClassNotFoundException, IOException */
  372. {
  373. /* Save the current state and get ready to read an object. */
  374. Object prevObject = currentObject;
  375. ObjectStreamClass prevClassDesc = currentClassDesc;
  376. Class prevClass = currentClass;
  377. byte oldStreamFormatVersion = streamFormatVersion;
  378. simpleReadDepth++; // Entering
  379. Object obj = null;
  380. /*
  381. * Check for reset, handle it before reading an object.
  382. */
  383. try {
  384. skipObjectUsingFVD(repositoryID, sender);
  385. }
  386. catch(ClassNotFoundException cnfe)
  387. {
  388. bridge.throwException( cnfe ) ;
  389. return;
  390. }
  391. catch(IOException ioe)
  392. {
  393. bridge.throwException( ioe ) ;
  394. return;
  395. }
  396. finally {
  397. simpleReadDepth --;
  398. streamFormatVersion = oldStreamFormatVersion;
  399. currentObject = prevObject;
  400. currentClassDesc = prevClassDesc;
  401. currentClass = prevClass;
  402. }
  403. /* Check for thrown exceptions and re-throw them, clearing them if
  404. * this is the last recursive call .
  405. */
  406. IOException exIOE = abortIOException;
  407. if (simpleReadDepth == 0)
  408. abortIOException = null;
  409. if (exIOE != null){
  410. bridge.throwException( exIOE ) ;
  411. return;
  412. }
  413. ClassNotFoundException exCNF = abortClassNotFoundException;
  414. if (simpleReadDepth == 0)
  415. abortClassNotFoundException = null;
  416. if (exCNF != null) {
  417. bridge.throwException( exCNF ) ;
  418. return;
  419. }
  420. return;
  421. }
  422. /////////////////
  423. /**
  424. * This method is called by trusted subclasses of ObjectOutputStream
  425. * that constructed ObjectOutputStream using the
  426. * protected no-arg constructor. The subclass is expected to provide
  427. * an override method with the modifier "final".
  428. *
  429. * @return the Object read from the stream.
  430. *
  431. * @see #ObjectInputStream()
  432. * @see #readObject
  433. * @since JDK 1.2
  434. */
  435. protected final Object readObjectOverride()
  436. throws OptionalDataException, ClassNotFoundException, IOException
  437. {
  438. return readObjectDelegate();
  439. }
  440. /**
  441. * Override the actions of the final method "defaultReadObject()"
  442. * in ObjectInputStream.
  443. * @since JDK1.1.6
  444. *
  445. * Read the non-static and non-transient fields of the current class
  446. * from this stream. This may only be called from the readObject method
  447. * of the class being deserialized. It will throw the NotActiveException
  448. * if it is called otherwise.
  449. *
  450. * @exception java.lang.ClassNotFoundException if the class of a serialized
  451. * object could not be found.
  452. * @exception IOException if an I/O error occurs.
  453. * @exception NotActiveException if the stream is not currently reading
  454. * objects.
  455. * @since JDK1.1
  456. */
  457. public final void defaultReadObjectDelegate()
  458. /* throws IOException, ClassNotFoundException, NotActiveException */
  459. {
  460. try {
  461. if (currentObject == null || currentClassDesc == null)
  462. // XXX I18N, logging needed.
  463. throw new NotActiveException("defaultReadObjectDelegate");
  464. // The array will be null unless fields were retrieved
  465. // remotely because of a serializable version difference.
  466. // Bug fix for 4365188. See the definition of
  467. // defaultReadObjectFVDMembers for more information.
  468. if (defaultReadObjectFVDMembers != null &&
  469. defaultReadObjectFVDMembers.length > 0) {
  470. // WARNING: Be very careful! What if some of
  471. // these fields actually have to do this, too?
  472. // This works because the defaultReadObjectFVDMembers
  473. // reference is passed to inputClassFields, but
  474. // there is no guarantee that
  475. // defaultReadObjectFVDMembers will point to the
  476. // same array after calling inputClassFields.
  477. // Use the remote fields to unmarshal.
  478. inputClassFields(currentObject,
  479. currentClass,
  480. currentClassDesc,
  481. defaultReadObjectFVDMembers,
  482. cbSender);
  483. } else {
  484. // Use the local fields to unmarshal.
  485. ObjectStreamField[] fields =
  486. currentClassDesc.getFieldsNoCopy();
  487. if (fields.length > 0) {
  488. inputClassFields(currentObject, currentClass, fields, cbSender);
  489. }
  490. }
  491. }
  492. catch(NotActiveException nae)
  493. {
  494. bridge.throwException( nae ) ;
  495. }
  496. catch(IOException ioe)
  497. {
  498. bridge.throwException( ioe ) ;
  499. }
  500. catch(ClassNotFoundException cnfe)
  501. {
  502. bridge.throwException( cnfe ) ;
  503. }
  504. }
  505. /**
  506. * Override the actions of the final method "enableResolveObject()"
  507. * in ObjectInputStream.
  508. * @since JDK1.1.6
  509. *
  510. * Enable the stream to allow objects read from the stream to be replaced.
  511. * If the stream is a trusted class it is allowed to enable replacment.
  512. * Trusted classes are those classes with a classLoader equals null. <p>
  513. *
  514. * When enabled the resolveObject method is called for every object
  515. * being deserialized.
  516. *
  517. * @exception SecurityException The classloader of this stream object is non-null.
  518. * @since JDK1.1
  519. */
  520. public final boolean enableResolveObjectDelegate(boolean enable)
  521. /* throws SecurityException */
  522. {
  523. return false;
  524. }
  525. // The following three methods allow the implementing orbStream
  526. // to provide mark/reset behavior as defined in java.io.InputStream.
  527. public final void mark(int readAheadLimit) {
  528. orbStream.mark(readAheadLimit);
  529. }
  530. public final boolean markSupported() {
  531. return orbStream.markSupported();
  532. }
  533. public final void reset() throws IOException {
  534. try {
  535. orbStream.reset();
  536. } catch (Error e) {
  537. IOException err = new IOException(e.getMessage());
  538. err.initCause(e) ;
  539. throw err ;
  540. }
  541. }
  542. public final int available() throws IOException{
  543. return 0; // unreliable
  544. }
  545. public final void close() throws IOException{
  546. // no op
  547. }
  548. public final int read() throws IOException{
  549. try{
  550. readObjectState.readData(this);
  551. return (orbStream.read_octet() << 0) & 0x000000FF;
  552. } catch (MARSHAL marshalException) {
  553. if (marshalException.minor
  554. == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
  555. setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
  556. return -1;
  557. }
  558. throw marshalException;
  559. } catch(Error e) {
  560. IOException exc = new IOException(e.getMessage());
  561. exc.initCause(e) ;
  562. throw exc ;
  563. }
  564. }
  565. public final int read(byte data[], int offset, int length) throws IOException{
  566. try{
  567. readObjectState.readData(this);
  568. orbStream.read_octet_array(data, offset, length);
  569. return length;
  570. } catch (MARSHAL marshalException) {
  571. if (marshalException.minor
  572. == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
  573. setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
  574. return -1;
  575. }
  576. throw marshalException;
  577. } catch(Error e) {
  578. IOException exc = new IOException(e.getMessage());
  579. exc.initCause(e) ;
  580. throw exc ;
  581. }
  582. }
  583. public final boolean readBoolean() throws IOException{
  584. try{
  585. readObjectState.readData(this);
  586. return orbStream.read_boolean();
  587. } catch (MARSHAL marshalException) {
  588. handleOptionalDataMarshalException(marshalException, false);
  589. throw marshalException;
  590. } catch(Error e) {
  591. IOException exc = new IOException(e.getMessage());
  592. exc.initCause(e);
  593. throw exc ;
  594. }
  595. }
  596. public final byte readByte() throws IOException{
  597. try{
  598. readObjectState.readData(this);
  599. return orbStream.read_octet();
  600. } catch (MARSHAL marshalException) {
  601. handleOptionalDataMarshalException(marshalException, false);
  602. throw marshalException;
  603. } catch(Error e) {
  604. IOException exc = new IOException(e.getMessage());
  605. exc.initCause(e);
  606. throw exc ;
  607. }
  608. }
  609. public final char readChar() throws IOException{
  610. try{
  611. readObjectState.readData(this);
  612. return orbStream.read_wchar();
  613. } catch (MARSHAL marshalException) {
  614. handleOptionalDataMarshalException(marshalException, false);
  615. throw marshalException;
  616. } catch(Error e) {
  617. IOException exc = new IOException(e.getMessage());
  618. exc.initCause(e);
  619. throw exc ;
  620. }
  621. }
  622. public final double readDouble() throws IOException{
  623. try{
  624. readObjectState.readData(this);
  625. return orbStream.read_double();
  626. } catch (MARSHAL marshalException) {
  627. handleOptionalDataMarshalException(marshalException, false);
  628. throw marshalException;
  629. } catch(Error e) {
  630. IOException exc = new IOException(e.getMessage());
  631. exc.initCause(e);
  632. throw exc ;
  633. }
  634. }
  635. public final float readFloat() throws IOException{
  636. try{
  637. readObjectState.readData(this);
  638. return orbStream.read_float();
  639. } catch (MARSHAL marshalException) {
  640. handleOptionalDataMarshalException(marshalException, false);
  641. throw marshalException;
  642. } catch(Error e) {
  643. IOException exc = new IOException(e.getMessage());
  644. exc.initCause(e);
  645. throw exc ;
  646. }
  647. }
  648. public final void readFully(byte data[]) throws IOException{
  649. // d11623 : implement readFully, required for serializing some core classes
  650. readFully(data, 0, data.length);
  651. }
  652. public final void readFully(byte data[], int offset, int size) throws IOException{
  653. // d11623 : implement readFully, required for serializing some core classes
  654. try{
  655. readObjectState.readData(this);
  656. orbStream.read_octet_array(data, offset, size);
  657. } catch (MARSHAL marshalException) {
  658. handleOptionalDataMarshalException(marshalException, false);
  659. throw marshalException;
  660. } catch(Error e) {
  661. IOException exc = new IOException(e.getMessage());
  662. exc.initCause(e);
  663. throw exc ;
  664. }
  665. }
  666. public final int readInt() throws IOException{
  667. try{
  668. readObjectState.readData(this);
  669. return orbStream.read_long();
  670. } catch (MARSHAL marshalException) {
  671. handleOptionalDataMarshalException(marshalException, false);
  672. throw marshalException;
  673. } catch(Error e) {
  674. IOException exc = new IOException(e.getMessage());
  675. exc.initCause(e);
  676. throw exc ;
  677. }
  678. }
  679. public final String readLine() throws IOException{
  680. // XXX I18N, logging needed.
  681. throw new IOException("Method readLine not supported");
  682. }
  683. public final long readLong() throws IOException{
  684. try{
  685. readObjectState.readData(this);
  686. return orbStream.read_longlong();
  687. } catch (MARSHAL marshalException) {
  688. handleOptionalDataMarshalException(marshalException, false);
  689. throw marshalException;
  690. } catch(Error e) {
  691. IOException exc = new IOException(e.getMessage());
  692. exc.initCause(e);
  693. throw exc ;
  694. }
  695. }
  696. public final short readShort() throws IOException{
  697. try{
  698. readObjectState.readData(this);
  699. return orbStream.read_short();
  700. } catch (MARSHAL marshalException) {
  701. handleOptionalDataMarshalException(marshalException, false);
  702. throw marshalException;
  703. } catch(Error e) {
  704. IOException exc = new IOException(e.getMessage());
  705. exc.initCause(e);
  706. throw exc ;
  707. }
  708. }
  709. protected final void readStreamHeader() throws IOException, StreamCorruptedException{
  710. // no op
  711. }
  712. public final int readUnsignedByte() throws IOException{
  713. try{
  714. readObjectState.readData(this);
  715. return (orbStream.read_octet() << 0) & 0x000000FF;
  716. } catch (MARSHAL marshalException) {
  717. handleOptionalDataMarshalException(marshalException, false);
  718. throw marshalException;
  719. } catch(Error e) {
  720. IOException exc = new IOException(e.getMessage());
  721. exc.initCause(e);
  722. throw exc ;
  723. }
  724. }
  725. public final int readUnsignedShort() throws IOException{
  726. try{
  727. readObjectState.readData(this);
  728. return (orbStream.read_ushort() << 0) & 0x0000FFFF;
  729. } catch (MARSHAL marshalException) {
  730. handleOptionalDataMarshalException(marshalException, false);
  731. throw marshalException;
  732. } catch(Error e) {
  733. IOException exc = new IOException(e.getMessage());
  734. exc.initCause(e);
  735. throw exc ;
  736. }
  737. }
  738. /**
  739. * Helper method for correcting the Kestrel bug 4367783 (dealing
  740. * with larger than 8-bit chars). The old behavior is preserved
  741. * in orbutil.IIOPInputStream_1_3 in order to interoperate with
  742. * our legacy ORBs.
  743. */
  744. protected String internalReadUTF(org.omg.CORBA.portable.InputStream stream)
  745. {
  746. return stream.read_wstring();
  747. }
  748. public final String readUTF() throws IOException{
  749. try{
  750. readObjectState.readData(this);
  751. return internalReadUTF(orbStream);
  752. } catch (MARSHAL marshalException) {
  753. handleOptionalDataMarshalException(marshalException, false);
  754. throw marshalException;
  755. } catch(Error e) {
  756. IOException exc = new IOException(e.getMessage());
  757. exc.initCause(e);
  758. throw exc ;
  759. }
  760. }
  761. // If the ORB stream detects an incompatibility between what's
  762. // on the wire and what our Serializable's readObject wants,
  763. // it throws a MARSHAL exception with a specific minor code.
  764. // This is rethrown to the readObject as an OptionalDataException.
  765. // So far in RMI-IIOP, this process isn't specific enough to
  766. // tell the readObject how much data is available, so we always
  767. // set the OptionalDataException's EOF marker to true.
  768. private void handleOptionalDataMarshalException(MARSHAL marshalException,
  769. boolean objectRead)
  770. throws IOException {
  771. // Java Object Serialization spec 3.4: "If the readObject method
  772. // of the class attempts to read more data than is present in the
  773. // optional part of the stream for this class, the stream will
  774. // return -1 for bytewise reads, throw an EOFException for
  775. // primitive data reads, or throw an OptionalDataException
  776. // with the eof field set to true for object reads."
  777. if (marshalException.minor
  778. == OMGSystemException.RMIIIOP_OPTIONAL_DATA_INCOMPATIBLE1) {
  779. IOException result;
  780. if (!objectRead)
  781. result = new EOFException("No more optional data");
  782. else
  783. result = createOptionalDataException();
  784. result.initCause(marshalException);
  785. setState(IN_READ_OBJECT_NO_MORE_OPT_DATA);
  786. throw result;
  787. }
  788. }
  789. public final synchronized void registerValidation(ObjectInputValidation obj,
  790. int prio)
  791. throws NotActiveException, InvalidObjectException{
  792. // XXX I18N, logging needed.
  793. throw new Error("Method registerValidation not supported");
  794. }
  795. protected final Class resolveClass(ObjectStreamClass v)
  796. throws IOException, ClassNotFoundException{
  797. // XXX I18N, logging needed.
  798. throw new IOException("Method resolveClass not supported");
  799. }
  800. protected final Object resolveObject(Object obj) throws IOException{
  801. // XXX I18N, logging needed.
  802. throw new IOException("Method resolveObject not supported");
  803. }
  804. public final int skipBytes(int len) throws IOException{
  805. try{
  806. readObjectState.readData(this);
  807. byte buf[] = new byte[len];
  808. orbStream.read_octet_array(buf, 0, len);
  809. return len;
  810. } catch (MARSHAL marshalException) {
  811. handleOptionalDataMarshalException(marshalException, false);
  812. throw marshalException;
  813. } catch(Error e) {
  814. IOException exc = new IOException(e.getMessage());
  815. exc.initCause(e) ;
  816. throw exc ;
  817. }
  818. }
  819. private Object inputObject(Class clz,
  820. String repositoryID,
  821. com.sun.org.omg.SendingContext.CodeBase sender,
  822. int offset)
  823. throws IOException, ClassNotFoundException
  824. {
  825. /*
  826. * Get the descriptor and then class of the incoming object.
  827. */
  828. currentClassDesc = ObjectStreamClass.lookup(clz);
  829. currentClass = currentClassDesc.forClass();
  830. //currentClassDesc.setClass(currentClass);
  831. if (currentClass == null)
  832. // XXX I18N, logging needed.
  833. throw new ClassNotFoundException(currentClassDesc.getName());
  834. try {
  835. /* If Externalizable,
  836. * Create an instance and tell it to read its data.
  837. * else,
  838. * Handle it as a serializable class.
  839. */
  840. if (currentClassDesc.isExternalizable()) {
  841. try {
  842. currentObject = (currentClass == null) ?
  843. null : currentClassDesc.newInstance();
  844. if (currentObject != null) {
  845. // Store this object and its beginning position
  846. // since there might be indirections to it while
  847. // it's been unmarshalled.
  848. activeRecursionMgr.addObject(offset, currentObject);
  849. // Read format version
  850. readFormatVersion();
  851. Externalizable ext = (Externalizable)currentObject;
  852. ext.readExternal(this);
  853. }
  854. } catch (InvocationTargetException e) {
  855. InvalidClassException exc = new InvalidClassException(
  856. currentClass.getName(),
  857. "InvocationTargetException accessing no-arg constructor");
  858. exc.initCause( e ) ;
  859. throw exc ;
  860. } catch (UnsupportedOperationException e) {
  861. InvalidClassException exc = new InvalidClassException(
  862. currentClass.getName(),
  863. "UnsupportedOperationException accessing no-arg constructor");
  864. exc.initCause( e ) ;
  865. throw exc ;
  866. } catch (InstantiationException e) {
  867. InvalidClassException exc = new InvalidClassException(
  868. currentClass.getName(),
  869. "InstantiationException accessing no-arg constructor");
  870. exc.initCause( e ) ;
  871. throw exc ;
  872. }
  873. } // end : if (currentClassDesc.isExternalizable())
  874. else {
  875. /* Count number of classes and descriptors we might have
  876. * to work on.
  877. */
  878. ObjectStreamClass currdesc = currentClassDesc;
  879. Class currclass = currentClass;
  880. int spBase = spClass; // current top of stack
  881. /* The object's classes should be processed from supertype to subtype
  882. * Push all the clases of the current object onto a stack.
  883. * Note that only the serializable classes are represented
  884. * in the descriptor list.
  885. *
  886. * Handle versioning where one or more supertypes of
  887. * have been inserted or removed. The stack will
  888. * contain pairs of descriptors and the corresponding
  889. * class. If the object has a class that did not occur in
  890. * the original the descriptor will be null. If the
  891. * original object had a descriptor for a class not
  892. * present in the local hierarchy of the object the class will be
  893. * null.
  894. *
  895. */
  896. /*
  897. * This is your basic diff pattern, made simpler
  898. * because reordering is not allowed.
  899. */
  900. // sun.4296963 ibm.11861
  901. // d11861 we should stop when we find the highest serializable class
  902. // We need this so that when we allocate the new object below, we
  903. // can call the constructor of the non-serializable superclass.
  904. // Note that in the JRMP variant of this code the
  905. // ObjectStreamClass.lookup() method handles this, but we've put
  906. // this fix here rather than change lookup because the new behaviour
  907. // is needed in other cases.
  908. for (currdesc = currentClassDesc, currclass = currentClass;
  909. currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/
  910. currdesc = currdesc.getSuperclass()) {
  911. /*
  912. * Search the classes to see if the class of this
  913. * descriptor appears further up the hierarchy. Until
  914. * it's found assume its an inserted class. If it's
  915. * not found, its the descriptor's class that has been
  916. * removed.
  917. */
  918. Class cc = currdesc.forClass();
  919. Class cl;
  920. for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
  921. if (cc == cl) {
  922. // found a superclass that matches this descriptor
  923. break;
  924. } else {
  925. /* Ignore a class that doesn't match. No
  926. * action is needed since it is already
  927. * initialized.
  928. */
  929. }
  930. } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass())
  931. /* Test if there is room for this new entry.
  932. * If not, double the size of the arrays and copy the contents.
  933. */
  934. spClass++;
  935. if (spClass >= classes.length) {
  936. int newlen = classes.length * 2;
  937. Class[] newclasses = new Class[newlen];
  938. ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];
  939. System.arraycopy(classes, 0,
  940. newclasses, 0,
  941. classes.length);
  942. System.arraycopy(classdesc, 0,
  943. newclassdesc, 0,
  944. classes.length);
  945. classes = newclasses;
  946. classdesc = newclassdesc;
  947. }
  948. if (cl == null) {
  949. /* Class not found corresponding to this descriptor.
  950. * Pop off all the extra classes pushed.
  951. * Push the descriptor and a null class.
  952. */
  953. classdesc[spClass] = currdesc;
  954. classes[spClass] = null;
  955. } else {
  956. /* Current class descriptor matches current class.
  957. * Some classes may have been inserted.
  958. * Record the match and advance the class, continue
  959. * with the next descriptor.
  960. */
  961. classdesc[spClass] = currdesc;
  962. classes[spClass] = cl;
  963. currclass = cl.getSuperclass();
  964. }
  965. } // end : for (currdesc = currentClassDesc, currclass = currentClass;
  966. /* Allocate a new object. The object is only constructed
  967. * above the highest serializable class and is set to
  968. * default values for all more specialized classes.
  969. */
  970. try {
  971. currentObject = (currentClass == null) ?
  972. null : currentClassDesc.newInstance() ;
  973. // Store this object and its beginning position
  974. // since there might be indirections to it while
  975. // it's been unmarshalled.
  976. activeRecursionMgr.addObject(offset, currentObject);
  977. } catch (InvocationTargetException e) {
  978. InvalidClassException exc = new InvalidClassException(
  979. currentClass.getName(),
  980. "InvocationTargetException accessing no-arg constructor");
  981. exc.initCause( e ) ;
  982. throw exc ;
  983. } catch (UnsupportedOperationException e) {
  984. InvalidClassException exc = new InvalidClassException(
  985. currentClass.getName(),
  986. "UnsupportedOperationException accessing no-arg constructor");
  987. exc.initCause( e ) ;
  988. throw exc ;
  989. } catch (InstantiationException e) {
  990. InvalidClassException exc = new InvalidClassException(
  991. currentClass.getName(),
  992. "InstantiationException accessing no-arg constructor");
  993. exc.initCause( e ) ;
  994. throw exc ;
  995. }
  996. /*
  997. * For all the pushed descriptors and classes.
  998. * if the class has its own writeObject and readObject methods
  999. * call the readObject method
  1000. * else
  1001. * invoke the defaultReadObject method
  1002. */
  1003. try {
  1004. for (spClass = spClass; spClass > spBase; spClass--) {
  1005. /*
  1006. * Set current descriptor and corresponding class
  1007. */
  1008. currentClassDesc = classdesc[spClass];
  1009. currentClass = classes[spClass];
  1010. if (classes[spClass] != null) {
  1011. /* Read the data from the stream described by the
  1012. * descriptor and store into the matching class.
  1013. */
  1014. ReadObjectState oldState = readObjectState;
  1015. setState(DEFAULT_STATE);
  1016. try {
  1017. // Changed since invokeObjectReader no longer does this.
  1018. if (currentClassDesc.hasWriteObject()) {
  1019. // Read format version
  1020. readFormatVersion();
  1021. // Read defaultWriteObject indicator
  1022. boolean calledDefaultWriteObject = readBoolean();
  1023. readObjectState.beginUnmarshalCustomValue(this,
  1024. calledDefaultWriteObject,
  1025. (currentClassDesc.readObjectMethod
  1026. != null));
  1027. } else {
  1028. if (currentClassDesc.hasReadObject())
  1029. setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
  1030. }
  1031. if (!invokeObjectReader(currentClassDesc, currentObject, currentClass) ||
  1032. readObjectState == IN_READ_OBJECT_DEFAULTS_SENT) {
  1033. // Error case of no readObject and didn't call
  1034. // defaultWriteObject handled in default state
  1035. ObjectStreamField[] fields =
  1036. currentClassDesc.getFieldsNoCopy();
  1037. if (fields.length > 0) {
  1038. inputClassFields(currentObject, currentClass, fields, sender);
  1039. }
  1040. }
  1041. if (currentClassDesc.hasWriteObject())
  1042. readObjectState.endUnmarshalCustomValue(this);
  1043. } finally {
  1044. setState(oldState);
  1045. }
  1046. } else {
  1047. // _REVISIT_ : Can we ever get here?
  1048. /* No local class for this descriptor,
  1049. * Skip over the data for this class.
  1050. * like defaultReadObject with a null currentObject.
  1051. * The code will read the values but discard them.
  1052. */
  1053. ObjectStreamField[] fields =
  1054. currentClassDesc.getFieldsNoCopy();
  1055. if (fields.length > 0) {
  1056. inputClassFields(null, currentClass, fields, sender);
  1057. }
  1058. }
  1059. }
  1060. } finally {
  1061. // Make sure we exit at the same stack level as when we started.
  1062. spClass = spBase;
  1063. }
  1064. }
  1065. } finally {
  1066. // We've completed deserializing this object. Any
  1067. // future indirections will be handled correctly at the
  1068. // CDR level. The ActiveRecursionManager only deals with
  1069. // objects currently being deserialized.
  1070. activeRecursionMgr.removeObject(offset);
  1071. }
  1072. return currentObject;
  1073. }
  1074. // This retrieves a vector of FVD's for the hierarchy of serializable classes stemming from
  1075. // repositoryID. It is assumed that the sender will not provide base_value id's for non-serializable
  1076. // classes!
  1077. private Vector getOrderedDescriptions(String repositoryID,
  1078. com.sun.org.omg.SendingContext.CodeBase sender) {
  1079. Vector descs = new Vector();
  1080. if (sender == null) {
  1081. return descs;
  1082. }
  1083. FullValueDescription aFVD = sender.meta(repositoryID);
  1084. while (aFVD != null) {
  1085. descs.insertElementAt(aFVD, 0);
  1086. if ((aFVD.base_value != null) && !kEmptyStr.equals(aFVD.base_value)) {
  1087. aFVD = sender.meta(aFVD.base_value);
  1088. }
  1089. else return descs;
  1090. }
  1091. return descs;
  1092. }
  1093. /**
  1094. * This input method uses FullValueDescriptions retrieved from the sender's runtime to
  1095. * read in the data. This method is capable of throwing out data not applicable to client's fields.
  1096. * This method handles instances where the reader has a class not sent by the sender, the sender sent
  1097. * a class not present on the reader, and/or the reader's class does not match the sender's class.
  1098. *
  1099. * NOTE : If the local description indicates custom marshaling and the remote type's FVD also
  1100. * indicates custom marsahling than the local type is used to read the data off the wire. However,
  1101. * if either says custom while the other does not, a MARSHAL error is thrown. Externalizable is
  1102. * a form of custom marshaling.
  1103. *
  1104. */
  1105. private Object inputObjectUsingFVD(Class clz,
  1106. String repositoryID,
  1107. com.sun.org.omg.SendingContext.CodeBase sender,
  1108. int offset)
  1109. throws IOException, ClassNotFoundException
  1110. {
  1111. int spBase = spClass; // current top of stack
  1112. try{
  1113. /*
  1114. * Get the descriptor and then class of the incoming object.
  1115. */
  1116. ObjectStreamClass currdesc = currentClassDesc = ObjectStreamClass.lookup(clz);
  1117. Class currclass = currentClass = clz;
  1118. /* If Externalizable,
  1119. * Create an instance and tell it to read its data.
  1120. * else,
  1121. * Handle it as a serializable class.
  1122. */
  1123. if (currentClassDesc.isExternalizable()) {
  1124. try {
  1125. currentObject = (currentClass == null) ?
  1126. null : currentClassDesc.newInstance();
  1127. if (currentObject != null) {
  1128. // Store this object and its beginning position
  1129. // since there might be indirections to it while
  1130. // it's been unmarshalled.
  1131. activeRecursionMgr.addObject(offset, currentObject);
  1132. // Read format version
  1133. readFormatVersion();
  1134. Externalizable ext = (Externalizable)currentObject;
  1135. ext.readExternal(this);
  1136. }
  1137. } catch (InvocationTargetException e) {
  1138. InvalidClassException exc = new InvalidClassException(
  1139. currentClass.getName(),
  1140. "InvocationTargetException accessing no-arg constructor");
  1141. exc.initCause( e ) ;
  1142. throw exc ;
  1143. } catch (UnsupportedOperationException e) {
  1144. InvalidClassException exc = new InvalidClassException(
  1145. currentClass.getName(),
  1146. "UnsupportedOperationException accessing no-arg constructor");
  1147. exc.initCause( e ) ;
  1148. throw exc ;
  1149. } catch (InstantiationException e) {
  1150. InvalidClassException exc = new InvalidClassException(
  1151. currentClass.getName(),
  1152. "InstantiationException accessing no-arg constructor");
  1153. exc.initCause( e ) ;
  1154. throw exc ;
  1155. }
  1156. } else {
  1157. /*
  1158. * This is your basic diff pattern, made simpler
  1159. * because reordering is not allowed.
  1160. */
  1161. for (currdesc = currentClassDesc, currclass = currentClass;
  1162. currdesc != null && currdesc.isSerializable(); /*sun.4296963 ibm.11861*/
  1163. currdesc = currdesc.getSuperclass()) {
  1164. /*
  1165. * Search the classes to see if the class of this
  1166. * descriptor appears further up the hierarchy. Until
  1167. * it's found assume its an inserted class. If it's
  1168. * not found, its the descriptor's class that has been
  1169. * removed.
  1170. */
  1171. Class cc = currdesc.forClass();
  1172. Class cl;
  1173. for (cl = currclass; cl != null; cl = cl.getSuperclass()) {
  1174. if (cc == cl) {
  1175. // found a superclass that matches this descriptor
  1176. break;
  1177. } else {
  1178. /* Ignore a class that doesn't match. No
  1179. * action is needed since it is already
  1180. * initialized.
  1181. */
  1182. }
  1183. } // end : for (cl = currclass; cl != null; cl = cl.getSuperclass())
  1184. /* Test if there is room for this new entry.
  1185. * If not, double the size of the arrays and copy the contents.
  1186. */
  1187. spClass++;
  1188. if (spClass >= classes.length) {
  1189. int newlen = classes.length * 2;
  1190. Class[] newclasses = new Class[newlen];
  1191. ObjectStreamClass[] newclassdesc = new ObjectStreamClass[newlen];
  1192. System.arraycopy(classes, 0,
  1193. newclasses, 0,
  1194. classes.length);
  1195. System.arraycopy(classdesc, 0,
  1196. newclassdesc, 0,
  1197. classes.length);
  1198. classes = newclasses;
  1199. classdesc = newclassdesc;
  1200. }
  1201. if (cl == null) {
  1202. /* Class not found corresponding to this descriptor.
  1203. * Pop off all the extra classes pushed.
  1204. * Push the descriptor and a null class.
  1205. */
  1206. classdesc[spClass] = currdesc;
  1207. classes[spClass] = null;
  1208. } else {
  1209. /* Current class descriptor matches current class.
  1210. * Some classes may have been inserted.
  1211. * Record the match and advance the class, continue
  1212. * with the next descriptor.
  1213. */
  1214. classdesc[spClass] = currdesc;
  1215. classes[spClass] = cl;
  1216. currclass = cl.getSuperclass();
  1217. }
  1218. } // end : for (currdesc = currentClassDesc, currclass = currentClass;
  1219. /* Allocate a new object.
  1220. */
  1221. try {
  1222. currentObject = (currentClass == null) ?
  1223. null : currentClassDesc.newInstance();