| 1 7 8 package java.io; 9 10 import java.io.ObjectStreamClass.WeakClassKey ; 11 import java.lang.ref.ReferenceQueue ; 12 import java.lang.reflect.Array ; 13 import java.lang.reflect.Modifier ; 14 import java.lang.reflect.Proxy ; 15 import java.security.AccessController ; 16 import java.security.PrivilegedAction ; 17 import java.util.Arrays ; 18 import java.util.HashMap ; 19 import java.util.concurrent.ConcurrentHashMap ; 20 import java.util.concurrent.ConcurrentMap ; 21 import java.util.concurrent.atomic.AtomicBoolean ; 22 import static java.io.ObjectStreamClass.processQueue ; 23 24 185 public class ObjectInputStream 186 extends InputStream implements ObjectInput , ObjectStreamConstants  187 { 188 189 private static final int NULL_HANDLE = -1; 190 191 192 private static final Object unsharedMarker = new Object (); 193 194 195 private static final HashMap primClasses = new HashMap (8, 1.0F); 196 static { 197 primClasses.put("boolean", boolean.class); 198 primClasses.put("byte", byte.class); 199 primClasses.put("char", char.class); 200 primClasses.put("short", short.class); 201 primClasses.put("int", int.class); 202 primClasses.put("long", long.class); 203 primClasses.put("float", float.class); 204 primClasses.put("double", double.class); 205 primClasses.put("void", void.class); 206 } 207 208 private static class Caches { 209 210 static final ConcurrentMap <WeakClassKey,Boolean > subclassAudits = 211 new ConcurrentHashMap <WeakClassKey,Boolean >(); 212 213 214 static final ReferenceQueue <Class <?>> subclassAuditsQueue = 215 new ReferenceQueue <Class <?>>(); 216 } 217 218 219 private final BlockDataInputStream bin; 220 221 private final ValidationList vlist; 222 223 private int depth; 224 225 private boolean closed; 226 227 228 private final HandleTable handles; 229 230 private int passHandle = NULL_HANDLE; 231 232 private boolean defaultDataEnd = false; 233 234 235 private byte[] primVals; 236 237 238 private final boolean enableOverride; 239 240 private boolean enableResolve; 241 242 247 private CallbackContext curContext; 248 249 271 public ObjectInputStream(InputStream in) throws IOException { 272 verifySubclass(); 273 bin = new BlockDataInputStream(in); 274 handles = new HandleTable(10); 275 vlist = new ValidationList(); 276 enableOverride = false; 277 readStreamHeader(); 278 bin.setBlockDataMode(true); 279 } 280 281 297 protected ObjectInputStream() throws IOException , SecurityException { 298 SecurityManager sm = System.getSecurityManager(); 299 if (sm != null) { 300 sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); 301 } 302 bin = null; 303 handles = null; 304 vlist = null; 305 enableOverride = true; 306 } 307 308 338 public final Object readObject() 339 throws IOException , ClassNotFoundException  340 { 341 if (enableOverride) { 342 return readObjectOverride(); 343 } 344 345 int outerHandle = passHandle; 347 try { 348 Object obj = readObject0(false); 349 handles.markDependency(outerHandle, passHandle); 350 ClassNotFoundException ex = handles.lookupException(passHandle); 351 if (ex != null) { 352 throw ex; 353 } 354 if (depth == 0) { 355 vlist.doCallbacks(); 356 } 357 return obj; 358 } finally { 359 passHandle = outerHandle; 360 if (closed && depth == 0) { 361 clear(); 362 } 363 } 364 } 365 366 383 protected Object readObjectOverride() 384 throws IOException , ClassNotFoundException  385 { 386 return null; 387 } 388 389 436 public Object readUnshared() throws IOException , ClassNotFoundException { 437 int outerHandle = passHandle; 439 try { 440 Object obj = readObject0(true); 441 handles.markDependency(outerHandle, passHandle); 442 ClassNotFoundException ex = handles.lookupException(passHandle); 443 if (ex != null) { 444 throw ex; 445 } 446 if (depth == 0) { 447 vlist.doCallbacks(); 448 } 449 return obj; 450 } finally { 451 passHandle = outerHandle; 452 if (closed && depth == 0) { 453 clear(); 454 } 455 } 456 } 457 458 470 public void defaultReadObject() 471 throws IOException , ClassNotFoundException  472 { 473 if (curContext == null) { 474 throw new NotActiveException ("not in call to readObject"); 475 } 476 Object curObj = curContext.getObj(); 477 ObjectStreamClass curDesc = curContext.getDesc(); 478 bin.setBlockDataMode(false); 479 defaultReadFields(curObj, curDesc); 480 bin.setBlockDataMode(true); 481 if (!curDesc.hasWriteObjectData()) { 482 487 defaultDataEnd = true; 488 } 489 ClassNotFoundException ex = handles.lookupException(passHandle); 490 if (ex != null) { 491 throw ex; 492 } 493 } 494 495 508 public ObjectInputStream.GetField readFields() 509 throws IOException , ClassNotFoundException  510 { 511 if (curContext == null) { 512 throw new NotActiveException ("not in call to readObject"); 513 } 514 Object curObj = curContext.getObj(); 515 ObjectStreamClass curDesc = curContext.getDesc(); 516 bin.setBlockDataMode(false); 517 GetFieldImpl getField = new GetFieldImpl(curDesc); 518 getField.readFields(); 519 bin.setBlockDataMode(true); 520 if (!curDesc.hasWriteObjectData()) { 521 526 defaultDataEnd = true; 527 } 528 529 return getField; 530 } 531 532 548 public void registerValidation(ObjectInputValidation obj, int prio) 549 throws NotActiveException , InvalidObjectException  550 { 551 if (depth == 0) { 552 throw new NotActiveException ("stream inactive"); 553 } 554 vlist.register(obj, prio); 555 } 556 557 580 protected Class <?> resolveClass(ObjectStreamClass desc) 581 throws IOException , ClassNotFoundException  582 { 583 String name = desc.getName(); 584 try { 585 return Class.forName(name, false, latestUserDefinedLoader()); 586 } catch (ClassNotFoundException ex) { 587 Class cl = (Class ) primClasses.get(name); 588 if (cl != null) { 589 return cl; 590 } else { 591 throw ex; 592 } 593 } 594 } 595 596 647 protected Class <?> resolveProxyClass(String [] interfaces) 648 throws IOException , ClassNotFoundException  649 { 650 ClassLoader latestLoader = latestUserDefinedLoader(); 651 ClassLoader nonPublicLoader = null; 652 boolean hasNonPublicInterface = false; 653 654 Class [] classObjs = new Class [interfaces.length]; 656 for (int i = 0; i < interfaces.length; i++) { 657 Class cl = Class.forName(interfaces[i], false, latestLoader); 658 if ((cl.getModifiers() & Modifier.PUBLIC) == 0) { 659 if (hasNonPublicInterface) { 660 if (nonPublicLoader != cl.getClassLoader()) { 661 throw new IllegalAccessError ( 662 "conflicting non-public interface class loaders"); 663 } 664 } else { 665 nonPublicLoader = cl.getClassLoader(); 666 hasNonPublicInterface = true; 667 } 668 } 669 classObjs[i] = cl; 670 } 671 try { 672 return Proxy.getProxyClass( 673 hasNonPublicInterface ? nonPublicLoader : latestLoader, 674 classObjs); 675 } catch (IllegalArgumentException e) { 676 throw new ClassNotFoundException (null, e); 677 } 678 } 679 680 707 protected Object resolveObject(Object obj) throws IOException { 708 return obj; 709 } 710 711 732 protected boolean enableResolveObject(boolean enable) 733 throws SecurityException  734 { 735 if (enable == enableResolve) { 736 return enable; 737 } 738 if (enable) { 739 SecurityManager sm = System.getSecurityManager(); 740 if (sm != null) { 741 sm.checkPermission(SUBSTITUTION_PERMISSION); 742 } 743 } 744 enableResolve = enable; 745 return !enableResolve; 746 } 747 748 758 protected void readStreamHeader() 759 throws IOException , StreamCorruptedException  760 { 761 if (bin.readShort() != STREAM_MAGIC || 762 bin.readShort() != STREAM_VERSION) 763 { 764 throw new StreamCorruptedException ("invalid stream header"); 765 } 766 } 767 768 785 protected ObjectStreamClass readClassDescriptor() 786 throws IOException , ClassNotFoundException  787 { 788 ObjectStreamClass desc = new ObjectStreamClass (); 789 desc.readNonProxy(this); 790 return desc; 791 } 792 793 799 public int read() throws IOException { 800 return bin.read(); 801 } 802 803 816 public int read(byte[] buf, int off, int len) throws IOException { 817 if (buf == null) { 818 throw new NullPointerException (); 819 } 820 int endoff = off + len; 821 if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) { 822 throw new IndexOutOfBoundsException (); 823 } 824 return bin.read(buf, off, len, false); 825 } 826 827 834 public int available() throws IOException { 835 return bin.available(); 836 } 837 838 844 public void close() throws IOException { 845 849 closed = true; 850 if (depth == 0) { 851 clear(); 852 } 853 bin.close(); 854 } 855 856 863 public boolean readBoolean() throws IOException { 864 return bin.readBoolean(); 865 } 866 867 874 public byte readByte() throws IOException { 875 return bin.readByte(); 876 } 877 878 885 public int readUnsignedByte() throws IOException { 886 return bin.readUnsignedByte(); 887 } 888 889 896 public char readChar() throws IOException { 897 return bin.readChar(); 898 } 899 900 907 public short readShort() throws IOException { 908 return bin.readShort(); 909 } 910 911 918 public int readUnsignedShort() throws IOException { 919 return bin.readUnsignedShort(); 920 } 921 922 929 public int readInt() throws IOException { 930 return bin.readInt(); 931 } 932 933 |