1 /* 2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.io; 27 28 import java.io.ObjectStreamClass.WeakClassKey; 29 import java.lang.System.Logger; 30 import java.lang.ref.ReferenceQueue; 31 import java.lang.reflect.Array; 32 import java.lang.reflect.Modifier; 33 import java.lang.reflect.Proxy; 34 import java.security.AccessControlContext; 35 import java.security.AccessController; 36 import java.security.PrivilegedAction; 37 import java.security.PrivilegedActionException; 38 import java.security.PrivilegedExceptionAction; 39 import java.util.Arrays; 40 import java.util.Map; 41 import java.util.Objects; 42 import java.util.concurrent.ConcurrentHashMap; 43 import java.util.concurrent.ConcurrentMap; 44 45 import static java.io.ObjectStreamClass.processQueue; 46 47 import jdk.internal.misc.ObjectStreamClassValidator; 48 import jdk.internal.misc.SharedSecrets; 49 import jdk.internal.misc.Unsafe; 50 import sun.reflect.misc.ReflectUtil; 51 52 /** 53 * An ObjectInputStream deserializes primitive data and objects previously 54 * written using an ObjectOutputStream. 55 * 56 * <p>ObjectOutputStream and ObjectInputStream can provide an application with 57 * persistent storage for graphs of objects when used with a FileOutputStream 58 * and FileInputStream respectively. ObjectInputStream is used to recover 59 * those objects previously serialized. Other uses include passing objects 60 * between hosts using a socket stream or for marshaling and unmarshaling 61 * arguments and parameters in a remote communication system. 62 * 63 * <p>ObjectInputStream ensures that the types of all objects in the graph 64 * created from the stream match the classes present in the Java Virtual 65 * Machine. Classes are loaded as required using the standard mechanisms. 66 * 67 * <p>Only objects that support the java.io.Serializable or 68 * java.io.Externalizable interface can be read from streams. 69 * 70 * <p>The method <code>readObject</code> is used to read an object from the 71 * stream. Java's safe casting should be used to get the desired type. In 72 * Java, strings and arrays are objects and are treated as objects during 73 * serialization. When read they need to be cast to the expected type. 74 * 75 * <p>Primitive data types can be read from the stream using the appropriate 76 * method on DataInput. 77 * 78 * <p>The default deserialization mechanism for objects restores the contents 79 * of each field to the value and type it had when it was written. Fields 80 * declared as transient or static are ignored by the deserialization process. 81 * References to other objects cause those objects to be read from the stream 82 * as necessary. Graphs of objects are restored correctly using a reference 83 * sharing mechanism. New objects are always allocated when deserializing, 84 * which prevents existing objects from being overwritten. 85 * 86 * <p>Reading an object is analogous to running the constructors of a new 87 * object. Memory is allocated for the object and initialized to zero (NULL). 88 * No-arg constructors are invoked for the non-serializable classes and then 89 * the fields of the serializable classes are restored from the stream starting 90 * with the serializable class closest to java.lang.object and finishing with 91 * the object's most specific class. 92 * 93 * <p>For example to read from a stream as written by the example in 94 * ObjectOutputStream: 95 * <br> 96 * <pre> 97 * FileInputStream fis = new FileInputStream("t.tmp"); 98 * ObjectInputStream ois = new ObjectInputStream(fis); 99 * 100 * int i = ois.readInt(); 101 * String today = (String) ois.readObject(); 102 * Date date = (Date) ois.readObject(); 103 * 104 * ois.close(); 105 * </pre> 106 * 107 * <p>Classes control how they are serialized by implementing either the 108 * java.io.Serializable or java.io.Externalizable interfaces. 109 * 110 * <p>Implementing the Serializable interface allows object serialization to 111 * save and restore the entire state of the object and it allows classes to 112 * evolve between the time the stream is written and the time it is read. It 113 * automatically traverses references between objects, saving and restoring 114 * entire graphs. 115 * 116 * <p>Serializable classes that require special handling during the 117 * serialization and deserialization process should implement the following 118 * methods: 119 * 120 * <pre> 121 * private void writeObject(java.io.ObjectOutputStream stream) 122 * throws IOException; 123 * private void readObject(java.io.ObjectInputStream stream) 124 * throws IOException, ClassNotFoundException; 125 * private void readObjectNoData() 126 * throws ObjectStreamException; 127 * </pre> 128 * 129 * <p>The readObject method is responsible for reading and restoring the state 130 * of the object for its particular class using data written to the stream by 131 * the corresponding writeObject method. The method does not need to concern 132 * itself with the state belonging to its superclasses or subclasses. State is 133 * restored by reading data from the ObjectInputStream for the individual 134 * fields and making assignments to the appropriate fields of the object. 135 * Reading primitive data types is supported by DataInput. 136 * 137 * <p>Any attempt to read object data which exceeds the boundaries of the 138 * custom data written by the corresponding writeObject method will cause an 139 * OptionalDataException to be thrown with an eof field value of true. 140 * Non-object reads which exceed the end of the allotted data will reflect the 141 * end of data in the same way that they would indicate the end of the stream: 142 * bytewise reads will return -1 as the byte read or number of bytes read, and 143 * primitive reads will throw EOFExceptions. If there is no corresponding 144 * writeObject method, then the end of default serialized data marks the end of 145 * the allotted data. 146 * 147 * <p>Primitive and object read calls issued from within a readExternal method 148 * behave in the same manner--if the stream is already positioned at the end of 149 * data written by the corresponding writeExternal method, object reads will 150 * throw OptionalDataExceptions with eof set to true, bytewise reads will 151 * return -1, and primitive reads will throw EOFExceptions. Note that this 152 * behavior does not hold for streams written with the old 153 * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the 154 * end of data written by writeExternal methods is not demarcated, and hence 155 * cannot be detected. 156 * 157 * <p>The readObjectNoData method is responsible for initializing the state of 158 * the object for its particular class in the event that the serialization 159 * stream does not list the given class as a superclass of the object being 160 * deserialized. This may occur in cases where the receiving party uses a 161 * different version of the deserialized instance's class than the sending 162 * party, and the receiver's version extends classes that are not extended by 163 * the sender's version. This may also occur if the serialization stream has 164 * been tampered; hence, readObjectNoData is useful for initializing 165 * deserialized objects properly despite a "hostile" or incomplete source 166 * stream. 167 * 168 * <p>Serialization does not read or assign values to the fields of any object 169 * that does not implement the java.io.Serializable interface. Subclasses of 170 * Objects that are not serializable can be serializable. In this case the 171 * non-serializable class must have a no-arg constructor to allow its fields to 172 * be initialized. In this case it is the responsibility of the subclass to 173 * save and restore the state of the non-serializable class. It is frequently 174 * the case that the fields of that class are accessible (public, package, or 175 * protected) or that there are get and set methods that can be used to restore 176 * the state. 177 * 178 * <p>The contents of the stream can be filtered during deserialization. 179 * If a {@linkplain #setObjectInputFilter(ObjectInputFilter) filter is set} 180 * on an ObjectInputStream, the {@link ObjectInputFilter} can check that 181 * the classes, array lengths, number of references in the stream, depth, and 182 * number of bytes consumed from the input stream are allowed and 183 * if not, can terminate deserialization. 184 * A {@linkplain ObjectInputFilter.Config#setSerialFilter(ObjectInputFilter) process-wide filter} 185 * can be configured that is applied to each {@code ObjectInputStream} unless replaced 186 * using {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter}. 187 * 188 * <p>Any exception that occurs while deserializing an object will be caught by 189 * the ObjectInputStream and abort the reading process. 190 * 191 * <p>Implementing the Externalizable interface allows the object to assume 192 * complete control over the contents and format of the object's serialized 193 * form. The methods of the Externalizable interface, writeExternal and 194 * readExternal, are called to save and restore the objects state. When 195 * implemented by a class they can write and read their own state using all of 196 * the methods of ObjectOutput and ObjectInput. It is the responsibility of 197 * the objects to handle any versioning that occurs. 198 * 199 * <p>Enum constants are deserialized differently than ordinary serializable or 200 * externalizable objects. The serialized form of an enum constant consists 201 * solely of its name; field values of the constant are not transmitted. To 202 * deserialize an enum constant, ObjectInputStream reads the constant name from 203 * the stream; the deserialized constant is then obtained by calling the static 204 * method <code>Enum.valueOf(Class, String)</code> with the enum constant's 205 * base type and the received constant name as arguments. Like other 206 * serializable or externalizable objects, enum constants can function as the 207 * targets of back references appearing subsequently in the serialization 208 * stream. The process by which enum constants are deserialized cannot be 209 * customized: any class-specific readObject, readObjectNoData, and readResolve 210 * methods defined by enum types are ignored during deserialization. 211 * Similarly, any serialPersistentFields or serialVersionUID field declarations 212 * are also ignored--all enum types have a fixed serialVersionUID of 0L. 213 * 214 * @author Mike Warres 215 * @author Roger Riggs 216 * @see java.io.DataInput 217 * @see java.io.ObjectOutputStream 218 * @see java.io.Serializable 219 * @see <a href="{@docRoot}/../specs/serialization/input.html"> 220 * Object Serialization Specification, Section 3, Object Input Classes</a> 221 * @since 1.1 222 */ 223 public class ObjectInputStream 224 extends InputStream implements ObjectInput, ObjectStreamConstants 225 { 226 /** handle value representing null */ 227 private static final int NULL_HANDLE = -1; 228 229 /** marker for unshared objects in internal handle table */ 230 private static final Object unsharedMarker = new Object(); 231 232 /** 233 * immutable table mapping primitive type names to corresponding 234 * class objects 235 */ 236 private static final Map<String, Class<?>> primClasses = 237 Map.of("boolean", boolean.class, 238 "byte", byte.class, 239 "char", char.class, 240 "short", short.class, 241 "int", int.class, 242 "long", long.class, 243 "float", float.class, 244 "double", double.class, 245 "void", void.class); 246 247 private static class Caches { 248 /** cache of subclass security audit results */ 249 static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits = 250 new ConcurrentHashMap<>(); 251 252 /** queue for WeakReferences to audited subclasses */ 253 static final ReferenceQueue<Class<?>> subclassAuditsQueue = 254 new ReferenceQueue<>(); 255 } 256 257 /* 258 * Separate class to defer initialization of logging until needed. 259 */ 260 private static class Logging { 261 /* 262 * Logger for ObjectInputFilter results. 263 * Setup the filter logger if it is set to DEBUG or TRACE. 264 * (Assuming it will not change). 265 */ 266 static final System.Logger filterLogger; 267 268 static { 269 Logger filterLog = System.getLogger("java.io.serialization"); 270 filterLogger = (filterLog.isLoggable(Logger.Level.DEBUG) 271 || filterLog.isLoggable(Logger.Level.TRACE)) ? filterLog : null; 272 } 273 } 274 275 /** filter stream for handling block data conversion */ 276 private final BlockDataInputStream bin; 277 /** validation callback list */ 278 private final ValidationList vlist; 279 /** recursion depth */ 280 private long depth; 281 /** Total number of references to any type of object, class, enum, proxy, etc. */ 282 private long totalObjectRefs; 283 /** whether stream is closed */ 284 private boolean closed; 285 286 /** wire handle -> obj/exception map */ 287 private final HandleTable handles; 288 /** scratch field for passing handle values up/down call stack */ 289 private int passHandle = NULL_HANDLE; 290 /** flag set when at end of field value block with no TC_ENDBLOCKDATA */ 291 private boolean defaultDataEnd = false; 292 293 /** if true, invoke readObjectOverride() instead of readObject() */ 294 private final boolean enableOverride; 295 /** if true, invoke resolveObject() */ 296 private boolean enableResolve; 297 298 /** 299 * Context during upcalls to class-defined readObject methods; holds 300 * object currently being deserialized and descriptor for current class. 301 * Null when not during readObject upcall. 302 */ 303 private SerialCallbackContext curContext; 304 305 /** 306 * Filter of class descriptors and classes read from the stream; 307 * may be null. 308 */ 309 private ObjectInputFilter serialFilter; 310 311 /** 312 * Creates an ObjectInputStream that reads from the specified InputStream. 313 * A serialization stream header is read from the stream and verified. 314 * This constructor will block until the corresponding ObjectOutputStream 315 * has written and flushed the header. 316 * 317 * <p>The serialization filter is initialized to the value of 318 * {@linkplain ObjectInputFilter.Config#getSerialFilter() the process-wide filter}. 319 * 320 * <p>If a security manager is installed, this constructor will check for 321 * the "enableSubclassImplementation" SerializablePermission when invoked 322 * directly or indirectly by the constructor of a subclass which overrides 323 * the ObjectInputStream.readFields or ObjectInputStream.readUnshared 324 * methods. 325 * 326 * @param in input stream to read from 327 * @throws StreamCorruptedException if the stream header is incorrect 328 * @throws IOException if an I/O error occurs while reading stream header 329 * @throws SecurityException if untrusted subclass illegally overrides 330 * security-sensitive methods 331 * @throws NullPointerException if <code>in</code> is <code>null</code> 332 * @see ObjectInputStream#ObjectInputStream() 333 * @see ObjectInputStream#readFields() 334 * @see ObjectOutputStream#ObjectOutputStream(OutputStream) 335 */ 336 public ObjectInputStream(InputStream in) throws IOException { 337 verifySubclass(); 338 bin = new BlockDataInputStream(in); 339 handles = new HandleTable(10); 340 vlist = new ValidationList(); 341 serialFilter = ObjectInputFilter.Config.getSerialFilter(); 342 enableOverride = false; 343 readStreamHeader(); 344 bin.setBlockDataMode(true); 345 } 346 347 /** 348 * Provide a way for subclasses that are completely reimplementing 349 * ObjectInputStream to not have to allocate private data just used by this 350 * implementation of ObjectInputStream. 351 * 352 * <p>The serialization filter is initialized to the value of 353 * {@linkplain ObjectInputFilter.Config#getSerialFilter() the process-wide filter}. 354 * 355 * <p>If there is a security manager installed, this method first calls the 356 * security manager's <code>checkPermission</code> method with the 357 * <code>SerializablePermission("enableSubclassImplementation")</code> 358 * permission to ensure it's ok to enable subclassing. 359 * 360 * @throws SecurityException if a security manager exists and its 361 * <code>checkPermission</code> method denies enabling 362 * subclassing. 363 * @throws IOException if an I/O error occurs while creating this stream 364 * @see SecurityManager#checkPermission 365 * @see java.io.SerializablePermission 366 */ 367 protected ObjectInputStream() throws IOException, SecurityException { 368 SecurityManager sm = System.getSecurityManager(); 369 if (sm != null) { 370 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 371 } 372 bin = null; 373 handles = null; 374 vlist = null; 375 serialFilter = ObjectInputFilter.Config.getSerialFilter(); 376 enableOverride = true; 377 } 378 379 private ClassLoader cachedLoader = null; 380 381 /** 382 * Read an object from the ObjectInputStream. The class of the object, the 383 * signature of the class, and the values of the non-transient and 384 * non-static fields of the class and all of its supertypes are read. 385 * Default deserializing for a class can be overridden using the writeObject 386 * and readObject methods. Objects referenced by this object are read 387 * transitively so that a complete equivalent graph of objects is 388 * reconstructed by readObject. 389 * 390 * <p>The root object is completely restored when all of its fields and the 391 * objects it references are completely restored. At this point the object 392 * validation callbacks are executed in order based on their registered 393 * priorities. The callbacks are registered by objects (in the readObject 394 * special methods) as they are individually restored. 395 * 396 * <p>The serialization filter, when not {@code null}, is invoked for 397 * each object (regular or class) read to reconstruct the root object. 398 * See {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter} for details. 399 * 400 * <p>Exceptions are thrown for problems with the InputStream and for 401 * classes that should not be deserialized. All exceptions are fatal to 402 * the InputStream and leave it in an indeterminate state; it is up to the 403 * caller to ignore or recover the stream state. 404 * 405 * @throws ClassNotFoundException Class of a serialized object cannot be 406 * found. 407 * @throws InvalidClassException Something is wrong with a class used by 408 * serialization. 409 * @throws StreamCorruptedException Control information in the 410 * stream is inconsistent. 411 * @throws OptionalDataException Primitive data was found in the 412 * stream instead of objects. 413 * @throws IOException Any of the usual Input/Output related exceptions. 414 */ 415 public final Object readObject() 416 throws IOException, ClassNotFoundException 417 { 418 if (enableOverride) { 419 return readObjectOverride(); 420 } 421 422 ClassLoader prevClassLoader = null; 423 boolean cached = false; 424 if (curContext == null) { 425 prevClassLoader = cachedLoader; 426 cachedLoader = latestUserDefinedLoader(); 427 cached = true; 428 } 429 430 // if nested read, passHandle contains handle of enclosing object 431 int outerHandle = passHandle; 432 try { 433 Object obj = readObject0(false); 434 handles.markDependency(outerHandle, passHandle); 435 ClassNotFoundException ex = handles.lookupException(passHandle); 436 if (ex != null) { 437 throw ex; 438 } 439 if (depth == 0) { 440 vlist.doCallbacks(); 441 freeze(); 442 } 443 return obj; 444 } finally { 445 passHandle = outerHandle; 446 if (cached) { 447 cachedLoader = prevClassLoader; 448 } 449 if (closed && depth == 0) { 450 clear(); 451 } 452 } 453 } 454 455 /** 456 * This method is called by trusted subclasses of ObjectOutputStream that 457 * constructed ObjectOutputStream using the protected no-arg constructor. 458 * The subclass is expected to provide an override method with the modifier 459 * "final". 460 * 461 * @return the Object read from the stream. 462 * @throws ClassNotFoundException Class definition of a serialized object 463 * cannot be found. 464 * @throws OptionalDataException Primitive data was found in the stream 465 * instead of objects. 466 * @throws IOException if I/O errors occurred while reading from the 467 * underlying stream 468 * @see #ObjectInputStream() 469 * @see #readObject() 470 * @since 1.2 471 */ 472 protected Object readObjectOverride() 473 throws IOException, ClassNotFoundException 474 { 475 return null; 476 } 477 478 /** 479 * Reads an "unshared" object from the ObjectInputStream. This method is 480 * identical to readObject, except that it prevents subsequent calls to 481 * readObject and readUnshared from returning additional references to the 482 * deserialized instance obtained via this call. Specifically: 483 * <ul> 484 * <li>If readUnshared is called to deserialize a back-reference (the 485 * stream representation of an object which has been written 486 * previously to the stream), an ObjectStreamException will be 487 * thrown. 488 * 489 * <li>If readUnshared returns successfully, then any subsequent attempts 490 * to deserialize back-references to the stream handle deserialized 491 * by readUnshared will cause an ObjectStreamException to be thrown. 492 * </ul> 493 * Deserializing an object via readUnshared invalidates the stream handle 494 * associated with the returned object. Note that this in itself does not 495 * always guarantee that the reference returned by readUnshared is unique; 496 * the deserialized object may define a readResolve method which returns an 497 * object visible to other parties, or readUnshared may return a Class 498 * object or enum constant obtainable elsewhere in the stream or through 499 * external means. If the deserialized object defines a readResolve method 500 * and the invocation of that method returns an array, then readUnshared 501 * returns a shallow clone of that array; this guarantees that the returned 502 * array object is unique and cannot be obtained a second time from an 503 * invocation of readObject or readUnshared on the ObjectInputStream, 504 * even if the underlying data stream has been manipulated. 505 * 506 * <p>The serialization filter, when not {@code null}, is invoked for 507 * each object (regular or class) read to reconstruct the root object. 508 * See {@link #setObjectInputFilter(ObjectInputFilter) setObjectInputFilter} for details. 509 * 510 * <p>ObjectInputStream subclasses which override this method can only be 511 * constructed in security contexts possessing the 512 * "enableSubclassImplementation" SerializablePermission; any attempt to 513 * instantiate such a subclass without this permission will cause a 514 * SecurityException to be thrown. 515 * 516 * @return reference to deserialized object 517 * @throws ClassNotFoundException if class of an object to deserialize 518 * cannot be found 519 * @throws StreamCorruptedException if control information in the stream 520 * is inconsistent 521 * @throws ObjectStreamException if object to deserialize has already 522 * appeared in stream 523 * @throws OptionalDataException if primitive data is next in stream 524 * @throws IOException if an I/O error occurs during deserialization 525 * @since 1.4 526 */ 527 public Object readUnshared() throws IOException, ClassNotFoundException { 528 ClassLoader prevClassLoader = null; 529 boolean cached = false; 530 if (curContext == null) { 531 prevClassLoader = cachedLoader; 532 cachedLoader = latestUserDefinedLoader(); 533 cached = true; 534 } 535 // if nested read, passHandle contains handle of enclosing object 536 int outerHandle = passHandle; 537 try { 538 Object obj = readObject0(true); 539 handles.markDependency(outerHandle, passHandle); 540 ClassNotFoundException ex = handles.lookupException(passHandle); 541 if (ex != null) { 542 throw ex; 543 } 544 if (depth == 0) { 545 vlist.doCallbacks(); 546 freeze(); 547 } 548 return obj; 549 } finally { 550 passHandle = outerHandle; 551 if (cached) { 552 cachedLoader = prevClassLoader; 553 } 554 if (closed && depth == 0) { 555 clear(); 556 } 557 } 558 } 559 560 /** 561 * Read the non-static and non-transient fields of the current class from 562 * this stream. This may only be called from the readObject method of the 563 * class being deserialized. It will throw the NotActiveException if it is 564 * called otherwise. 565 * 566 * @throws ClassNotFoundException if the class of a serialized object 567 * could not be found. 568 * @throws IOException if an I/O error occurs. 569 * @throws NotActiveException if the stream is not currently reading 570 * objects. 571 */ 572 public void defaultReadObject() 573 throws IOException, ClassNotFoundException 574 { 575 SerialCallbackContext ctx = curContext; 576 if (ctx == null) { 577 throw new NotActiveException("not in call to readObject"); 578 } 579 Object curObj = ctx.getObj(); 580 ObjectStreamClass curDesc = ctx.getDesc(); 581 bin.setBlockDataMode(false); 582 FieldValues vals = defaultReadFields(curObj, curDesc); 583 if (curObj != null) { 584 defaultCheckFieldValues(curObj, curDesc, vals); 585 defaultSetFieldValues(curObj, curDesc, vals); 586 } 587 bin.setBlockDataMode(true); 588 if (!curDesc.hasWriteObjectData()) { 589 /* 590 * Fix for 4360508: since stream does not contain terminating 591 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere 592 * knows to simulate end-of-custom-data behavior. 593 */ 594 defaultDataEnd = true; 595 } 596 ClassNotFoundException ex = handles.lookupException(passHandle); 597 if (ex != null) { 598 throw ex; 599 } 600 } 601 602 /** 603 * Reads the persistent fields from the stream and makes them available by 604 * name. 605 * 606 * @return the <code>GetField</code> object representing the persistent 607 * fields of the object being deserialized 608 * @throws ClassNotFoundException if the class of a serialized object 609 * could not be found. 610 * @throws IOException if an I/O error occurs. 611 * @throws NotActiveException if the stream is not currently reading 612 * objects. 613 * @since 1.2 614 */ 615 public ObjectInputStream.GetField readFields() 616 throws IOException, ClassNotFoundException 617 { 618 SerialCallbackContext ctx = curContext; 619 if (ctx == null) { 620 throw new NotActiveException("not in call to readObject"); 621 } 622 ctx.checkAndSetUsed(); 623 ObjectStreamClass curDesc = ctx.getDesc(); 624 bin.setBlockDataMode(false); 625 GetFieldImpl getField = new GetFieldImpl(curDesc); 626 getField.readFields(); 627 bin.setBlockDataMode(true); 628 if (!curDesc.hasWriteObjectData()) { 629 /* 630 * Fix for 4360508: since stream does not contain terminating 631 * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere 632 * knows to simulate end-of-custom-data behavior. 633 */ 634 defaultDataEnd = true; 635 } 636 637 return getField; 638 } 639 640 /** 641 * Register an object to be validated before the graph is returned. While 642 * similar to resolveObject these validations are called after the entire 643 * graph has been reconstituted. Typically, a readObject method will 644 * register the object with the stream so that when all of the objects are 645 * restored a final set of validations can be performed. 646 * 647 * @param obj the object to receive the validation callback. 648 * @param prio controls the order of callbacks;zero is a good default. 649 * Use higher numbers to be called back earlier, lower numbers for 650 * later callbacks. Within a priority, callbacks are processed in 651 * no particular order. 652 * @throws NotActiveException The stream is not currently reading objects 653 * so it is invalid to register a callback. 654 * @throws InvalidObjectException The validation object is null. 655 */ 656 public void registerValidation(ObjectInputValidation obj, int prio) 657 throws NotActiveException, InvalidObjectException 658 { 659 if (depth == 0) { 660 throw new NotActiveException("stream inactive"); 661 } 662 vlist.register(obj, prio); 663 } 664 665 /** 666 * Load the local class equivalent of the specified stream class 667 * description. Subclasses may implement this method to allow classes to 668 * be fetched from an alternate source. 669 * 670 * <p>The corresponding method in <code>ObjectOutputStream</code> is 671 * <code>annotateClass</code>. This method will be invoked only once for 672 * each unique class in the stream. This method can be implemented by 673 * subclasses to use an alternate loading mechanism but must return a 674 * <code>Class</code> object. Once returned, if the class is not an array 675 * class, its serialVersionUID is compared to the serialVersionUID of the 676 * serialized class, and if there is a mismatch, the deserialization fails 677 * and an {@link InvalidClassException} is thrown. 678 * 679 * <p>The default implementation of this method in 680 * <code>ObjectInputStream</code> returns the result of calling 681 * <pre> 682 * Class.forName(desc.getName(), false, loader) 683 * </pre> 684 * where <code>loader</code> is the first class loader on the current 685 * thread's stack (starting from the currently executing method) that is 686 * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform 687 * class loader} nor its ancestor; otherwise, <code>loader</code> is the 688 * <em>platform class loader</em>. If this call results in a 689 * <code>ClassNotFoundException</code> and the name of the passed 690 * <code>ObjectStreamClass</code> instance is the Java language keyword 691 * for a primitive type or void, then the <code>Class</code> object 692 * representing that primitive type or void will be returned 693 * (e.g., an <code>ObjectStreamClass</code> with the name 694 * <code>"int"</code> will be resolved to <code>Integer.TYPE</code>). 695 * Otherwise, the <code>ClassNotFoundException</code> will be thrown to 696 * the caller of this method. 697 * 698 * @param desc an instance of class <code>ObjectStreamClass</code> 699 * @return a <code>Class</code> object corresponding to <code>desc</code> 700 * @throws IOException any of the usual Input/Output exceptions. 701 * @throws ClassNotFoundException if class of a serialized object cannot 702 * be found. 703 */ 704 protected Class<?> resolveClass(ObjectStreamClass desc) 705 throws IOException, ClassNotFoundException 706 { 707 String name = desc.getName(); 708 try { 709 if (cachedLoader != null) 710 return Class.forName(name, false, cachedLoader); 711 else 712 return Class.forName(name, false, latestUserDefinedLoader()); 713 } catch (ClassNotFoundException ex) { 714 Class<?> cl = primClasses.get(name); 715 if (cl != null) { 716 return cl; 717 } else { 718 throw ex; 719 } 720 } 721 } 722 723 /** 724 * Returns a proxy class that implements the interfaces named in a proxy 725 * class descriptor; subclasses may implement this method to read custom 726 * data from the stream along with the descriptors for dynamic proxy 727 * classes, allowing them to use an alternate loading mechanism for the 728 * interfaces and the proxy class. 729 * 730 * <p>This method is called exactly once for each unique proxy class 731 * descriptor in the stream. 732 * 733 * <p>The corresponding method in <code>ObjectOutputStream</code> is 734 * <code>annotateProxyClass</code>. For a given subclass of 735 * <code>ObjectInputStream</code> that overrides this method, the 736 * <code>annotateProxyClass</code> method in the corresponding subclass of 737 * <code>ObjectOutputStream</code> must write any data or objects read by 738 * this method. 739 * 740 * <p>The default implementation of this method in 741 * <code>ObjectInputStream</code> returns the result of calling 742 * <code>Proxy.getProxyClass</code> with the list of <code>Class</code> 743 * objects for the interfaces that are named in the <code>interfaces</code> 744 * parameter. The <code>Class</code> object for each interface name 745 * <code>i</code> is the value returned by calling 746 * <pre> 747 * Class.forName(i, false, loader) 748 * </pre> 749 * where <code>loader</code> is the first class loader on the current 750 * thread's stack (starting from the currently executing method) that is 751 * neither the {@linkplain ClassLoader#getPlatformClassLoader() platform 752 * class loader} nor its ancestor; otherwise, <code>loader</code> is the 753 * <em>platform class loader</em>. 754 * Unless any of the resolved interfaces are non-public, this same value 755 * of <code>loader</code> is also the class loader passed to 756 * <code>Proxy.getProxyClass</code>; if non-public interfaces are present, 757 * their class loader is passed instead (if more than one non-public 758 * interface class loader is encountered, an 759 * <code>IllegalAccessError</code> is thrown). 760 * If <code>Proxy.getProxyClass</code> throws an 761 * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code> 762 * will throw a <code>ClassNotFoundException</code> containing the 763 * <code>IllegalArgumentException</code>. 764 * 765 * @param interfaces the list of interface names that were 766 * deserialized in the proxy class descriptor 767 * @return a proxy class for the specified interfaces 768 * @throws IOException any exception thrown by the underlying 769 * <code>InputStream</code> 770 * @throws ClassNotFoundException if the proxy class or any of the 771 * named interfaces could not be found 772 * @see ObjectOutputStream#annotateProxyClass(Class) 773 * @since 1.3 774 */ 775 protected Class<?> resolveProxyClass(String[] interfaces) 776 throws IOException, ClassNotFoundException 777 { 778 ClassLoader latestLoader = latestUserDefinedLoader(); 779 ClassLoader nonPublicLoader = null; 780 boolean hasNonPublicInterface = false; 781 782 // define proxy in class loader of non-public interface(s), if any 783 Class<?>[] classObjs = new Class<?>[interfaces.length]; 784 for (int i = 0; i < interfaces.length; i++) { 785 Class<?> cl = Class.forName(interfaces[i], false, latestLoader); 786 if ((cl.getModifiers() & Modifier.PUBLIC) == 0) { 787 if (hasNonPublicInterface) { 788 if (nonPublicLoader != cl.getClassLoader()) { 789 throw new IllegalAccessError( 790 "conflicting non-public interface class loaders"); 791 } 792 } else { 793 nonPublicLoader = cl.getClassLoader(); 794 hasNonPublicInterface = true; 795 } 796 } 797 classObjs[i] = cl; 798 } 799 try { 800 @SuppressWarnings("deprecation") 801 Class<?> proxyClass = Proxy.getProxyClass( 802 hasNonPublicInterface ? nonPublicLoader : latestLoader, 803 classObjs); 804 return proxyClass; 805 } catch (IllegalArgumentException e) { 806 throw new ClassNotFoundException(null, e); 807 } 808 } 809 810 /** 811 * This method will allow trusted subclasses of ObjectInputStream to 812 * substitute one object for another during deserialization. Replacing 813 * objects is disabled until enableResolveObject is called. The 814 * enableResolveObject method checks that the stream requesting to resolve 815 * object can be trusted. Every reference to serializable objects is passed 816 * to resolveObject. To insure that the private state of objects is not 817 * unintentionally exposed only trusted streams may use resolveObject. 818 * 819 * <p>This method is called after an object has been read but before it is 820 * returned from readObject. The default resolveObject method just returns 821 * the same object. 822 * 823 * <p>When a subclass is replacing objects it must insure that the 824 * substituted object is compatible with every field where the reference 825 * will be stored. Objects whose type is not a subclass of the type of the 826 * field or array element abort the serialization by raising an exception 827 * and the object is not be stored. 828 * 829 * <p>This method is called only once when each object is first 830 * encountered. All subsequent references to the object will be redirected 831 * to the new object. 832 * 833 * @param obj object to be substituted 834 * @return the substituted object 835 * @throws IOException Any of the usual Input/Output exceptions. 836 */ 837 protected Object resolveObject(Object obj) throws IOException { 838 return obj; 839 } 840 841 /** 842 * Enables the stream to do replacement of objects read from the stream. When 843 * enabled, the {@link #resolveObject} method is called for every object being 844 * deserialized. 845 * 846 * <p>If object replacement is currently not enabled, and 847 * {@code enable} is true, and there is a security manager installed, 848 * this method first calls the security manager's 849 * {@code checkPermission} method with the 850 * {@code SerializablePermission("enableSubstitution")} permission to 851 * ensure that the caller is permitted to enable the stream to do replacement 852 * of objects read from the stream. 853 * 854 * @param enable true for enabling use of {@code resolveObject} for 855 * every object being deserialized 856 * @return the previous setting before this method was invoked 857 * @throws SecurityException if a security manager exists and its 858 * {@code checkPermission} method denies enabling the stream 859 * to do replacement of objects read from the stream. 860 * @see SecurityManager#checkPermission 861 * @see java.io.SerializablePermission 862 */ 863 protected boolean enableResolveObject(boolean enable) 864 throws SecurityException 865 { 866 if (enable == enableResolve) { 867 return enable; 868 } 869 if (enable) { 870 SecurityManager sm = System.getSecurityManager(); 871 if (sm != null) { 872 sm.checkPermission(SUBSTITUTION_PERMISSION); 873 } 874 } 875 enableResolve = enable; 876 return !enableResolve; 877 } 878 879 /** 880 * The readStreamHeader method is provided to allow subclasses to read and 881 * verify their own stream headers. It reads and verifies the magic number 882 * and version number. 883 * 884 * @throws IOException if there are I/O errors while reading from the 885 * underlying <code>InputStream</code> 886 * @throws StreamCorruptedException if control information in the stream 887 * is inconsistent 888 */ 889 protected void readStreamHeader() 890 throws IOException, StreamCorruptedException 891 { 892 short s0 = bin.readShort(); 893 short s1 = bin.readShort(); 894 if (s0 != STREAM_MAGIC || s1 != STREAM_VERSION) { 895 throw new StreamCorruptedException( 896 String.format("invalid stream header: %04X%04X", s0, s1)); 897 } 898 } 899 900 /** 901 * Read a class descriptor from the serialization stream. This method is 902 * called when the ObjectInputStream expects a class descriptor as the next 903 * item in the serialization stream. Subclasses of ObjectInputStream may 904 * override this method to read in class descriptors that have been written 905 * in non-standard formats (by subclasses of ObjectOutputStream which have 906 * overridden the <code>writeClassDescriptor</code> method). By default, 907 * this method reads class descriptors according to the format defined in 908 * the Object Serialization specification. 909 * 910 * @return the class descriptor read 911 * @throws IOException If an I/O error has occurred. 912 * @throws ClassNotFoundException If the Class of a serialized object used 913 * in the class descriptor representation cannot be found 914 * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass) 915 * @since 1.3 916 */ 917 protected ObjectStreamClass readClassDescriptor() 918 throws IOException, ClassNotFoundException 919 { 920 ObjectStreamClass desc = new ObjectStreamClass(); 921 desc.readNonProxy(this); 922 return desc; 923 } 924 925 /** 926 * Reads a byte of data. This method will block if no input is available. 927 * 928 * @return the byte read, or -1 if the end of the stream is reached. 929 * @throws IOException If an I/O error has occurred. 930 */ 931 public int read() throws IOException { 932 return bin.read(); 933 } 934 935 /** 936 * Reads into an array of bytes. This method will block until some input 937 * is available. Consider using java.io.DataInputStream.readFully to read 938 * exactly 'length' bytes. 939 * 940 * @param buf the buffer into which the data is read 941 * @param off the start offset in the destination array {@code buf} 942 * @param len the maximum number of bytes read 943 * @return the actual number of bytes read, -1 is returned when the end of 944 * the stream is reached. 945 * @throws NullPointerException if {@code buf} is {@code null}. 946 * @throws IndexOutOfBoundsException if {@code off} is negative, 947 * {@code len} is negative, or {@code len} is greater than 948 * {@code buf.length - off}. 949 * @throws IOException If an I/O error has occurred. 950 * @see java.io.DataInputStream#readFully(byte[],int,int) 951 */ 952 public int read(byte[] buf, int off, int len) throws IOException { 953 if (buf == null) { 954 throw new NullPointerException(); 955 } 956 int endoff = off + len; 957 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) { 958 throw new IndexOutOfBoundsException(); 959 } 960 return bin.read(buf, off, len, false); 961 } 962 963 /** 964 * Returns the number of bytes that can be read without blocking. 965 * 966 * @return the number of available bytes. 967 * @throws IOException if there are I/O errors while reading from the 968 * underlying <code>InputStream</code> 969 */ 970 public int available() throws IOException { 971 return bin.available(); 972 } 973 974 /** 975 * Closes the input stream. Must be called to release any resources 976 * associated with the stream. 977 * 978 * @throws IOException If an I/O error has occurred. 979 */ 980 public void close() throws IOException { 981 /* 982 * Even if stream already closed, propagate redundant close to 983 * underlying stream to stay consistent with previous implementations. 984 */ 985 closed = true; 986 if (depth == 0) { 987 clear(); 988 } 989 bin.close(); 990 } 991 992 /** 993 * Reads in a boolean. 994 * 995 * @return the boolean read. 996 * @throws EOFException If end of file is reached. 997 * @throws IOException If other I/O error has occurred. 998 */ 999 public boolean readBoolean() throws IOException { 1000 return bin.readBoolean(); 1001 } 1002 1003 /** 1004 * Reads an 8 bit byte. 1005 * 1006 * @return the 8 bit byte read. 1007 * @throws EOFException If end of file is reached. 1008 * @throws IOException If other I/O error has occurred. 1009 */ 1010 public byte readByte() throws IOException { 1011 return bin.readByte(); 1012 } 1013 1014 /** 1015 * Reads an unsigned 8 bit byte. 1016 * 1017 * @return the 8 bit byte read. 1018 * @throws EOFException If end of file is reached. 1019 * @throws IOException If other I/O error has occurred. 1020 */ 1021 public int readUnsignedByte() throws IOException { 1022 return bin.readUnsignedByte(); 1023 } 1024 1025 /** 1026 * Reads a 16 bit char. 1027 * 1028 * @return the 16 bit char read. 1029 * @throws EOFException If end of file is reached. 1030 * @throws IOException If other I/O error has occurred. 1031 */ 1032 public char readChar() throws IOException { 1033 return bin.readChar(); 1034 } 1035 1036 /** 1037 * Reads a 16 bit short. 1038 * 1039 * @return the 16 bit short read. 1040 * @throws EOFException If end of file is reached. 1041 * @throws IOException If other I/O error has occurred. 1042 */ 1043 public short readShort() throws IOException { 1044 return bin.readShort(); 1045 } 1046 1047 /** 1048 * Reads an unsigned 16 bit short. 1049 * 1050 * @return the 16 bit short read. 1051 * @throws EOFException If end of file is reached. 1052 * @throws IOException If other I/O error has occurred. 1053 */ 1054 public int readUnsignedShort() throws IOException { 1055 return bin.readUnsignedShort(); 1056 } 1057 1058 /** 1059 * Reads a 32 bit int. 1060 * 1061 * @return the 32 bit integer read. 1062 * @throws EOFException If end of file is reached. 1063 * @throws IOException If other I/O error has occurred. 1064 */ 1065 public int readInt() throws IOException { 1066 return bin.readInt(); 1067 } 1068 1069 /** 1070 * Reads a 64 bit long. 1071 * 1072 * @return the read 64 bit long. 1073 * @throws EOFException If end of file is reached. 1074 * @throws IOException If other I/O error has occurred. 1075 */ 1076 public long readLong() throws IOException { 1077 return bin.readLong(); 1078 } 1079 1080 /** 1081 * Reads a 32 bit float. 1082 * 1083 * @return the 32 bit float read. 1084 * @throws EOFException If end of file is reached. 1085 * @throws IOException If other I/O error has occurred. 1086 */ 1087 public float readFloat() throws IOException { 1088 return bin.readFloat(); 1089 } 1090 1091 /** 1092 * Reads a 64 bit double. 1093 * 1094 * @return the 64 bit double read. 1095 * @throws EOFException If end of file is reached. 1096 * @throws IOException If other I/O error has occurred. 1097 */ 1098 public double readDouble() throws IOException { 1099 return bin.readDouble(); 1100 } 1101 1102 /** 1103 * Reads bytes, blocking until all bytes are read. 1104 * 1105 * @param buf the buffer into which the data is read 1106 * @throws NullPointerException If {@code buf} is {@code null}. 1107 * @throws EOFException If end of file is reached. 1108 * @throws IOException If other I/O error has occurred. 1109 */ 1110 public void readFully(byte[] buf) throws IOException { 1111 bin.readFully(buf, 0, buf.length, false); 1112 } 1113 1114 /** 1115 * Reads bytes, blocking until all bytes are read. 1116 * 1117 * @param buf the buffer into which the data is read 1118 * @param off the start offset into the data array {@code buf} 1119 * @param len the maximum number of bytes to read 1120 * @throws NullPointerException If {@code buf} is {@code null}. 1121 * @throws IndexOutOfBoundsException If {@code off} is negative, 1122 * {@code len} is negative, or {@code len} is greater than 1123 * {@code buf.length - off}. 1124 * @throws EOFException If end of file is reached. 1125 * @throws IOException If other I/O error has occurred. 1126 */ 1127 public void readFully(byte[] buf, int off, int len) throws IOException { 1128 int endoff = off + len; 1129 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) { 1130 throw new IndexOutOfBoundsException(); 1131 } 1132 bin.readFully(buf, off, len, false); 1133 } 1134 1135 /** 1136 * Skips bytes. 1137 * 1138 * @param len the number of bytes to be skipped 1139 * @return the actual number of bytes skipped. 1140 * @throws IOException If an I/O error has occurred. 1141 */ 1142 public int skipBytes(int len) throws IOException { 1143 return bin.skipBytes(len); 1144 } 1145 1146 /** 1147 * Reads in a line that has been terminated by a \n, \r, \r\n or EOF. 1148 * 1149 * @return a String copy of the line. 1150 * @throws IOException if there are I/O errors while reading from the 1151 * underlying <code>InputStream</code> 1152 * @deprecated This method does not properly convert bytes to characters. 1153 * see DataInputStream for the details and alternatives. 1154 */ 1155 @Deprecated 1156 public String readLine() throws IOException { 1157 return bin.readLine(); 1158 } 1159 1160 /** 1161 * Reads a String in 1162 * <a href="DataInput.html#modified-utf-8">modified UTF-8</a> 1163 * format. 1164 * 1165 * @return the String. 1166 * @throws IOException if there are I/O errors while reading from the 1167 * underlying <code>InputStream</code> 1168 * @throws UTFDataFormatException if read bytes do not represent a valid 1169 * modified UTF-8 encoding of a string 1170 */ 1171 public String readUTF() throws IOException { 1172 return bin.readUTF(); 1173 } 1174 1175 /** 1176 * Returns the serialization filter for this stream. 1177 * The serialization filter is the most recent filter set in 1178 * {@link #setObjectInputFilter setObjectInputFilter} or 1179 * the initial process-wide filter from 1180 * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter}. 1181 * 1182 * @return the serialization filter for the stream; may be null 1183 * @since 9 1184 */ 1185 public final ObjectInputFilter getObjectInputFilter() { 1186 return serialFilter; 1187 } 1188 1189 /** 1190 * Set the serialization filter for the stream. 1191 * The filter's {@link ObjectInputFilter#checkInput checkInput} method is called 1192 * for each class and reference in the stream. 1193 * The filter can check any or all of the class, the array length, the number 1194 * of references, the depth of the graph, and the size of the input stream. 1195 * The depth is the number of nested {@linkplain #readObject readObject} 1196 * calls starting with the reading of the root of the graph being deserialized 1197 * and the current object being deserialized. 1198 * The number of references is the cumulative number of objects and references 1199 * to objects already read from the stream including the current object being read. 1200 * The filter is invoked only when reading objects from the stream and for 1201 * not primitives. 1202 * <p> 1203 * If the filter returns {@link ObjectInputFilter.Status#REJECTED Status.REJECTED}, 1204 * {@code null} or throws a {@link RuntimeException}, 1205 * the active {@code readObject} or {@code readUnshared} 1206 * throws {@link InvalidClassException}, otherwise deserialization 1207 * continues uninterrupted. 1208 * <p> 1209 * The serialization filter is initialized to the value of 1210 * {@link ObjectInputFilter.Config#getSerialFilter() ObjectInputFilter.Config.getSerialFilter} 1211 * when the {@code ObjectInputStream} is constructed and can be set 1212 * to a custom filter only once. 1213 * 1214 * @implSpec 1215 * The filter, when not {@code null}, is invoked during {@link #readObject readObject} 1216 * and {@link #readUnshared readUnshared} for each object (regular or class) in the stream. 1217 * Strings are treated as primitives and do not invoke the filter. 1218 * The filter is called for: 1219 * <ul> 1220 * <li>each object reference previously deserialized from the stream 1221 * (class is {@code null}, arrayLength is -1), 1222 * <li>each regular class (class is not {@code null}, arrayLength is -1), 1223 * <li>each interface of a dynamic proxy and the dynamic proxy class itself 1224 * (class is not {@code null}, arrayLength is -1), 1225 * <li>each array is filtered using the array type and length of the array 1226 * (class is the array type, arrayLength is the requested length), 1227 * <li>each object replaced by its class' {@code readResolve} method 1228 * is filtered using the replacement object's class, if not {@code null}, 1229 * and if it is an array, the arrayLength, otherwise -1, 1230 * <li>and each object replaced by {@link #resolveObject resolveObject} 1231 * is filtered using the replacement object's class, if not {@code null}, 1232 * and if it is an array, the arrayLength, otherwise -1. 1233 * </ul> 1234 * 1235 * When the {@link ObjectInputFilter#checkInput checkInput} method is invoked 1236 * it is given access to the current class, the array length, 1237 * the current number of references already read from the stream, 1238 * the depth of nested calls to {@link #readObject readObject} or 1239 * {@link #readUnshared readUnshared}, 1240 * and the implementation dependent number of bytes consumed from the input stream. 1241 * <p> 1242 * Each call to {@link #readObject readObject} or 1243 * {@link #readUnshared readUnshared} increases the depth by 1 1244 * before reading an object and decreases by 1 before returning 1245 * normally or exceptionally. 1246 * The depth starts at {@code 1} and increases for each nested object and 1247 * decrements when each nested call returns. 1248 * The count of references in the stream starts at {@code 1} and 1249 * is increased before reading an object. 1250 * 1251 * @param filter the filter, may be null 1252 * @throws SecurityException if there is security manager and the 1253 * {@code SerializablePermission("serialFilter")} is not granted 1254 * @throws IllegalStateException if the {@linkplain #getObjectInputFilter() current filter} 1255 * is not {@code null} and is not the process-wide filter 1256 * @since 9 1257 */ 1258 public final void setObjectInputFilter(ObjectInputFilter filter) { 1259 SecurityManager sm = System.getSecurityManager(); 1260 if (sm != null) { 1261 sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION); 1262 } 1263 // Allow replacement of the process-wide filter if not already set 1264 if (serialFilter != null && 1265 serialFilter != ObjectInputFilter.Config.getSerialFilter()) { 1266 throw new IllegalStateException("filter can not be set more than once"); 1267 } 1268 this.serialFilter = filter; 1269 } 1270 1271 /** 1272 * Invoke the serialization filter if non-null. 1273 * If the filter rejects or an exception is thrown, throws InvalidClassException. 1274 * 1275 * @param clazz the class; may be null 1276 * @param arrayLength the array length requested; use {@code -1} if not creating an array 1277 * @throws InvalidClassException if it rejected by the filter or 1278 * a {@link RuntimeException} is thrown 1279 */ 1280 private void filterCheck(Class<?> clazz, int arrayLength) 1281 throws InvalidClassException { 1282 if (serialFilter != null) { 1283 RuntimeException ex = null; 1284 ObjectInputFilter.Status status; 1285 try { 1286 status = serialFilter.checkInput(new FilterValues(clazz, arrayLength, 1287 totalObjectRefs, depth, bin.getBytesRead())); 1288 } catch (RuntimeException e) { 1289 // Preventive interception of an exception to log 1290 status = ObjectInputFilter.Status.REJECTED; 1291 ex = e; 1292 } 1293 if (Logging.filterLogger != null) { 1294 // Debug logging of filter checks that fail; Tracing for those that succeed 1295 Logging.filterLogger.log(status == null || status == ObjectInputFilter.Status.REJECTED 1296 ? Logger.Level.DEBUG 1297 : Logger.Level.TRACE, 1298 "ObjectInputFilter {0}: {1}, array length: {2}, nRefs: {3}, depth: {4}, bytes: {5}, ex: {6}", 1299 status, clazz, arrayLength, totalObjectRefs, depth, bin.getBytesRead(), 1300 Objects.toString(ex, "n/a")); 1301 } 1302 if (status == null || 1303 status == ObjectInputFilter.Status.REJECTED) { 1304 InvalidClassException ice = new InvalidClassException("filter status: " + status); 1305 ice.initCause(ex); 1306 throw ice; 1307 } 1308 } 1309 } 1310 1311 /** 1312 * Provide access to the persistent fields read from the input stream. 1313 */ 1314 public abstract static class GetField { 1315 1316 /** 1317 * Get the ObjectStreamClass that describes the fields in the stream. 1318 * 1319 * @return the descriptor class that describes the serializable fields 1320 */ 1321 public abstract ObjectStreamClass getObjectStreamClass(); 1322 1323 /** 1324 * Return true if the named field is defaulted and has no value in this 1325 * stream. 1326 * 1327 * @param name the name of the field 1328 * @return true, if and only if the named field is defaulted 1329 * @throws IOException if there are I/O errors while reading from 1330 * the underlying <code>InputStream</code> 1331 * @throws IllegalArgumentException if <code>name</code> does not 1332 * correspond to a serializable field 1333 */ 1334 public abstract boolean defaulted(String name) throws IOException; 1335 1336 /** 1337 * Get the value of the named boolean field from the persistent field. 1338 * 1339 * @param name the name of the field 1340 * @param val the default value to use if <code>name</code> does not 1341 * have a value 1342 * @return the value of the named <code>boolean</code> field 1343 * @throws IOException if there are I/O errors while reading from the 1344 * underlying <code>InputStream</code> 1345 * @throws IllegalArgumentException if type of <code>name</code> is 1346 * not serializable or if the field type is incorrect 1347 */ 1348 public abstract boolean get(String name, boolean val) 1349 throws IOException; 1350 1351 /** 1352 * Get the value of the named byte field from the persistent field. 1353 * 1354 * @param name the name of the field 1355 * @param val the default value to use if <code>name</code> does not 1356 * have a value 1357 * @return the value of the named <code>byte</code> field 1358 * @throws IOException if there are I/O errors while reading from the 1359 * underlying <code>InputStream</code> 1360 * @throws IllegalArgumentException if type of <code>name</code> is 1361 * not serializable or if the field type is incorrect 1362 */ 1363 public abstract byte get(String name, byte val) throws IOException; 1364 1365 /** 1366 * Get the value of the named char field from the persistent field. 1367 * 1368 * @param name the name of the field 1369 * @param val the default value to use if <code>name</code> does not 1370 * have a value 1371 * @return the value of the named <code>char</code> field 1372 * @throws IOException if there are I/O errors while reading from the 1373 * underlying <code>InputStream</code> 1374 * @throws IllegalArgumentException if type of <code>name</code> is 1375 * not serializable or if the field type is incorrect 1376 */ 1377 public abstract char get(String name, char val) throws IOException; 1378 1379 /** 1380 * Get the value of the named short field from the persistent field. 1381 * 1382 * @param name the name of the field 1383 * @param val the default value to use if <code>name</code> does not 1384 * have a value 1385 * @return the value of the named <code>short</code> field 1386 * @throws IOException if there are I/O errors while reading from the 1387 * underlying <code>InputStream</code> 1388 * @throws IllegalArgumentException if type of <code>name</code> is 1389 * not serializable or if the field type is incorrect 1390 */ 1391 public abstract short get(String name, short val) throws IOException; 1392 1393 /** 1394 * Get the value of the named int field from the persistent field. 1395 * 1396 * @param name the name of the field 1397 * @param val the default value to use if <code>name</code> does not 1398 * have a value 1399 * @return the value of the named <code>int</code> field 1400 * @throws IOException if there are I/O errors while reading from the 1401 * underlying <code>InputStream</code> 1402 * @throws IllegalArgumentException if type of <code>name</code> is 1403 * not serializable or if the field type is incorrect 1404 */ 1405 public abstract int get(String name, int val) throws IOException; 1406 1407 /** 1408 * Get the value of the named long field from the persistent field. 1409 * 1410 * @param name the name of the field 1411 * @param val the default value to use if <code>name</code> does not 1412 * have a value 1413 * @return the value of the named <code>long</code> field 1414 * @throws IOException if there are I/O errors while reading from the 1415 * underlying <code>InputStream</code> 1416 * @throws IllegalArgumentException if type of <code>name</code> is 1417 * not serializable or if the field type is incorrect 1418 */ 1419 public abstract long get(String name, long val) throws IOException; 1420 1421 /** 1422 * Get the value of the named float field from the persistent field. 1423 * 1424 * @param name the name of the field 1425 * @param val the default value to use if <code>name</code> does not 1426 * have a value 1427 * @return the value of the named <code>float</code> field 1428 * @throws IOException if there are I/O errors while reading from the 1429 * underlying <code>InputStream</code> 1430 * @throws IllegalArgumentException if type of <code>name</code> is 1431 * not serializable or if the field type is incorrect 1432 */ 1433 public abstract float get(String name, float val) throws IOException; 1434 1435 /** 1436 * Get the value of the named double field from the persistent field. 1437 * 1438 * @param name the name of the field 1439 * @param val the default value to use if <code>name</code> does not 1440 * have a value 1441 * @return the value of the named <code>double</code> field 1442 * @throws IOException if there are I/O errors while reading from the 1443 * underlying <code>InputStream</code> 1444 * @throws IllegalArgumentException if type of <code>name</code> is 1445 * not serializable or if the field type is incorrect 1446 */ 1447 public abstract double get(String name, double val) throws IOException; 1448 1449 /** 1450 * Get the value of the named Object field from the persistent field. 1451 * 1452 * @param name the name of the field 1453 * @param val the default value to use if <code>name</code> does not 1454 * have a value 1455 * @return the value of the named <code>Object</code> field 1456 * @throws IOException if there are I/O errors while reading from the 1457 * underlying <code>InputStream</code> 1458 * @throws IllegalArgumentException if type of <code>name</code> is 1459 * not serializable or if the field type is incorrect 1460 */ 1461 public abstract Object get(String name, Object val) throws IOException; 1462 } 1463 1464 /** 1465 * Verifies that this (possibly subclass) instance can be constructed 1466 * without violating security constraints: the subclass must not override 1467 * security-sensitive non-final methods, or else the 1468 * "enableSubclassImplementation" SerializablePermission is checked. 1469 */ 1470 private void verifySubclass() { 1471 Class<?> cl = getClass(); 1472 if (cl == ObjectInputStream.class) { 1473 return; 1474 } 1475 SecurityManager sm = System.getSecurityManager(); 1476 if (sm == null) { 1477 return; 1478 } 1479 processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits); 1480 WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue); 1481 Boolean result = Caches.subclassAudits.get(key); 1482 if (result == null) { 1483 result = auditSubclass(cl); 1484 Caches.subclassAudits.putIfAbsent(key, result); 1485 } 1486 if (!result) { 1487 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 1488 } 1489 } 1490 1491 /** 1492 * Performs reflective checks on given subclass to verify that it doesn't 1493 * override security-sensitive non-final methods. Returns TRUE if subclass 1494 * is "safe", FALSE otherwise. 1495 */ 1496 private static Boolean auditSubclass(Class<?> subcl) { 1497 return AccessController.doPrivileged( 1498 new PrivilegedAction<Boolean>() { 1499 public Boolean run() { 1500 for (Class<?> cl = subcl; 1501 cl != ObjectInputStream.class; 1502 cl = cl.getSuperclass()) 1503 { 1504 try { 1505 cl.getDeclaredMethod( 1506 "readUnshared", (Class[]) null); 1507 return Boolean.FALSE; 1508 } catch (NoSuchMethodException ex) { 1509 } 1510 try { 1511 cl.getDeclaredMethod("readFields", (Class[]) null); 1512 return Boolean.FALSE; 1513 } catch (NoSuchMethodException ex) { 1514 } 1515 } 1516 return Boolean.TRUE; 1517 } 1518 } 1519 ); 1520 } 1521 1522 /** 1523 * Clears internal data structures. 1524 */ 1525 private void clear() { 1526 handles.clear(); 1527 vlist.clear(); 1528 } 1529 1530 /** 1531 * Underlying readObject implementation. 1532 */ 1533 private Object readObject0(boolean unshared) throws IOException { 1534 boolean oldMode = bin.getBlockDataMode(); 1535 if (oldMode) { 1536 int remain = bin.currentBlockRemaining(); 1537 if (remain > 0) { 1538 throw new OptionalDataException(remain); 1539 } else if (defaultDataEnd) { 1540 /* 1541 * Fix for 4360508: stream is currently at the end of a field 1542 * value block written via default serialization; since there 1543 * is no terminating TC_ENDBLOCKDATA tag, simulate 1544 * end-of-custom-data behavior explicitly. 1545 */ 1546 throw new OptionalDataException(true); 1547 } 1548 bin.setBlockDataMode(false); 1549 } 1550 1551 byte tc; 1552 while ((tc = bin.peekByte()) == TC_RESET) { 1553 bin.readByte(); 1554 handleReset(); 1555 } 1556 1557 depth++; 1558 totalObjectRefs++; 1559 try { 1560 switch (tc) { 1561 case TC_NULL: 1562 return readNull(); 1563 1564 case TC_REFERENCE: 1565 return readHandle(unshared); 1566 1567 case TC_CLASS: 1568 return readClass(unshared); 1569 1570 case TC_CLASSDESC: 1571 case TC_PROXYCLASSDESC: 1572 return readClassDesc(unshared); 1573 1574 case TC_STRING: 1575 case TC_LONGSTRING: 1576 return checkResolve(readString(unshared)); 1577 1578 case TC_ARRAY: 1579 return checkResolve(readArray(unshared)); 1580 1581 case TC_ENUM: 1582 return checkResolve(readEnum(unshared)); 1583 1584 case TC_OBJECT: 1585 return checkResolve(readOrdinaryObject(unshared)); 1586 1587 case TC_EXCEPTION: 1588 IOException ex = readFatalException(); 1589 throw new WriteAbortedException("writing aborted", ex); 1590 1591 case TC_BLOCKDATA: 1592 case TC_BLOCKDATALONG: 1593 if (oldMode) { 1594 bin.setBlockDataMode(true); 1595 bin.peek(); // force header read 1596 throw new OptionalDataException( 1597 bin.currentBlockRemaining()); 1598 } else { 1599 throw new StreamCorruptedException( 1600 "unexpected block data"); 1601 } 1602 1603 case TC_ENDBLOCKDATA: 1604 if (oldMode) { 1605 throw new OptionalDataException(true); 1606 } else { 1607 throw new StreamCorruptedException( 1608 "unexpected end of block data"); 1609 } 1610 1611 default: 1612 throw new StreamCorruptedException( 1613 String.format("invalid type code: %02X", tc)); 1614 } 1615 } finally { 1616 depth--; 1617 bin.setBlockDataMode(oldMode); 1618 } 1619 } 1620 1621 /** 1622 * If resolveObject has been enabled and given object does not have an 1623 * exception associated with it, calls resolveObject to determine 1624 * replacement for object, and updates handle table accordingly. Returns 1625 * replacement object, or echoes provided object if no replacement 1626 * occurred. Expects that passHandle is set to given object's handle prior 1627 * to calling this method. 1628 */ 1629 private Object checkResolve(Object obj) throws IOException { 1630 if (!enableResolve || handles.lookupException(passHandle) != null) { 1631 return obj; 1632 } 1633 Object rep = resolveObject(obj); 1634 if (rep != obj) { 1635 // The type of the original object has been filtered but resolveObject 1636 // may have replaced it; filter the replacement's type 1637 if (rep != null) { 1638 if (rep.getClass().isArray()) { 1639 filterCheck(rep.getClass(), Array.getLength(rep)); 1640 } else { 1641 filterCheck(rep.getClass(), -1); 1642 } 1643 } 1644 handles.setObject(passHandle, rep); 1645 } 1646 return rep; 1647 } 1648 1649 /** 1650 * Reads string without allowing it to be replaced in stream. Called from 1651 * within ObjectStreamClass.read(). 1652 */ 1653 String readTypeString() throws IOException { 1654 int oldHandle = passHandle; 1655 try { 1656 byte tc = bin.peekByte(); 1657 switch (tc) { 1658 case TC_NULL: 1659 return (String) readNull(); 1660 1661 case TC_REFERENCE: 1662 return (String) readHandle(false); 1663 1664 case TC_STRING: 1665 case TC_LONGSTRING: 1666 return readString(false); 1667 1668 default: 1669 throw new StreamCorruptedException( 1670 String.format("invalid type code: %02X", tc)); 1671 } 1672 } finally { 1673 passHandle = oldHandle; 1674 } 1675 } 1676 1677 /** 1678 * Reads in null code, sets passHandle to NULL_HANDLE and returns null. 1679 */ 1680 private Object readNull() throws IOException { 1681 if (bin.readByte() != TC_NULL) { 1682 throw new InternalError(); 1683 } 1684 passHandle = NULL_HANDLE; 1685 return null; 1686 } 1687 1688 /** 1689 * Reads in object handle, sets passHandle to the read handle, and returns 1690 * object associated with the handle. 1691 */ 1692 private Object readHandle(boolean unshared) throws IOException { 1693 if (bin.readByte() != TC_REFERENCE) { 1694 throw new InternalError(); 1695 } 1696 passHandle = bin.readInt() - baseWireHandle; 1697 if (passHandle < 0 || passHandle >= handles.size()) { 1698 throw new StreamCorruptedException( 1699 String.format("invalid handle value: %08X", passHandle + 1700 baseWireHandle)); 1701 } 1702 if (unshared) { 1703 // REMIND: what type of exception to throw here? 1704 throw new InvalidObjectException( 1705 "cannot read back reference as unshared"); 1706 } 1707 1708 Object obj = handles.lookupObject(passHandle); 1709 if (obj == unsharedMarker) { 1710 // REMIND: what type of exception to throw here? 1711 throw new InvalidObjectException( 1712 "cannot read back reference to unshared object"); 1713 } 1714 filterCheck(null, -1); // just a check for number of references, depth, no class 1715 return obj; 1716 } 1717 1718 /** 1719 * Reads in and returns class object. Sets passHandle to class object's 1720 * assigned handle. Returns null if class is unresolvable (in which case a 1721 * ClassNotFoundException will be associated with the class' handle in the 1722 * handle table). 1723 */ 1724 private Class<?> readClass(boolean unshared) throws IOException { 1725 if (bin.readByte() != TC_CLASS) { 1726 throw new InternalError(); 1727 } 1728 ObjectStreamClass desc = readClassDesc(false); 1729 Class<?> cl = desc.forClass(); 1730 passHandle = handles.assign(unshared ? unsharedMarker : cl); 1731 1732 ClassNotFoundException resolveEx = desc.getResolveException(); 1733 if (resolveEx != null) { 1734 handles.markException(passHandle, resolveEx); 1735 } 1736 1737 handles.finish(passHandle); 1738 return cl; 1739 } 1740 1741 /** 1742 * Reads in and returns (possibly null) class descriptor. Sets passHandle 1743 * to class descriptor's assigned handle. If class descriptor cannot be 1744 * resolved to a class in the local VM, a ClassNotFoundException is 1745 * associated with the class descriptor's handle. 1746 */ 1747 private ObjectStreamClass readClassDesc(boolean unshared) 1748 throws IOException 1749 { 1750 byte tc = bin.peekByte(); 1751 ObjectStreamClass descriptor; 1752 switch (tc) { 1753 case TC_NULL: 1754 descriptor = (ObjectStreamClass) readNull(); 1755 break; 1756 case TC_REFERENCE: 1757 descriptor = (ObjectStreamClass) readHandle(unshared); 1758 break; 1759 case TC_PROXYCLASSDESC: 1760 descriptor = readProxyDesc(unshared); 1761 break; 1762 case TC_CLASSDESC: 1763 descriptor = readNonProxyDesc(unshared); 1764 break; 1765 default: 1766 throw new StreamCorruptedException( 1767 String.format("invalid type code: %02X", tc)); 1768 } 1769 if (descriptor != null) { 1770 validateDescriptor(descriptor); 1771 } 1772 return descriptor; 1773 } 1774 1775 private boolean isCustomSubclass() { 1776 // Return true if this class is a custom subclass of ObjectInputStream 1777 return getClass().getClassLoader() 1778 != ObjectInputStream.class.getClassLoader(); 1779 } 1780 1781 /** 1782 * Reads in and returns class descriptor for a dynamic proxy class. Sets 1783 * passHandle to proxy class descriptor's assigned handle. If proxy class 1784 * descriptor cannot be resolved to a class in the local VM, a 1785 * ClassNotFoundException is associated with the descriptor's handle. 1786 */ 1787 private ObjectStreamClass readProxyDesc(boolean unshared) 1788 throws IOException 1789 { 1790 if (bin.readByte() != TC_PROXYCLASSDESC) { 1791 throw new InternalError(); 1792 } 1793 1794 ObjectStreamClass desc = new ObjectStreamClass(); 1795 int descHandle = handles.assign(unshared ? unsharedMarker : desc); 1796 passHandle = NULL_HANDLE; 1797 1798 int numIfaces = bin.readInt(); 1799 String[] ifaces = new String[numIfaces]; 1800 for (int i = 0; i < numIfaces; i++) { 1801 ifaces[i] = bin.readUTF(); 1802 } 1803 1804 Class<?> cl = null; 1805 ClassNotFoundException resolveEx = null; 1806 bin.setBlockDataMode(true); 1807 try { 1808 if ((cl = resolveProxyClass(ifaces)) == null) { 1809 resolveEx = new ClassNotFoundException("null class"); 1810 } else if (!Proxy.isProxyClass(cl)) { 1811 throw new InvalidClassException("Not a proxy"); 1812 } else { 1813 // ReflectUtil.checkProxyPackageAccess makes a test 1814 // equivalent to isCustomSubclass so there's no need 1815 // to condition this call to isCustomSubclass == true here. 1816 ReflectUtil.checkProxyPackageAccess( 1817 getClass().getClassLoader(), 1818 cl.getInterfaces()); 1819 // Filter the interfaces 1820 for (Class<?> clazz : cl.getInterfaces()) { 1821 filterCheck(clazz, -1); 1822 } 1823 } 1824 } catch (ClassNotFoundException ex) { 1825 resolveEx = ex; 1826 } 1827 1828 // Call filterCheck on the class before reading anything else 1829 filterCheck(cl, -1); 1830 1831 skipCustomData(); 1832 1833 try { 1834 totalObjectRefs++; 1835 depth++; 1836 desc.initProxy(cl, resolveEx, readClassDesc(false)); 1837 } finally { 1838 depth--; 1839 } 1840 1841 handles.finish(descHandle); 1842 passHandle = descHandle; 1843 return desc; 1844 } 1845 1846 /** 1847 * Reads in and returns class descriptor for a class that is not a dynamic 1848 * proxy class. Sets passHandle to class descriptor's assigned handle. If 1849 * class descriptor cannot be resolved to a class in the local VM, a 1850 * ClassNotFoundException is associated with the descriptor's handle. 1851 */ 1852 private ObjectStreamClass readNonProxyDesc(boolean unshared) 1853 throws IOException 1854 { 1855 if (bin.readByte() != TC_CLASSDESC) { 1856 throw new InternalError(); 1857 } 1858 1859 ObjectStreamClass desc = new ObjectStreamClass(); 1860 int descHandle = handles.assign(unshared ? unsharedMarker : desc); 1861 passHandle = NULL_HANDLE; 1862 1863 ObjectStreamClass readDesc; 1864 try { 1865 readDesc = readClassDescriptor(); 1866 } catch (ClassNotFoundException ex) { 1867 throw (IOException) new InvalidClassException( 1868 "failed to read class descriptor").initCause(ex); 1869 } 1870 1871 Class<?> cl = null; 1872 ClassNotFoundException resolveEx = null; 1873 bin.setBlockDataMode(true); 1874 final boolean checksRequired = isCustomSubclass(); 1875 try { 1876 if ((cl = resolveClass(readDesc)) == null) { 1877 resolveEx = new ClassNotFoundException("null class"); 1878 } else if (checksRequired) { 1879 ReflectUtil.checkPackageAccess(cl); 1880 } 1881 } catch (ClassNotFoundException ex) { 1882 resolveEx = ex; 1883 } 1884 1885 // Call filterCheck on the class before reading anything else 1886 filterCheck(cl, -1); 1887 1888 skipCustomData(); 1889 1890 try { 1891 totalObjectRefs++; 1892 depth++; 1893 desc.initNonProxy(readDesc, cl, resolveEx, readClassDesc(false)); 1894 } finally { 1895 depth--; 1896 } 1897 1898 handles.finish(descHandle); 1899 passHandle = descHandle; 1900 1901 return desc; 1902 } 1903 1904 /** 1905 * Reads in and returns new string. Sets passHandle to new string's 1906 * assigned handle. 1907 */ 1908 private String readString(boolean unshared) throws IOException { 1909 String str; 1910 byte tc = bin.readByte(); 1911 switch (tc) { 1912 case TC_STRING: 1913 str = bin.readUTF(); 1914 break; 1915 1916 case TC_LONGSTRING: 1917 str = bin.readLongUTF(); 1918 break; 1919 1920 default: 1921 throw new StreamCorruptedException( 1922 String.format("invalid type code: %02X", tc)); 1923 } 1924 passHandle = handles.assign(unshared ? unsharedMarker : str); 1925 handles.finish(passHandle); 1926 return str; 1927 } 1928 1929 /** 1930 * Reads in and returns array object, or null if array class is 1931 * unresolvable. Sets passHandle to array's assigned handle. 1932 */ 1933 private Object readArray(boolean unshared) throws IOException { 1934 if (bin.readByte() != TC_ARRAY) { 1935 throw new InternalError(); 1936 } 1937 1938 ObjectStreamClass desc = readClassDesc(false); 1939 int len = bin.readInt(); 1940 1941 filterCheck(desc.forClass(), len); 1942 1943 Object array = null; 1944 Class<?> cl, ccl = null; 1945 if ((cl = desc.forClass()) != null) { 1946 ccl = cl.getComponentType(); 1947 array = Array.newInstance(ccl, len); 1948 } 1949 1950 int arrayHandle = handles.assign(unshared ? unsharedMarker : array); 1951 ClassNotFoundException resolveEx = desc.getResolveException(); 1952 if (resolveEx != null) { 1953 handles.markException(arrayHandle, resolveEx); 1954 } 1955 1956 if (ccl == null) { 1957 for (int i = 0; i < len; i++) { 1958 readObject0(false); 1959 } 1960 } else if (ccl.isPrimitive()) { 1961 if (ccl == Integer.TYPE) { 1962 bin.readInts((int[]) array, 0, len); 1963 } else if (ccl == Byte.TYPE) { 1964 bin.readFully((byte[]) array, 0, len, true); 1965 } else if (ccl == Long.TYPE) { 1966 bin.readLongs((long[]) array, 0, len); 1967 } else if (ccl == Float.TYPE) { 1968 bin.readFloats((float[]) array, 0, len); 1969 } else if (ccl == Double.TYPE) { 1970 bin.readDoubles((double[]) array, 0, len); 1971 } else if (ccl == Short.TYPE) { 1972 bin.readShorts((short[]) array, 0, len); 1973 } else if (ccl == Character.TYPE) { 1974 bin.readChars((char[]) array, 0, len); 1975 } else if (ccl == Boolean.TYPE) { 1976 bin.readBooleans((boolean[]) array, 0, len); 1977 } else { 1978 throw new InternalError(); 1979 } 1980 } else { 1981 Object[] oa = (Object[]) array; 1982 for (int i = 0; i < len; i++) { 1983 oa[i] = readObject0(false); 1984 handles.markDependency(arrayHandle, passHandle); 1985 } 1986 } 1987 1988 handles.finish(arrayHandle); 1989 passHandle = arrayHandle; 1990 return array; 1991 } 1992 1993 /** 1994 * Reads in and returns enum constant, or null if enum type is 1995 * unresolvable. Sets passHandle to enum constant's assigned handle. 1996 */ 1997 private Enum<?> readEnum(boolean unshared) throws IOException { 1998 if (bin.readByte() != TC_ENUM) { 1999 throw new InternalError(); 2000 } 2001 2002 ObjectStreamClass desc = readClassDesc(false); 2003 if (!desc.isEnum()) { 2004 throw new InvalidClassException("non-enum class: " + desc); 2005 } 2006 2007 int enumHandle = handles.assign(unshared ? unsharedMarker : null); 2008 ClassNotFoundException resolveEx = desc.getResolveException(); 2009 if (resolveEx != null) { 2010 handles.markException(enumHandle, resolveEx); 2011 } 2012 2013 String name = readString(false); 2014 Enum<?> result = null; 2015 Class<?> cl = desc.forClass(); 2016 if (cl != null) { 2017 try { 2018 @SuppressWarnings("unchecked") 2019 Enum<?> en = Enum.valueOf((Class)cl, name); 2020 result = en; 2021 } catch (IllegalArgumentException ex) { 2022 throw (IOException) new InvalidObjectException( 2023 "enum constant " + name + " does not exist in " + 2024 cl).initCause(ex); 2025 } 2026 if (!unshared) { 2027 handles.setObject(enumHandle, result); 2028 } 2029 } 2030 2031 handles.finish(enumHandle); 2032 passHandle = enumHandle; 2033 return result; 2034 } 2035 2036 /** 2037 * Reads and returns "ordinary" (i.e., not a String, Class, 2038 * ObjectStreamClass, array, or enum constant) object, or null if object's 2039 * class is unresolvable (in which case a ClassNotFoundException will be 2040 * associated with object's handle). Sets passHandle to object's assigned 2041 * handle. 2042 */ 2043 private Object readOrdinaryObject(boolean unshared) 2044 throws IOException 2045 { 2046 if (bin.readByte() != TC_OBJECT) { 2047 throw new InternalError(); 2048 } 2049 2050 ObjectStreamClass desc = readClassDesc(false); 2051 desc.checkDeserialize(); 2052 2053 Class<?> cl = desc.forClass(); 2054 if (cl == String.class || cl == Class.class 2055 || cl == ObjectStreamClass.class) { 2056 throw new InvalidClassException("invalid class descriptor"); 2057 } 2058 2059 Object obj; 2060 try { 2061 obj = desc.isInstantiable() ? desc.newInstance() : null; 2062 } catch (Exception ex) { 2063 throw (IOException) new InvalidClassException( 2064 desc.forClass().getName(), 2065 "unable to create instance").initCause(ex); 2066 } 2067 2068 passHandle = handles.assign(unshared ? unsharedMarker : obj); 2069 ClassNotFoundException resolveEx = desc.getResolveException(); 2070 if (resolveEx != null) { 2071 handles.markException(passHandle, resolveEx); 2072 } 2073 2074 if (desc.isExternalizable()) { 2075 readExternalData((Externalizable) obj, desc); 2076 } else { 2077 readSerialData(obj, desc); 2078 } 2079 2080 handles.finish(passHandle); 2081 2082 if (obj != null && 2083 handles.lookupException(passHandle) == null && 2084 desc.hasReadResolveMethod()) 2085 { 2086 Object rep = desc.invokeReadResolve(obj); 2087 if (unshared && rep.getClass().isArray()) { 2088 rep = cloneArray(rep); 2089 } 2090 if (rep != obj) { 2091 // Filter the replacement object 2092 if (rep != null) { 2093 if (rep.getClass().isArray()) { 2094 filterCheck(rep.getClass(), Array.getLength(rep)); 2095 } else { 2096 filterCheck(rep.getClass(), -1); 2097 } 2098 } 2099 handles.setObject(passHandle, obj = rep); 2100 } 2101 } 2102 2103 return obj; 2104 } 2105 2106 /** 2107 * If obj is non-null, reads externalizable data by invoking readExternal() 2108 * method of obj; otherwise, attempts to skip over externalizable data. 2109 * Expects that passHandle is set to obj's handle before this method is 2110 * called. 2111 */ 2112 private void readExternalData(Externalizable obj, ObjectStreamClass desc) 2113 throws IOException 2114 { 2115 SerialCallbackContext oldContext = curContext; 2116 if (oldContext != null) 2117 oldContext.check(); 2118 curContext = null; 2119 try { 2120 boolean blocked = desc.hasBlockExternalData(); 2121 if (blocked) { 2122 bin.setBlockDataMode(true); 2123 } 2124 if (obj != null) { 2125 try { 2126 obj.readExternal(this); 2127 } catch (ClassNotFoundException ex) { 2128 /* 2129 * In most cases, the handle table has already propagated 2130 * a CNFException to passHandle at this point; this mark 2131 * call is included to address cases where the readExternal 2132 * method has cons'ed and thrown a new CNFException of its 2133 * own. 2134 */ 2135 handles.markException(passHandle, ex); 2136 } 2137 } 2138 if (blocked) { 2139 skipCustomData(); 2140 } 2141 } finally { 2142 if (oldContext != null) 2143 oldContext.check(); 2144 curContext = oldContext; 2145 } 2146 /* 2147 * At this point, if the externalizable data was not written in 2148 * block-data form and either the externalizable class doesn't exist 2149 * locally (i.e., obj == null) or readExternal() just threw a 2150 * CNFException, then the stream is probably in an inconsistent state, 2151 * since some (or all) of the externalizable data may not have been 2152 * consumed. Since there's no "correct" action to take in this case, 2153 * we mimic the behavior of past serialization implementations and 2154 * blindly hope that the stream is in sync; if it isn't and additional 2155 * externalizable data remains in the stream, a subsequent read will 2156 * most likely throw a StreamCorruptedException. 2157 */ 2158 } 2159 2160 /** 2161 * Reads (or attempts to skip, if obj is null or is tagged with a 2162 * ClassNotFoundException) instance data for each serializable class of 2163 * object in stream, from superclass to subclass. Expects that passHandle 2164 * is set to obj's handle before this method is called. 2165 */ 2166 private void readSerialData(Object obj, ObjectStreamClass desc) 2167 throws IOException 2168 { 2169 ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout(); 2170 // Best effort Failure Atomicity; slotValues will be non-null if field 2171 // values can be set after reading all field data in the hierarchy. 2172 // Field values can only be set after reading all data if there are no 2173 // user observable methods in the hierarchy, readObject(NoData). The 2174 // top most Serializable class in the hierarchy can be skipped. 2175 FieldValues[] slotValues = null; 2176 2177 boolean hasSpecialReadMethod = false; 2178 for (int i = 1; i < slots.length; i++) { 2179 ObjectStreamClass slotDesc = slots[i].desc; 2180 if (slotDesc.hasReadObjectMethod() 2181 || slotDesc.hasReadObjectNoDataMethod()) { 2182 hasSpecialReadMethod = true; 2183 break; 2184 } 2185 } 2186 // No special read methods, can store values and defer setting. 2187 if (!hasSpecialReadMethod) 2188 slotValues = new FieldValues[slots.length]; 2189 2190 for (int i = 0; i < slots.length; i++) { 2191 ObjectStreamClass slotDesc = slots[i].desc; 2192 2193 if (slots[i].hasData) { 2194 if (obj == null || handles.lookupException(passHandle) != null) { 2195 defaultReadFields(null, slotDesc); // skip field values 2196 } else if (slotDesc.hasReadObjectMethod()) { 2197 ThreadDeath t = null; 2198 boolean reset = false; 2199 SerialCallbackContext oldContext = curContext; 2200 if (oldContext != null) 2201 oldContext.check(); 2202 try { 2203 curContext = new SerialCallbackContext(obj, slotDesc); 2204 2205 bin.setBlockDataMode(true); 2206 slotDesc.invokeReadObject(obj, this); 2207 } catch (ClassNotFoundException ex) { 2208 /* 2209 * In most cases, the handle table has already 2210 * propagated a CNFException to passHandle at this 2211 * point; this mark call is included to address cases 2212 * where the custom readObject method has cons'ed and 2213 * thrown a new CNFException of its own. 2214 */ 2215 handles.markException(passHandle, ex); 2216 } finally { 2217 do { 2218 try { 2219 curContext.setUsed(); 2220 if (oldContext!= null) 2221 oldContext.check(); 2222 curContext = oldContext; 2223 reset = true; 2224 } catch (ThreadDeath x) { 2225 t = x; // defer until reset is true 2226 } 2227 } while (!reset); 2228 if (t != null) 2229 throw t; 2230 } 2231 2232 /* 2233 * defaultDataEnd may have been set indirectly by custom 2234 * readObject() method when calling defaultReadObject() or 2235 * readFields(); clear it to restore normal read behavior. 2236 */ 2237 defaultDataEnd = false; 2238 } else { 2239 FieldValues vals = defaultReadFields(obj, slotDesc); 2240 if (slotValues != null) { 2241 slotValues[i] = vals; 2242 } else if (obj != null) { 2243 defaultCheckFieldValues(obj, slotDesc, vals); 2244 defaultSetFieldValues(obj, slotDesc, vals); 2245 } 2246 } 2247 2248 if (slotDesc.hasWriteObjectData()) { 2249 skipCustomData(); 2250 } else { 2251 bin.setBlockDataMode(false); 2252 } 2253 } else { 2254 if (obj != null && 2255 slotDesc.hasReadObjectNoDataMethod() && 2256 handles.lookupException(passHandle) == null) 2257 { 2258 slotDesc.invokeReadObjectNoData(obj); 2259 } 2260 } 2261 } 2262 2263 if (obj != null && slotValues != null) { 2264 // Check that the non-primitive types are assignable for all slots 2265 // before assigning. 2266 for (int i = 0; i < slots.length; i++) { 2267 if (slotValues[i] != null) 2268 defaultCheckFieldValues(obj, slots[i].desc, slotValues[i]); 2269 } 2270 for (int i = 0; i < slots.length; i++) { 2271 if (slotValues[i] != null) 2272 defaultSetFieldValues(obj, slots[i].desc, slotValues[i]); 2273 } 2274 } 2275 } 2276 2277 /** 2278 * Skips over all block data and objects until TC_ENDBLOCKDATA is 2279 * encountered. 2280 */ 2281 private void skipCustomData() throws IOException { 2282 int oldHandle = passHandle; 2283 for (;;) { 2284 if (bin.getBlockDataMode()) { 2285 bin.skipBlockData(); 2286 bin.setBlockDataMode(false); 2287 } 2288 switch (bin.peekByte()) { 2289 case TC_BLOCKDATA: 2290 case TC_BLOCKDATALONG: 2291 bin.setBlockDataMode(true); 2292 break; 2293 2294 case TC_ENDBLOCKDATA: 2295 bin.readByte(); 2296 passHandle = oldHandle; 2297 return; 2298 2299 default: 2300 readObject0(false); 2301 break; 2302 } 2303 } 2304 } 2305 2306 private class FieldValues { 2307 final byte[] primValues; 2308 final Object[] objValues; 2309 2310 FieldValues(byte[] primValues, Object[] objValues) { 2311 this.primValues = primValues; 2312 this.objValues = objValues; 2313 } 2314 } 2315 2316 /** 2317 * Reads in values of serializable fields declared by given class 2318 * descriptor. Expects that passHandle is set to obj's handle before this 2319 * method is called. 2320 */ 2321 private FieldValues defaultReadFields(Object obj, ObjectStreamClass desc) 2322 throws IOException 2323 { 2324 Class<?> cl = desc.forClass(); 2325 if (cl != null && obj != null && !cl.isInstance(obj)) { 2326 throw new ClassCastException(); 2327 } 2328 2329 byte[] primVals = null; 2330 int primDataSize = desc.getPrimDataSize(); 2331 if (primDataSize > 0) { 2332 primVals = new byte[primDataSize]; 2333 bin.readFully(primVals, 0, primDataSize, false); 2334 } 2335 2336 Object[] objVals = null; 2337 int numObjFields = desc.getNumObjFields(); 2338 if (numObjFields > 0) { 2339 int objHandle = passHandle; 2340 ObjectStreamField[] fields = desc.getFields(false); 2341 objVals = new Object[numObjFields]; 2342 int numPrimFields = fields.length - objVals.length; 2343 for (int i = 0; i < objVals.length; i++) { 2344 ObjectStreamField f = fields[numPrimFields + i]; 2345 objVals[i] = readObject0(f.isUnshared()); 2346 if (f.getField() != null) { 2347 handles.markDependency(objHandle, passHandle); 2348 } 2349 } 2350 passHandle = objHandle; 2351 } 2352 2353 return new FieldValues(primVals, objVals); 2354 } 2355 2356 /** Throws ClassCastException if any value is not assignable. */ 2357 private void defaultCheckFieldValues(Object obj, ObjectStreamClass desc, 2358 FieldValues values) { 2359 Object[] objectValues = values.objValues; 2360 if (objectValues != null) 2361 desc.checkObjFieldValueTypes(obj, objectValues); 2362 } 2363 2364 /** Sets field values in obj. */ 2365 private void defaultSetFieldValues(Object obj, ObjectStreamClass desc, 2366 FieldValues values) { 2367 byte[] primValues = values.primValues; 2368 Object[] objectValues = values.objValues; 2369 2370 if (primValues != null) 2371 desc.setPrimFieldValues(obj, primValues); 2372 if (objectValues != null) 2373 desc.setObjFieldValues(obj, objectValues); 2374 } 2375 2376 /** 2377 * Reads in and returns IOException that caused serialization to abort. 2378 * All stream state is discarded prior to reading in fatal exception. Sets 2379 * passHandle to fatal exception's handle. 2380 */ 2381 private IOException readFatalException() throws IOException { 2382 if (bin.readByte() != TC_EXCEPTION) { 2383 throw new InternalError(); 2384 } 2385 clear(); 2386 return (IOException) readObject0(false); 2387 } 2388 2389 /** 2390 * If recursion depth is 0, clears internal data structures; otherwise, 2391 * throws a StreamCorruptedException. This method is called when a 2392 * TC_RESET typecode is encountered. 2393 */ 2394 private void handleReset() throws StreamCorruptedException { 2395 if (depth > 0) { 2396 throw new StreamCorruptedException( 2397 "unexpected reset; recursion depth: " + depth); 2398 } 2399 clear(); 2400 } 2401 2402 /** 2403 * Converts specified span of bytes into float values. 2404 */ 2405 // REMIND: remove once hotspot inlines Float.intBitsToFloat 2406 private static native void bytesToFloats(byte[] src, int srcpos, 2407 float[] dst, int dstpos, 2408 int nfloats); 2409 2410 /** 2411 * Converts specified span of bytes into double values. 2412 */ 2413 // REMIND: remove once hotspot inlines Double.longBitsToDouble 2414 private static native void bytesToDoubles(byte[] src, int srcpos, 2415 double[] dst, int dstpos, 2416 int ndoubles); 2417 2418 /** 2419 * Returns the first non-null and non-platform class loader (not counting 2420 * class loaders of generated reflection implementation classes) up the 2421 * execution stack, or the platform class loader if only code from the 2422 * bootstrap and platform class loader is on the stack. 2423 */ 2424 private static ClassLoader latestUserDefinedLoader() { 2425 return jdk.internal.misc.VM.latestUserDefinedLoader(); 2426 } 2427 2428 /** 2429 * Default GetField implementation. 2430 */ 2431 private class GetFieldImpl extends GetField { 2432 2433 /** class descriptor describing serializable fields */ 2434 private final ObjectStreamClass desc; 2435 /** primitive field values */ 2436 private final byte[] primVals; 2437 /** object field values */ 2438 private final Object[] objVals; 2439 /** object field value handles */ 2440 private final int[] objHandles; 2441 2442 /** 2443 * Creates GetFieldImpl object for reading fields defined in given 2444 * class descriptor. 2445 */ 2446 GetFieldImpl(ObjectStreamClass desc) { 2447 this.desc = desc; 2448 primVals = new byte[desc.getPrimDataSize()]; 2449 objVals = new Object[desc.getNumObjFields()]; 2450 objHandles = new int[objVals.length]; 2451 } 2452 2453 public ObjectStreamClass getObjectStreamClass() { 2454 return desc; 2455 } 2456 2457 public boolean defaulted(String name) throws IOException { 2458 return (getFieldOffset(name, null) < 0); 2459 } 2460 2461 public boolean get(String name, boolean val) throws IOException { 2462 int off = getFieldOffset(name, Boolean.TYPE); 2463 return (off >= 0) ? Bits.getBoolean(primVals, off) : val; 2464 } 2465 2466 public byte get(String name, byte val) throws IOException { 2467 int off = getFieldOffset(name, Byte.TYPE); 2468 return (off >= 0) ? primVals[off] : val; 2469 } 2470 2471 public char get(String name, char val) throws IOException { 2472 int off = getFieldOffset(name, Character.TYPE); 2473 return (off >= 0) ? Bits.getChar(primVals, off) : val; 2474 } 2475 2476 public short get(String name, short val) throws IOException { 2477 int off = getFieldOffset(name, Short.TYPE); 2478 return (off >= 0) ? Bits.getShort(primVals, off) : val; 2479 } 2480 2481 public int get(String name, int val) throws IOException { 2482 int off = getFieldOffset(name, Integer.TYPE); 2483 return (off >= 0) ? Bits.getInt(primVals, off) : val; 2484 } 2485 2486 public float get(String name, float val) throws IOException { 2487 int off = getFieldOffset(name, Float.TYPE); 2488 return (off >= 0) ? Bits.getFloat(primVals, off) : val; 2489 } 2490 2491 public long get(String name, long val) throws IOException { 2492 int off = getFieldOffset(name, Long.TYPE); 2493 return (off >= 0) ? Bits.getLong(primVals, off) : val; 2494 } 2495 2496 public double get(String name, double val) throws IOException { 2497 int off = getFieldOffset(name, Double.TYPE); 2498 return (off >= 0) ? Bits.getDouble(primVals, off) : val; 2499 } 2500 2501 public Object get(String name, Object val) throws IOException { 2502 int off = getFieldOffset(name, Object.class); 2503 if (off >= 0) { 2504 int objHandle = objHandles[off]; 2505 handles.markDependency(passHandle, objHandle); 2506 return (handles.lookupException(objHandle) == null) ? 2507 objVals[off] : null; 2508 } else { 2509 return val; 2510 } 2511 } 2512 2513 /** 2514 * Reads primitive and object field values from stream. 2515 */ 2516 void readFields() throws IOException { 2517 bin.readFully(primVals, 0, primVals.length, false); 2518 2519 int oldHandle = passHandle; 2520 ObjectStreamField[] fields = desc.getFields(false); 2521 int numPrimFields = fields.length - objVals.length; 2522 for (int i = 0; i < objVals.length; i++) { 2523 objVals[i] = 2524 readObject0(fields[numPrimFields + i].isUnshared()); 2525 objHandles[i] = passHandle; 2526 } 2527 passHandle = oldHandle; 2528 } 2529 2530 /** 2531 * Returns offset of field with given name and type. A specified type 2532 * of null matches all types, Object.class matches all non-primitive 2533 * types, and any other non-null type matches assignable types only. 2534 * If no matching field is found in the (incoming) class 2535 * descriptor but a matching field is present in the associated local 2536 * class descriptor, returns -1. Throws IllegalArgumentException if 2537 * neither incoming nor local class descriptor contains a match. 2538 */ 2539 private int getFieldOffset(String name, Class<?> type) { 2540 ObjectStreamField field = desc.getField(name, type); 2541 if (field != null) { 2542 return field.getOffset(); 2543 } else if (desc.getLocalDesc().getField(name, type) != null) { 2544 return -1; 2545 } else { 2546 throw new IllegalArgumentException("no such field " + name + 2547 " with type " + type); 2548 } 2549 } 2550 } 2551 2552 /** 2553 * Prioritized list of callbacks to be performed once object graph has been 2554 * completely deserialized. 2555 */ 2556 private static class ValidationList { 2557 2558 private static class Callback { 2559 final ObjectInputValidation obj; 2560 final int priority; 2561 Callback next; 2562 final AccessControlContext acc; 2563 2564 Callback(ObjectInputValidation obj, int priority, Callback next, 2565 AccessControlContext acc) 2566 { 2567 this.obj = obj; 2568 this.priority = priority; 2569 this.next = next; 2570 this.acc = acc; 2571 } 2572 } 2573 2574 /** linked list of callbacks */ 2575 private Callback list; 2576 2577 /** 2578 * Creates new (empty) ValidationList. 2579 */ 2580 ValidationList() { 2581 } 2582 2583 /** 2584 * Registers callback. Throws InvalidObjectException if callback 2585 * object is null. 2586 */ 2587 void register(ObjectInputValidation obj, int priority) 2588 throws InvalidObjectException 2589 { 2590 if (obj == null) { 2591 throw new InvalidObjectException("null callback"); 2592 } 2593 2594 Callback prev = null, cur = list; 2595 while (cur != null && priority < cur.priority) { 2596 prev = cur; 2597 cur = cur.next; 2598 } 2599 AccessControlContext acc = AccessController.getContext(); 2600 if (prev != null) { 2601 prev.next = new Callback(obj, priority, cur, acc); 2602 } else { 2603 list = new Callback(obj, priority, list, acc); 2604 } 2605 } 2606 2607 /** 2608 * Invokes all registered callbacks and clears the callback list. 2609 * Callbacks with higher priorities are called first; those with equal 2610 * priorities may be called in any order. If any of the callbacks 2611 * throws an InvalidObjectException, the callback process is terminated 2612 * and the exception propagated upwards. 2613 */ 2614 void doCallbacks() throws InvalidObjectException { 2615 try { 2616 while (list != null) { 2617 AccessController.doPrivileged( 2618 new PrivilegedExceptionAction<Void>() 2619 { 2620 public Void run() throws InvalidObjectException { 2621 list.obj.validateObject(); 2622 return null; 2623 } 2624 }, list.acc); 2625 list = list.next; 2626 } 2627 } catch (PrivilegedActionException ex) { 2628 list = null; 2629 throw (InvalidObjectException) ex.getException(); 2630 } 2631 } 2632 2633 /** 2634 * Resets the callback list to its initial (empty) state. 2635 */ 2636 public void clear() { 2637 list = null; 2638 } 2639 } 2640 2641 /** 2642 * Hold a snapshot of values to be passed to an ObjectInputFilter. 2643 */ 2644 static class FilterValues implements ObjectInputFilter.FilterInfo { 2645 final Class<?> clazz; 2646 final long arrayLength; 2647 final long totalObjectRefs; 2648 final long depth; 2649 final long streamBytes; 2650 2651 public FilterValues(Class<?> clazz, long arrayLength, long totalObjectRefs, 2652 long depth, long streamBytes) { 2653 this.clazz = clazz; 2654 this.arrayLength = arrayLength; 2655 this.totalObjectRefs = totalObjectRefs; 2656 this.depth = depth; 2657 this.streamBytes = streamBytes; 2658 } 2659 2660 @Override 2661 public Class<?> serialClass() { 2662 return clazz; 2663 } 2664 2665 @Override 2666 public long arrayLength() { 2667 return arrayLength; 2668 } 2669 2670 @Override 2671 public long references() { 2672 return totalObjectRefs; 2673 } 2674 2675 @Override 2676 public long depth() { 2677 return depth; 2678 } 2679 2680 @Override 2681 public long streamBytes() { 2682 return streamBytes; 2683 } 2684 } 2685 2686 /** 2687 * Input stream supporting single-byte peek operations. 2688 */ 2689 private static class PeekInputStream extends InputStream { 2690 2691 /** underlying stream */ 2692 private final InputStream in; 2693 /** peeked byte */ 2694 private int peekb = -1; 2695 /** total bytes read from the stream */ 2696 private long totalBytesRead = 0; 2697 2698 /** 2699 * Creates new PeekInputStream on top of given underlying stream. 2700 */ 2701 PeekInputStream(InputStream in) { 2702 this.in = in; 2703 } 2704 2705 /** 2706 * Peeks at next byte value in stream. Similar to read(), except 2707 * that it does not consume the read value. 2708 */ 2709 int peek() throws IOException { 2710 if (peekb >= 0) { 2711 return peekb; 2712 } 2713 peekb = in.read(); 2714 totalBytesRead += peekb >= 0 ? 1 : 0; 2715 return peekb; 2716 } 2717 2718 public int read() throws IOException { 2719 if (peekb >= 0) { 2720 int v = peekb; 2721 peekb = -1; 2722 return v; 2723 } else { 2724 int nbytes = in.read(); 2725 totalBytesRead += nbytes >= 0 ? 1 : 0; 2726 return nbytes; 2727 } 2728 } 2729 2730 public int read(byte[] b, int off, int len) throws IOException { 2731 int nbytes; 2732 if (len == 0) { 2733 return 0; 2734 } else if (peekb < 0) { 2735 nbytes = in.read(b, off, len); 2736 totalBytesRead += nbytes >= 0 ? nbytes : 0; 2737 return nbytes; 2738 } else { 2739 b[off++] = (byte) peekb; 2740 len--; 2741 peekb = -1; 2742 nbytes = in.read(b, off, len); 2743 totalBytesRead += nbytes >= 0 ? nbytes : 0; 2744 return (nbytes >= 0) ? (nbytes + 1) : 1; 2745 } 2746 } 2747 2748 void readFully(byte[] b, int off, int len) throws IOException { 2749 int n = 0; 2750 while (n < len) { 2751 int count = read(b, off + n, len - n); 2752 if (count < 0) { 2753 throw new EOFException(); 2754 } 2755 n += count; 2756 } 2757 } 2758 2759 public long skip(long n) throws IOException { 2760 if (n <= 0) { 2761 return 0; 2762 } 2763 int skipped = 0; 2764 if (peekb >= 0) { 2765 peekb = -1; 2766 skipped++; 2767 n--; 2768 } 2769 n = skipped + in.skip(n); 2770 totalBytesRead += n; 2771 return n; 2772 } 2773 2774 public int available() throws IOException { 2775 return in.available() + ((peekb >= 0) ? 1 : 0); 2776 } 2777 2778 public void close() throws IOException { 2779 in.close(); 2780 } 2781 2782 public long getBytesRead() { 2783 return totalBytesRead; 2784 } 2785 } 2786 2787 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); 2788 2789 /** 2790 * Performs a "freeze" action, required to adhere to final field semantics. 2791 * 2792 * <p> This method can be called unconditionally before returning the graph, 2793 * from the topmost readObject call, since it is expected that the 2794 * additional cost of the freeze action is negligible compared to 2795 * reconstituting even the most simple graph. 2796 * 2797 * <p> Nested calls to readObject do not issue freeze actions because the 2798 * sub-graph returned from a nested call is not guaranteed to be fully 2799 * initialized yet (possible cycles). 2800 */ 2801 private void freeze() { 2802 // Issue a StoreStore|StoreLoad fence, which is at least sufficient 2803 // to provide final-freeze semantics. 2804 UNSAFE.storeFence(); 2805 } 2806 2807 /** 2808 * Input stream with two modes: in default mode, inputs data written in the 2809 * same format as DataOutputStream; in "block data" mode, inputs data 2810 * bracketed by block data markers (see object serialization specification 2811 * for details). Buffering depends on block data mode: when in default 2812 * mode, no data is buffered in advance; when in block data mode, all data 2813 * for the current data block is read in at once (and buffered). 2814 */ 2815 private class BlockDataInputStream 2816 extends InputStream implements DataInput 2817 { 2818 /** maximum data block length */ 2819 private static final int MAX_BLOCK_SIZE = 1024; 2820 /** maximum data block header length */ 2821 private static final int MAX_HEADER_SIZE = 5; 2822 /** (tunable) length of char buffer (for reading strings) */ 2823 private static final int CHAR_BUF_SIZE = 256; 2824 /** readBlockHeader() return value indicating header read may block */ 2825 private static final int HEADER_BLOCKED = -2; 2826 2827 /** buffer for reading general/block data */ 2828 private final byte[] buf = new byte[MAX_BLOCK_SIZE]; 2829 /** buffer for reading block data headers */ 2830 private final byte[] hbuf = new byte[MAX_HEADER_SIZE]; 2831 /** char buffer for fast string reads */ 2832 private final char[] cbuf = new char[CHAR_BUF_SIZE]; 2833 2834 /** block data mode */ 2835 private boolean blkmode = false; 2836 2837 // block data state fields; values meaningful only when blkmode true 2838 /** current offset into buf */ 2839 private int pos = 0; 2840 /** end offset of valid data in buf, or -1 if no more block data */ 2841 private int end = -1; 2842 /** number of bytes in current block yet to be read from stream */ 2843 private int unread = 0; 2844 2845 /** underlying stream (wrapped in peekable filter stream) */ 2846 private final PeekInputStream in; 2847 /** loopback stream (for data reads that span data blocks) */ 2848 private final DataInputStream din; 2849 2850 /** 2851 * Creates new BlockDataInputStream on top of given underlying stream. 2852 * Block data mode is turned off by default. 2853 */ 2854 BlockDataInputStream(InputStream in) { 2855 this.in = new PeekInputStream(in); 2856 din = new DataInputStream(this); 2857 } 2858 2859 /** 2860 * Sets block data mode to the given mode (true == on, false == off) 2861 * and returns the previous mode value. If the new mode is the same as 2862 * the old mode, no action is taken. Throws IllegalStateException if 2863 * block data mode is being switched from on to off while unconsumed 2864 * block data is still present in the stream. 2865 */ 2866 boolean setBlockDataMode(boolean newmode) throws IOException { 2867 if (blkmode == newmode) { 2868 return blkmode; 2869 } 2870 if (newmode) { 2871 pos = 0; 2872 end = 0; 2873 unread = 0; 2874 } else if (pos < end) { 2875 throw new IllegalStateException("unread block data"); 2876 } 2877 blkmode = newmode; 2878 return !blkmode; 2879 } 2880 2881 /** 2882 * Returns true if the stream is currently in block data mode, false 2883 * otherwise. 2884 */ 2885 boolean getBlockDataMode() { 2886 return blkmode; 2887 } 2888 2889 /** 2890 * If in block data mode, skips to the end of the current group of data 2891 * blocks (but does not unset block data mode). If not in block data 2892 * mode, throws an IllegalStateException. 2893 */ 2894 void skipBlockData() throws IOException { 2895 if (!blkmode) { 2896 throw new IllegalStateException("not in block data mode"); 2897 } 2898 while (end >= 0) { 2899 refill(); 2900 } 2901 } 2902 2903 /** 2904 * Attempts to read in the next block data header (if any). If 2905 * canBlock is false and a full header cannot be read without possibly 2906 * blocking, returns HEADER_BLOCKED, else if the next element in the 2907 * stream is a block data header, returns the block data length 2908 * specified by the header, else returns -1. 2909 */ 2910 private int readBlockHeader(boolean canBlock) throws IOException { 2911 if (defaultDataEnd) { 2912 /* 2913 * Fix for 4360508: stream is currently at the end of a field 2914 * value block written via default serialization; since there 2915 * is no terminating TC_ENDBLOCKDATA tag, simulate 2916 * end-of-custom-data behavior explicitly. 2917 */ 2918 return -1; 2919 } 2920 try { 2921 for (;;) { 2922 int avail = canBlock ? Integer.MAX_VALUE : in.available(); 2923 if (avail == 0) { 2924 return HEADER_BLOCKED; 2925 } 2926 2927 int tc = in.peek(); 2928 switch (tc) { 2929 case TC_BLOCKDATA: 2930 if (avail < 2) { 2931 return HEADER_BLOCKED; 2932 } 2933 in.readFully(hbuf, 0, 2); 2934 return hbuf[1] & 0xFF; 2935 2936 case TC_BLOCKDATALONG: 2937 if (avail < 5) { 2938 return HEADER_BLOCKED; 2939 } 2940 in.readFully(hbuf, 0, 5); 2941 int len = Bits.getInt(hbuf, 1); 2942 if (len < 0) { 2943 throw new StreamCorruptedException( 2944 "illegal block data header length: " + 2945 len); 2946 } 2947 return len; 2948 2949 /* 2950 * TC_RESETs may occur in between data blocks. 2951 * Unfortunately, this case must be parsed at a lower 2952 * level than other typecodes, since primitive data 2953 * reads may span data blocks separated by a TC_RESET. 2954 */ 2955 case TC_RESET: 2956 in.read(); 2957 handleReset(); 2958 break; 2959 2960 default: 2961 if (tc >= 0 && (tc < TC_BASE || tc > TC_MAX)) { 2962 throw new StreamCorruptedException( 2963 String.format("invalid type code: %02X", 2964 tc)); 2965 } 2966 return -1; 2967 } 2968 } 2969 } catch (EOFException ex) { 2970 throw new StreamCorruptedException( 2971 "unexpected EOF while reading block data header"); 2972 } 2973 } 2974 2975 /** 2976 * Refills internal buffer buf with block data. Any data in buf at the 2977 * time of the call is considered consumed. Sets the pos, end, and 2978 * unread fields to reflect the new amount of available block data; if 2979 * the next element in the stream is not a data block, sets pos and 2980 * unread to 0 and end to -1. 2981 */ 2982 private void refill() throws IOException { 2983 try { 2984 do { 2985 pos = 0; 2986 if (unread > 0) { 2987 int n = 2988 in.read(buf, 0, Math.min(unread, MAX_BLOCK_SIZE)); 2989 if (n >= 0) { 2990 end = n; 2991 unread -= n; 2992 } else { 2993 throw new StreamCorruptedException( 2994 "unexpected EOF in middle of data block"); 2995 } 2996 } else { 2997 int n = readBlockHeader(true); 2998 if (n >= 0) { 2999 end = 0; 3000 unread = n; 3001 } else { 3002 end = -1; 3003 unread = 0; 3004 } 3005 } 3006 } while (pos == end); 3007 } catch (IOException ex) { 3008 pos = 0; 3009 end = -1; 3010 unread = 0; 3011 throw ex; 3012 } 3013 } 3014 3015 /** 3016 * If in block data mode, returns the number of unconsumed bytes 3017 * remaining in the current data block. If not in block data mode, 3018 * throws an IllegalStateException. 3019 */ 3020 int currentBlockRemaining() { 3021 if (blkmode) { 3022 return (end >= 0) ? (end - pos) + unread : 0; 3023 } else { 3024 throw new IllegalStateException(); 3025 } 3026 } 3027 3028 /** 3029 * Peeks at (but does not consume) and returns the next byte value in 3030 * the stream, or -1 if the end of the stream/block data (if in block 3031 * data mode) has been reached. 3032 */ 3033 int peek() throws IOException { 3034 if (blkmode) { 3035 if (pos == end) { 3036 refill(); 3037 } 3038 return (end >= 0) ? (buf[pos] & 0xFF) : -1; 3039 } else { 3040 return in.peek(); 3041 } 3042 } 3043 3044 /** 3045 * Peeks at (but does not consume) and returns the next byte value in 3046 * the stream, or throws EOFException if end of stream/block data has 3047 * been reached. 3048 */ 3049 byte peekByte() throws IOException { 3050 int val = peek(); 3051 if (val < 0) { 3052 throw new EOFException(); 3053 } 3054 return (byte) val; 3055 } 3056 3057 3058 /* ----------------- generic input stream methods ------------------ */ 3059 /* 3060 * The following methods are equivalent to their counterparts in 3061 * InputStream, except that they interpret data block boundaries and 3062 * read the requested data from within data blocks when in block data 3063 * mode. 3064 */ 3065 3066 public int read() throws IOException { 3067 if (blkmode) { 3068 if (pos == end) { 3069 refill(); 3070 } 3071 return (end >= 0) ? (buf[pos++] & 0xFF) : -1; 3072 } else { 3073 return in.read(); 3074 } 3075 } 3076 3077 public int read(byte[] b, int off, int len) throws IOException { 3078 return read(b, off, len, false); 3079 } 3080 3081 public long skip(long len) throws IOException { 3082 long remain = len; 3083 while (remain > 0) { 3084 if (blkmode) { 3085 if (pos == end) { 3086 refill(); 3087 } 3088 if (end < 0) { 3089 break; 3090 } 3091 int nread = (int) Math.min(remain, end - pos); 3092 remain -= nread; 3093 pos += nread; 3094 } else { 3095 int nread = (int) Math.min(remain, MAX_BLOCK_SIZE); 3096 if ((nread = in.read(buf, 0, nread)) < 0) { 3097 break; 3098 } 3099 remain -= nread; 3100 } 3101 } 3102 return len - remain; 3103 } 3104 3105 public int available() throws IOException { 3106 if (blkmode) { 3107 if ((pos == end) && (unread == 0)) { 3108 int n; 3109 while ((n = readBlockHeader(false)) == 0) ; 3110 switch (n) { 3111 case HEADER_BLOCKED: 3112 break; 3113 3114 case -1: 3115 pos = 0; 3116 end = -1; 3117 break; 3118 3119 default: 3120 pos = 0; 3121 end = 0; 3122 unread = n; 3123 break; 3124 } 3125 } 3126 // avoid unnecessary call to in.available() if possible 3127 int unreadAvail = (unread > 0) ? 3128 Math.min(in.available(), unread) : 0; 3129 return (end >= 0) ? (end - pos) + unreadAvail : 0; 3130 } else { 3131 return in.available(); 3132 } 3133 } 3134 3135 public void close() throws IOException { 3136 if (blkmode) { 3137 pos = 0; 3138 end = -1; 3139 unread = 0; 3140 } 3141 in.close(); 3142 } 3143 3144 /** 3145 * Attempts to read len bytes into byte array b at offset off. Returns 3146 * the number of bytes read, or -1 if the end of stream/block data has 3147 * been reached. If copy is true, reads values into an intermediate 3148 * buffer before copying them to b (to avoid exposing a reference to 3149 * b). 3150 */ 3151 int read(byte[] b, int off, int len, boolean copy) throws IOException { 3152 if (len == 0) { 3153 return 0; 3154 } else if (blkmode) { 3155 if (pos == end) { 3156 refill(); 3157 } 3158 if (end < 0) { 3159 return -1; 3160 } 3161 int nread = Math.min(len, end - pos); 3162 System.arraycopy(buf, pos, b, off, nread); 3163 pos += nread; 3164 return nread; 3165 } else if (copy) { 3166 int nread = in.read(buf, 0, Math.min(len, MAX_BLOCK_SIZE)); 3167 if (nread > 0) { 3168 System.arraycopy(buf, 0, b, off, nread); 3169 } 3170 return nread; 3171 } else { 3172 return in.read(b, off, len); 3173 } 3174 } 3175 3176 /* ----------------- primitive data input methods ------------------ */ 3177 /* 3178 * The following methods are equivalent to their counterparts in 3179 * DataInputStream, except that they interpret data block boundaries 3180 * and read the requested data from within data blocks when in block 3181 * data mode. 3182 */ 3183 3184 public void readFully(byte[] b) throws IOException { 3185 readFully(b, 0, b.length, false); 3186 } 3187 3188 public void readFully(byte[] b, int off, int len) throws IOException { 3189 readFully(b, off, len, false); 3190 } 3191 3192 public void readFully(byte[] b, int off, int len, boolean copy) 3193 throws IOException 3194 { 3195 while (len > 0) { 3196 int n = read(b, off, len, copy); 3197 if (n < 0) { 3198 throw new EOFException(); 3199 } 3200 off += n; 3201 len -= n; 3202 } 3203 } 3204 3205 public int skipBytes(int n) throws IOException { 3206 return din.skipBytes(n); 3207 } 3208 3209 public boolean readBoolean() throws IOException { 3210 int v = read(); 3211 if (v < 0) { 3212 throw new EOFException(); 3213 } 3214 return (v != 0); 3215 } 3216 3217 public byte readByte() throws IOException { 3218 int v = read(); 3219 if (v < 0) { 3220 throw new EOFException(); 3221 } 3222 return (byte) v; 3223 } 3224 3225 public int readUnsignedByte() throws IOException { 3226 int v = read(); 3227 if (v < 0) { 3228 throw new EOFException(); 3229 } 3230 return v; 3231 } 3232 3233 public char readChar() throws IOException { 3234 if (!blkmode) { 3235 pos = 0; 3236 in.readFully(buf, 0, 2); 3237 } else if (end - pos < 2) { 3238 return din.readChar(); 3239 } 3240 char v = Bits.getChar(buf, pos); 3241 pos += 2; 3242 return v; 3243 } 3244 3245 public short readShort() throws IOException { 3246 if (!blkmode) { 3247 pos = 0; 3248 in.readFully(buf, 0, 2); 3249 } else if (end - pos < 2) { 3250 return din.readShort(); 3251 } 3252 short v = Bits.getShort(buf, pos); 3253 pos += 2; 3254 return v; 3255 } 3256 3257 public int readUnsignedShort() throws IOException { 3258 if (!blkmode) { 3259 pos = 0; 3260 in.readFully(buf, 0, 2); 3261 } else if (end - pos < 2) { 3262 return din.readUnsignedShort(); 3263 } 3264 int v = Bits.getShort(buf, pos) & 0xFFFF; 3265 pos += 2; 3266 return v; 3267 } 3268 3269 public int readInt() throws IOException { 3270 if (!blkmode) { 3271 pos = 0; 3272 in.readFully(buf, 0, 4); 3273 } else if (end - pos < 4) { 3274 return din.readInt(); 3275 } 3276 int v = Bits.getInt(buf, pos); 3277 pos += 4; 3278 return v; 3279 } 3280 3281 public float readFloat() throws IOException { 3282 if (!blkmode) { 3283 pos = 0; 3284 in.readFully(buf, 0, 4); 3285 } else if (end - pos < 4) { 3286 return din.readFloat(); 3287 } 3288 float v = Bits.getFloat(buf, pos); 3289 pos += 4; 3290 return v; 3291 } 3292 3293 public long readLong() throws IOException { 3294 if (!blkmode) { 3295 pos = 0; 3296 in.readFully(buf, 0, 8); 3297 } else if (end - pos < 8) { 3298 return din.readLong(); 3299 } 3300 long v = Bits.getLong(buf, pos); 3301 pos += 8; 3302 return v; 3303 } 3304 3305 public double readDouble() throws IOException { 3306 if (!blkmode) { 3307 pos = 0; 3308 in.readFully(buf, 0, 8); 3309 } else if (end - pos < 8) { 3310 return din.readDouble(); 3311 } 3312 double v = Bits.getDouble(buf, pos); 3313 pos += 8; 3314 return v; 3315 } 3316 3317 public String readUTF() throws IOException { 3318 return readUTFBody(readUnsignedShort()); 3319 } 3320 3321 @SuppressWarnings("deprecation") 3322 public String readLine() throws IOException { 3323 return din.readLine(); // deprecated, not worth optimizing 3324 } 3325 3326 /* -------------- primitive data array input methods --------------- */ 3327 /* 3328 * The following methods read in spans of primitive data values. 3329 * Though equivalent to calling the corresponding primitive read 3330 * methods repeatedly, these methods are optimized for reading groups 3331 * of primitive data values more efficiently. 3332 */ 3333 3334 void readBooleans(boolean[] v, int off, int len) throws IOException { 3335 int stop, endoff = off + len; 3336 while (off < endoff) { 3337 if (!blkmode) { 3338 int span = Math.min(endoff - off, MAX_BLOCK_SIZE); 3339 in.readFully(buf, 0, span); 3340 stop = off + span; 3341 pos = 0; 3342 } else if (end - pos < 1) { 3343 v[off++] = din.readBoolean(); 3344 continue; 3345 } else { 3346 stop = Math.min(endoff, off + end - pos); 3347 } 3348 3349 while (off < stop) { 3350 v[off++] = Bits.getBoolean(buf, pos++); 3351 } 3352 } 3353 } 3354 3355 void readChars(char[] v, int off, int len) throws IOException { 3356 int stop, endoff = off + len; 3357 while (off < endoff) { 3358 if (!blkmode) { 3359 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1); 3360 in.readFully(buf, 0, span << 1); 3361 stop = off + span; 3362 pos = 0; 3363 } else if (end - pos < 2) { 3364 v[off++] = din.readChar(); 3365 continue; 3366 } else { 3367 stop = Math.min(endoff, off + ((end - pos) >> 1)); 3368 } 3369 3370 while (off < stop) { 3371 v[off++] = Bits.getChar(buf, pos); 3372 pos += 2; 3373 } 3374 } 3375 } 3376 3377 void readShorts(short[] v, int off, int len) throws IOException { 3378 int stop, endoff = off + len; 3379 while (off < endoff) { 3380 if (!blkmode) { 3381 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 1); 3382 in.readFully(buf, 0, span << 1); 3383 stop = off + span; 3384 pos = 0; 3385 } else if (end - pos < 2) { 3386 v[off++] = din.readShort(); 3387 continue; 3388 } else { 3389 stop = Math.min(endoff, off + ((end - pos) >> 1)); 3390 } 3391 3392 while (off < stop) { 3393 v[off++] = Bits.getShort(buf, pos); 3394 pos += 2; 3395 } 3396 } 3397 } 3398 3399 void readInts(int[] v, int off, int len) throws IOException { 3400 int stop, endoff = off + len; 3401 while (off < endoff) { 3402 if (!blkmode) { 3403 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2); 3404 in.readFully(buf, 0, span << 2); 3405 stop = off + span; 3406 pos = 0; 3407 } else if (end - pos < 4) { 3408 v[off++] = din.readInt(); 3409 continue; 3410 } else { 3411 stop = Math.min(endoff, off + ((end - pos) >> 2)); 3412 } 3413 3414 while (off < stop) { 3415 v[off++] = Bits.getInt(buf, pos); 3416 pos += 4; 3417 } 3418 } 3419 } 3420 3421 void readFloats(float[] v, int off, int len) throws IOException { 3422 int span, endoff = off + len; 3423 while (off < endoff) { 3424 if (!blkmode) { 3425 span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 2); 3426 in.readFully(buf, 0, span << 2); 3427 pos = 0; 3428 } else if (end - pos < 4) { 3429 v[off++] = din.readFloat(); 3430 continue; 3431 } else { 3432 span = Math.min(endoff - off, ((end - pos) >> 2)); 3433 } 3434 3435 bytesToFloats(buf, pos, v, off, span); 3436 off += span; 3437 pos += span << 2; 3438 } 3439 } 3440 3441 void readLongs(long[] v, int off, int len) throws IOException { 3442 int stop, endoff = off + len; 3443 while (off < endoff) { 3444 if (!blkmode) { 3445 int span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3); 3446 in.readFully(buf, 0, span << 3); 3447 stop = off + span; 3448 pos = 0; 3449 } else if (end - pos < 8) { 3450 v[off++] = din.readLong(); 3451 continue; 3452 } else { 3453 stop = Math.min(endoff, off + ((end - pos) >> 3)); 3454 } 3455 3456 while (off < stop) { 3457 v[off++] = Bits.getLong(buf, pos); 3458 pos += 8; 3459 } 3460 } 3461 } 3462 3463 void readDoubles(double[] v, int off, int len) throws IOException { 3464 int span, endoff = off + len; 3465 while (off < endoff) { 3466 if (!blkmode) { 3467 span = Math.min(endoff - off, MAX_BLOCK_SIZE >> 3); 3468 in.readFully(buf, 0, span << 3); 3469 pos = 0; 3470 } else if (end - pos < 8) { 3471 v[off++] = din.readDouble(); 3472 continue; 3473 } else { 3474 span = Math.min(endoff - off, ((end - pos) >> 3)); 3475 } 3476 3477 bytesToDoubles(buf, pos, v, off, span); 3478 off += span; 3479 pos += span << 3; 3480 } 3481 } 3482 3483 /** 3484 * Reads in string written in "long" UTF format. "Long" UTF format is 3485 * identical to standard UTF, except that it uses an 8 byte header 3486 * (instead of the standard 2 bytes) to convey the UTF encoding length. 3487 */ 3488 String readLongUTF() throws IOException { 3489 return readUTFBody(readLong()); 3490 } 3491 3492 /** 3493 * Reads in the "body" (i.e., the UTF representation minus the 2-byte 3494 * or 8-byte length header) of a UTF encoding, which occupies the next 3495 * utflen bytes. 3496 */ 3497 private String readUTFBody(long utflen) throws IOException { 3498 StringBuilder sbuf; 3499 if (utflen > 0 && utflen < Integer.MAX_VALUE) { 3500 // a reasonable initial capacity based on the UTF length 3501 int initialCapacity = Math.min((int)utflen, 0xFFFF); 3502 sbuf = new StringBuilder(initialCapacity); 3503 } else { 3504 sbuf = new StringBuilder(); 3505 } 3506 3507 if (!blkmode) { 3508 end = pos = 0; 3509 } 3510 3511 while (utflen > 0) { 3512 int avail = end - pos; 3513 if (avail >= 3 || (long) avail == utflen) { 3514 utflen -= readUTFSpan(sbuf, utflen); 3515 } else { 3516 if (blkmode) { 3517 // near block boundary, read one byte at a time 3518 utflen -= readUTFChar(sbuf, utflen); 3519 } else { 3520 // shift and refill buffer manually 3521 if (avail > 0) { 3522 System.arraycopy(buf, pos, buf, 0, avail); 3523 } 3524 pos = 0; 3525 end = (int) Math.min(MAX_BLOCK_SIZE, utflen); 3526 in.readFully(buf, avail, end - avail); 3527 } 3528 } 3529 } 3530 3531 return sbuf.toString(); 3532 } 3533 3534 /** 3535 * Reads span of UTF-encoded characters out of internal buffer 3536 * (starting at offset pos and ending at or before offset end), 3537 * consuming no more than utflen bytes. Appends read characters to 3538 * sbuf. Returns the number of bytes consumed. 3539 */ 3540 private long readUTFSpan(StringBuilder sbuf, long utflen) 3541 throws IOException 3542 { 3543 int cpos = 0; 3544 int start = pos; 3545 int avail = Math.min(end - pos, CHAR_BUF_SIZE); 3546 // stop short of last char unless all of utf bytes in buffer 3547 int stop = pos + ((utflen > avail) ? avail - 2 : (int) utflen); 3548 boolean outOfBounds = false; 3549 3550 try { 3551 while (pos < stop) { 3552 int b1, b2, b3; 3553 b1 = buf[pos++] & 0xFF; 3554 switch (b1 >> 4) { 3555 case 0: 3556 case 1: 3557 case 2: 3558 case 3: 3559 case 4: 3560 case 5: 3561 case 6: 3562 case 7: // 1 byte format: 0xxxxxxx 3563 cbuf[cpos++] = (char) b1; 3564 break; 3565 3566 case 12: 3567 case 13: // 2 byte format: 110xxxxx 10xxxxxx 3568 b2 = buf[pos++]; 3569 if ((b2 & 0xC0) != 0x80) { 3570 throw new UTFDataFormatException(); 3571 } 3572 cbuf[cpos++] = (char) (((b1 & 0x1F) << 6) | 3573 ((b2 & 0x3F) << 0)); 3574 break; 3575 3576 case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx 3577 b3 = buf[pos + 1]; 3578 b2 = buf[pos + 0]; 3579 pos += 2; 3580 if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { 3581 throw new UTFDataFormatException(); 3582 } 3583 cbuf[cpos++] = (char) (((b1 & 0x0F) << 12) | 3584 ((b2 & 0x3F) << 6) | 3585 ((b3 & 0x3F) << 0)); 3586 break; 3587 3588 default: // 10xx xxxx, 1111 xxxx 3589 throw new UTFDataFormatException(); 3590 } 3591 } 3592 } catch (ArrayIndexOutOfBoundsException ex) { 3593 outOfBounds = true; 3594 } finally { 3595 if (outOfBounds || (pos - start) > utflen) { 3596 /* 3597 * Fix for 4450867: if a malformed utf char causes the 3598 * conversion loop to scan past the expected end of the utf 3599 * string, only consume the expected number of utf bytes. 3600 */ 3601 pos = start + (int) utflen; 3602 throw new UTFDataFormatException(); 3603 } 3604 } 3605 3606 sbuf.append(cbuf, 0, cpos); 3607 return pos - start; 3608 } 3609 3610 /** 3611 * Reads in single UTF-encoded character one byte at a time, appends 3612 * the character to sbuf, and returns the number of bytes consumed. 3613 * This method is used when reading in UTF strings written in block 3614 * data mode to handle UTF-encoded characters which (potentially) 3615 * straddle block-data boundaries. 3616 */ 3617 private int readUTFChar(StringBuilder sbuf, long utflen) 3618 throws IOException 3619 { 3620 int b1, b2, b3; 3621 b1 = readByte() & 0xFF; 3622 switch (b1 >> 4) { 3623 case 0: 3624 case 1: 3625 case 2: 3626 case 3: 3627 case 4: 3628 case 5: 3629 case 6: 3630 case 7: // 1 byte format: 0xxxxxxx 3631 sbuf.append((char) b1); 3632 return 1; 3633 3634 case 12: 3635 case 13: // 2 byte format: 110xxxxx 10xxxxxx 3636 if (utflen < 2) { 3637 throw new UTFDataFormatException(); 3638 } 3639 b2 = readByte(); 3640 if ((b2 & 0xC0) != 0x80) { 3641 throw new UTFDataFormatException(); 3642 } 3643 sbuf.append((char) (((b1 & 0x1F) << 6) | 3644 ((b2 & 0x3F) << 0))); 3645 return 2; 3646 3647 case 14: // 3 byte format: 1110xxxx 10xxxxxx 10xxxxxx 3648 if (utflen < 3) { 3649 if (utflen == 2) { 3650 readByte(); // consume remaining byte 3651 } 3652 throw new UTFDataFormatException(); 3653 } 3654 b2 = readByte(); 3655 b3 = readByte(); 3656 if ((b2 & 0xC0) != 0x80 || (b3 & 0xC0) != 0x80) { 3657 throw new UTFDataFormatException(); 3658 } 3659 sbuf.append((char) (((b1 & 0x0F) << 12) | 3660 ((b2 & 0x3F) << 6) | 3661 ((b3 & 0x3F) << 0))); 3662 return 3; 3663 3664 default: // 10xx xxxx, 1111 xxxx 3665 throw new UTFDataFormatException(); 3666 } 3667 } 3668 3669 /** 3670 * Returns the number of bytes read from the input stream. 3671 * @return the number of bytes read from the input stream 3672 */ 3673 long getBytesRead() { 3674 return in.getBytesRead(); 3675 } 3676 } 3677 3678 /** 3679 * Unsynchronized table which tracks wire handle to object mappings, as 3680 * well as ClassNotFoundExceptions associated with deserialized objects. 3681 * This class implements an exception-propagation algorithm for 3682 * determining which objects should have ClassNotFoundExceptions associated 3683 * with them, taking into account cycles and discontinuities (e.g., skipped 3684 * fields) in the object graph. 3685 * 3686 * <p>General use of the table is as follows: during deserialization, a 3687 * given object is first assigned a handle by calling the assign method. 3688 * This method leaves the assigned handle in an "open" state, wherein 3689 * dependencies on the exception status of other handles can be registered 3690 * by calling the markDependency method, or an exception can be directly 3691 * associated with the handle by calling markException. When a handle is 3692 * tagged with an exception, the HandleTable assumes responsibility for 3693 * propagating the exception to any other objects which depend 3694 * (transitively) on the exception-tagged object. 3695 * 3696 * <p>Once all exception information/dependencies for the handle have been 3697 * registered, the handle should be "closed" by calling the finish method 3698 * on it. The act of finishing a handle allows the exception propagation 3699 * algorithm to aggressively prune dependency links, lessening the 3700 * performance/memory impact of exception tracking. 3701 * 3702 * <p>Note that the exception propagation algorithm used depends on handles 3703 * being assigned/finished in LIFO order; however, for simplicity as well 3704 * as memory conservation, it does not enforce this constraint. 3705 */ 3706 // REMIND: add full description of exception propagation algorithm? 3707 private static class HandleTable { 3708 3709 /* status codes indicating whether object has associated exception */ 3710 private static final byte STATUS_OK = 1; 3711 private static final byte STATUS_UNKNOWN = 2; 3712 private static final byte STATUS_EXCEPTION = 3; 3713 3714 /** array mapping handle -> object status */ 3715 byte[] status; 3716 /** array mapping handle -> object/exception (depending on status) */ 3717 Object[] entries; 3718 /** array mapping handle -> list of dependent handles (if any) */ 3719 HandleList[] deps; 3720 /** lowest unresolved dependency */ 3721 int lowDep = -1; 3722 /** number of handles in table */ 3723 int size = 0; 3724 3725 /** 3726 * Creates handle table with the given initial capacity. 3727 */ 3728 HandleTable(int initialCapacity) { 3729 status = new byte[initialCapacity]; 3730 entries = new Object[initialCapacity]; 3731 deps = new HandleList[initialCapacity]; 3732 } 3733 3734 /** 3735 * Assigns next available handle to given object, and returns assigned 3736 * handle. Once object has been completely deserialized (and all 3737 * dependencies on other objects identified), the handle should be 3738 * "closed" by passing it to finish(). 3739 */ 3740 int assign(Object obj) { 3741 if (size >= entries.length) { 3742 grow(); 3743 } 3744 status[size] = STATUS_UNKNOWN; 3745 entries[size] = obj; 3746 return size++; 3747 } 3748 3749 /** 3750 * Registers a dependency (in exception status) of one handle on 3751 * another. The dependent handle must be "open" (i.e., assigned, but 3752 * not finished yet). No action is taken if either dependent or target 3753 * handle is NULL_HANDLE. Additionally, no action is taken if the 3754 * dependent and target are the same. 3755 */ 3756 void markDependency(int dependent, int target) { 3757 if (dependent == target || dependent == NULL_HANDLE || target == NULL_HANDLE) { 3758 return; 3759 } 3760 switch (status[dependent]) { 3761 3762 case STATUS_UNKNOWN: 3763 switch (status[target]) { 3764 case STATUS_OK: 3765 // ignore dependencies on objs with no exception 3766 break; 3767 3768 case STATUS_EXCEPTION: 3769 // eagerly propagate exception 3770 markException(dependent, 3771 (ClassNotFoundException) entries[target]); 3772 break; 3773 3774 case STATUS_UNKNOWN: 3775 // add to dependency list of target 3776 if (deps[target] == null) { 3777 deps[target] = new HandleList(); 3778 } 3779 deps[target].add(dependent); 3780 3781 // remember lowest unresolved target seen 3782 if (lowDep < 0 || lowDep > target) { 3783 lowDep = target; 3784 } 3785 break; 3786 3787 default: 3788 throw new InternalError(); 3789 } 3790 break; 3791 3792 case STATUS_EXCEPTION: 3793 break; 3794 3795 default: 3796 throw new InternalError(); 3797 } 3798 } 3799 3800 /** 3801 * Associates a ClassNotFoundException (if one not already associated) 3802 * with the currently active handle and propagates it to other 3803 * referencing objects as appropriate. The specified handle must be 3804 * "open" (i.e., assigned, but not finished yet). 3805 */ 3806 void markException(int handle, ClassNotFoundException ex) { 3807 switch (status[handle]) { 3808 case STATUS_UNKNOWN: 3809 status[handle] = STATUS_EXCEPTION; 3810 entries[handle] = ex; 3811 3812 // propagate exception to dependents 3813 HandleList dlist = deps[handle]; 3814 if (dlist != null) { 3815 int ndeps = dlist.size(); 3816 for (int i = 0; i < ndeps; i++) { 3817 markException(dlist.get(i), ex); 3818 } 3819 deps[handle] = null; 3820 } 3821 break; 3822 3823 case STATUS_EXCEPTION: 3824 break; 3825 3826 default: 3827 throw new InternalError(); 3828 } 3829 } 3830 3831 /** 3832 * Marks given handle as finished, meaning that no new dependencies 3833 * will be marked for handle. Calls to the assign and finish methods 3834 * must occur in LIFO order. 3835 */ 3836 void finish(int handle) { 3837 int end; 3838 if (lowDep < 0) { 3839 // no pending unknowns, only resolve current handle 3840 end = handle + 1; 3841 } else if (lowDep >= handle) { 3842 // pending unknowns now clearable, resolve all upward handles 3843 end = size; 3844 lowDep = -1; 3845 } else { 3846 // unresolved backrefs present, can't resolve anything yet 3847 return; 3848 } 3849 3850 // change STATUS_UNKNOWN -> STATUS_OK in selected span of handles 3851 for (int i = handle; i < end; i++) { 3852 switch (status[i]) { 3853 case STATUS_UNKNOWN: 3854 status[i] = STATUS_OK; 3855 deps[i] = null; 3856 break; 3857 3858 case STATUS_OK: 3859 case STATUS_EXCEPTION: 3860 break; 3861 3862 default: 3863 throw new InternalError(); 3864 } 3865 } 3866 } 3867 3868 /** 3869 * Assigns a new object to the given handle. The object previously 3870 * associated with the handle is forgotten. This method has no effect 3871 * if the given handle already has an exception associated with it. 3872 * This method may be called at any time after the handle is assigned. 3873 */ 3874 void setObject(int handle, Object obj) { 3875 switch (status[handle]) { 3876 case STATUS_UNKNOWN: 3877 case STATUS_OK: 3878 entries[handle] = obj; 3879 break; 3880 3881 case STATUS_EXCEPTION: 3882 break; 3883 3884 default: 3885 throw new InternalError(); 3886 } 3887 } 3888 3889 /** 3890 * Looks up and returns object associated with the given handle. 3891 * Returns null if the given handle is NULL_HANDLE, or if it has an 3892 * associated ClassNotFoundException. 3893 */ 3894 Object lookupObject(int handle) { 3895 return (handle != NULL_HANDLE && 3896 status[handle] != STATUS_EXCEPTION) ? 3897 entries[handle] : null; 3898 } 3899 3900 /** 3901 * Looks up and returns ClassNotFoundException associated with the 3902 * given handle. Returns null if the given handle is NULL_HANDLE, or 3903 * if there is no ClassNotFoundException associated with the handle. 3904 */ 3905 ClassNotFoundException lookupException(int handle) { 3906 return (handle != NULL_HANDLE && 3907 status[handle] == STATUS_EXCEPTION) ? 3908 (ClassNotFoundException) entries[handle] : null; 3909 } 3910 3911 /** 3912 * Resets table to its initial state. 3913 */ 3914 void clear() { 3915 Arrays.fill(status, 0, size, (byte) 0); 3916 Arrays.fill(entries, 0, size, null); 3917 Arrays.fill(deps, 0, size, null); 3918 lowDep = -1; 3919 size = 0; 3920 } 3921 3922 /** 3923 * Returns number of handles registered in table. 3924 */ 3925 int size() { 3926 return size; 3927 } 3928 3929 /** 3930 * Expands capacity of internal arrays. 3931 */ 3932 private void grow() { 3933 int newCapacity = (entries.length << 1) + 1; 3934 3935 byte[] newStatus = new byte[newCapacity]; 3936 Object[] newEntries = new Object[newCapacity]; 3937 HandleList[] newDeps = new HandleList[newCapacity]; 3938 3939 System.arraycopy(status, 0, newStatus, 0, size); 3940 System.arraycopy(entries, 0, newEntries, 0, size); 3941 System.arraycopy(deps, 0, newDeps, 0, size); 3942 3943 status = newStatus; 3944 entries = newEntries; 3945 deps = newDeps; 3946 } 3947 3948 /** 3949 * Simple growable list of (integer) handles. 3950 */ 3951 private static class HandleList { 3952 private int[] list = new int[4]; 3953 private int size = 0; 3954 3955 public HandleList() { 3956 } 3957 3958 public void add(int handle) { 3959 if (size >= list.length) { 3960 int[] newList = new int[list.length << 1]; 3961 System.arraycopy(list, 0, newList, 0, list.length); 3962 list = newList; 3963 } 3964 list[size++] = handle; 3965 } 3966 3967 public int get(int index) { 3968 if (index >= size) { 3969 throw new ArrayIndexOutOfBoundsException(); 3970 } 3971 return list[index]; 3972 } 3973 3974 public int size() { 3975 return size; 3976 } 3977 } 3978 } 3979 3980 /** 3981 * Method for cloning arrays in case of using unsharing reading 3982 */ 3983 private static Object cloneArray(Object array) { 3984 if (array instanceof Object[]) { 3985 return ((Object[]) array).clone(); 3986 } else if (array instanceof boolean[]) { 3987 return ((boolean[]) array).clone(); 3988 } else if (array instanceof byte[]) { 3989 return ((byte[]) array).clone(); 3990 } else if (array instanceof char[]) { 3991 return ((char[]) array).clone(); 3992 } else if (array instanceof double[]) { 3993 return ((double[]) array).clone(); 3994 } else if (array instanceof float[]) { 3995 return ((float[]) array).clone(); 3996 } else if (array instanceof int[]) { 3997 return ((int[]) array).clone(); 3998 } else if (array instanceof long[]) { 3999 return ((long[]) array).clone(); 4000 } else if (array instanceof short[]) { 4001 return ((short[]) array).clone(); 4002 } else { 4003 throw new AssertionError(); 4004 } 4005 } 4006 4007 private void validateDescriptor(ObjectStreamClass descriptor) { 4008 ObjectStreamClassValidator validating = validator; 4009 if (validating != null) { 4010 validating.validateDescriptor(descriptor); 4011 } 4012 } 4013 4014 // controlled access to ObjectStreamClassValidator 4015 private volatile ObjectStreamClassValidator validator; 4016 4017 private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) { 4018 ois.validator = validator; 4019 } 4020 static { 4021 SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator); 4022 } 4023 } --- EOF ---