1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.luni.tests.java.io; 19 20import java.io.BufferedInputStream; 21import java.io.ByteArrayInputStream; 22import java.io.ByteArrayOutputStream; 23import java.io.Externalizable; 24import java.io.File; 25import java.io.FileInputStream; 26import java.io.FileNotFoundException; 27import java.io.FileOutputStream; 28import java.io.IOException; 29import java.io.InputStream; 30import java.io.InvalidObjectException; 31import java.io.NotActiveException; 32import java.io.ObjectInput; 33import java.io.ObjectInputStream; 34import java.io.ObjectInputValidation; 35import java.io.ObjectOutput; 36import java.io.ObjectOutputStream; 37import java.io.ObjectStreamClass; 38import java.io.OutputStream; 39import java.io.PipedInputStream; 40import java.io.PipedOutputStream; 41import java.io.Serializable; 42import java.io.SerializablePermission; 43import java.io.StreamCorruptedException; 44import java.lang.reflect.Proxy; 45import java.security.Permission; 46import java.util.Arrays; 47import java.util.HashMap; 48import java.util.Hashtable; 49import java.util.Vector; 50 51import junit.framework.TestCase; 52 53import org.apache.harmony.testframework.serialization.SerializationTest; 54import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert; 55 56@SuppressWarnings("serial") 57public class ObjectInputStreamTest extends TestCase implements 58 Serializable { 59 60 ObjectInputStream ois; 61 62 ObjectOutputStream oos; 63 64 ByteArrayOutputStream bao; 65 66 public class SerializableTestHelper implements Serializable { 67 68 public String aField1; 69 70 public String aField2; 71 72 SerializableTestHelper() { 73 aField1 = null; 74 aField2 = null; 75 } 76 77 SerializableTestHelper(String s, String t) { 78 aField1 = s; 79 aField2 = t; 80 } 81 82 private void readObject(ObjectInputStream ois) throws Exception { 83 // note aField2 is not read 84 ObjectInputStream.GetField fields = ois.readFields(); 85 aField1 = (String) fields.get("aField1", "Zap"); 86 } 87 88 private void writeObject(ObjectOutputStream oos) throws IOException { 89 // note aField2 is not written 90 ObjectOutputStream.PutField fields = oos.putFields(); 91 fields.put("aField1", aField1); 92 oos.writeFields(); 93 } 94 95 public String getText1() { 96 return aField1; 97 } 98 99 public void setText1(String s) { 100 aField1 = s; 101 } 102 103 public String getText2() { 104 return aField2; 105 } 106 107 public void setText2(String s) { 108 aField2 = s; 109 } 110 } 111 112 public static class A1 implements Serializable { 113 114 private static final long serialVersionUID = 5942584913446079661L; 115 116 B1 b1 = new B1(); 117 118 B1 b2 = b1; 119 120 Vector v = new Vector(); 121 } 122 123 public static class B1 implements Serializable { 124 125 int i = 5; 126 127 Hashtable h = new Hashtable(); 128 } 129 130 /** 131 * java.io.ObjectInputStream#readObject() 132 */ 133 public void test_readObjectMissingClasses() throws Exception { 134 SerializationTest.verifySelf(new A1(), new SerializableAssert() { 135 public void assertDeserialized(Serializable initial, 136 Serializable deserialized) { 137 assertEquals(5, ((A1) deserialized).b1.i); 138 } 139 }); 140 } 141 142 /** 143 * java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream) 144 */ 145 public void test_ConstructorLjava_io_InputStream() throws IOException { 146 oos.writeDouble(Double.MAX_VALUE); 147 oos.close(); 148 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 149 ois.close(); 150 oos.close(); 151 152 try { 153 ois = new ObjectInputStream(new ByteArrayInputStream(new byte[90])); 154 fail("StreamCorruptedException expected"); 155 } catch (StreamCorruptedException e) { 156 // Expected 157 } 158 } 159 160 /** 161 * {@link java.io.ObjectInputStream#resolveProxyClass(String[])} 162 */ 163 public void test_resolveProxyClass() throws IOException, 164 ClassNotFoundException { 165 oos.writeBytes("HelloWorld"); 166 oos.close(); 167 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 168 MockObjectInputStream mockIn = new MockObjectInputStream( 169 new ByteArrayInputStream(bao.toByteArray())); 170 Class[] clazzs = { java.io.ObjectInputStream.class, 171 java.io.Reader.class }; 172 for (int i = 0; i < clazzs.length; i++) { 173 Class clazz = clazzs[i]; 174 Class[] interfaceNames = clazz.getInterfaces(); 175 String[] interfaces = new String[interfaceNames.length]; 176 int index = 0; 177 for (Class c : interfaceNames) { 178 interfaces[index] = c.getName(); 179 index++; 180 } 181 Class<?> s = mockIn.resolveProxyClass(interfaces); 182 183 if (Proxy.isProxyClass(s)) { 184 Class[] implementedInterfaces = s.getInterfaces(); 185 for (index = 0; index < implementedInterfaces.length; index++) { 186 assertEquals(interfaceNames[index], 187 implementedInterfaces[index]); 188 } 189 } else { 190 fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor"); 191 } 192 } 193 mockIn.close(); 194 } 195 196 class MockObjectInputStream extends ObjectInputStream { 197 198 public MockObjectInputStream(InputStream input) 199 throws StreamCorruptedException, IOException { 200 super(input); 201 } 202 203 @Override 204 public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException { 205 return super.resolveProxyClass(interfaceNames); 206 } 207 208 } 209 210 /** 211 * java.io.ObjectInputStream#available() 212 */ 213 public void test_available() throws IOException { 214 oos.writeBytes("HelloWorld"); 215 oos.close(); 216 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 217 assertEquals("Read incorrect bytes", 10, ois.available()); 218 ois.close(); 219 } 220 221 /** 222 * java.io.ObjectInputStream#close() 223 */ 224 public void test_close() throws IOException { 225 oos.writeBytes("HelloWorld"); 226 oos.close(); 227 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 228 ois.close(); 229 } 230 231 /** 232 * java.io.ObjectInputStream#defaultReadObject() 233 */ 234 public void test_defaultReadObject() throws Exception { 235 // SM. This method may as well be private, as if called directly it 236 // throws an exception. 237 String s = "HelloWorld"; 238 oos.writeObject(s); 239 oos.close(); 240 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 241 try { 242 ois.defaultReadObject(); 243 fail("NotActiveException expected"); 244 } catch (NotActiveException e) { 245 // Desired behavior 246 } finally { 247 ois.close(); 248 } 249 } 250 251 /** 252 * java.io.ObjectInputStream#read() 253 */ 254 public void test_read() throws IOException { 255 oos.write('T'); 256 oos.close(); 257 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 258 assertEquals("Read incorrect byte value", 'T', ois.read()); 259 ois.close(); 260 } 261 262 /** 263 * java.io.ObjectInputStream#read(byte[], int, int) 264 */ 265 public void test_read$BII() throws IOException { 266 byte[] buf = new byte[10]; 267 oos.writeBytes("HelloWorld"); 268 oos.close(); 269 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 270 ois.read(buf, 0, 10); 271 ois.close(); 272 assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 273 10, "UTF-8")); 274 } 275 276 /** 277 * java.io.ObjectInputStream#readBoolean() 278 */ 279 public void test_readBoolean() throws IOException { 280 oos.writeBoolean(true); 281 oos.close(); 282 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 283 assertTrue("Read incorrect boolean value", ois.readBoolean()); 284 ois.close(); 285 } 286 287 /** 288 * java.io.ObjectInputStream#readByte() 289 */ 290 public void test_readByte() throws IOException { 291 oos.writeByte(127); 292 oos.close(); 293 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 294 assertEquals("Read incorrect byte value", 127, ois.readByte()); 295 ois.close(); 296 } 297 298 /** 299 * java.io.ObjectInputStream#readChar() 300 */ 301 public void test_readChar() throws IOException { 302 oos.writeChar('T'); 303 oos.close(); 304 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 305 assertEquals("Read incorrect char value", 'T', ois.readChar()); 306 ois.close(); 307 } 308 309 /** 310 * java.io.ObjectInputStream#readDouble() 311 */ 312 public void test_readDouble() throws IOException { 313 oos.writeDouble(Double.MAX_VALUE); 314 oos.close(); 315 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 316 assertTrue("Read incorrect double value", 317 ois.readDouble() == Double.MAX_VALUE); 318 ois.close(); 319 } 320 321 /** 322 * java.io.ObjectInputStream#readFields() 323 */ 324 public void test_readFields() throws Exception { 325 326 SerializableTestHelper sth; 327 328 /* 329 * "SerializableTestHelper" is an object created for these tests with 330 * two fields (Strings) and simple implementations of readObject and 331 * writeObject which simply read and write the first field but not the 332 * second 333 */ 334 335 oos.writeObject(new SerializableTestHelper("Gabba", "Jabba")); 336 oos.flush(); 337 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 338 sth = (SerializableTestHelper) (ois.readObject()); 339 assertEquals("readFields / writeFields failed--first field not set", 340 "Gabba", sth.getText1()); 341 assertNull( 342 "readFields / writeFields failed--second field should not have been set", 343 sth.getText2()); 344 } 345 346 /** 347 * java.io.ObjectInputStream#readFloat() 348 */ 349 public void test_readFloat() throws IOException { 350 oos.writeFloat(Float.MAX_VALUE); 351 oos.close(); 352 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 353 assertTrue("Read incorrect float value", 354 ois.readFloat() == Float.MAX_VALUE); 355 ois.close(); 356 } 357 358 /** 359 * java.io.ObjectInputStream#readFully(byte[]) 360 */ 361 public void test_readFully$B() throws IOException { 362 byte[] buf = new byte[10]; 363 oos.writeBytes("HelloWorld"); 364 oos.close(); 365 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 366 ois.readFully(buf); 367 ois.close(); 368 assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 369 10, "UTF-8")); 370 } 371 372 /** 373 * java.io.ObjectInputStream#readFully(byte[], int, int) 374 */ 375 public void test_readFully$BII() throws IOException { 376 byte[] buf = new byte[10]; 377 oos.writeBytes("HelloWorld"); 378 oos.close(); 379 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 380 ois.readFully(buf, 0, 10); 381 ois.close(); 382 assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0, 383 10, "UTF-8")); 384 } 385 386 /** 387 * java.io.ObjectInputStream#readInt() 388 */ 389 public void test_readInt() throws IOException { 390 oos.writeInt(Integer.MAX_VALUE); 391 oos.close(); 392 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 393 assertTrue("Read incorrect int value", 394 ois.readInt() == Integer.MAX_VALUE); 395 ois.close(); 396 } 397 398 /** 399 * java.io.ObjectInputStream#readLine() 400 */ 401 @SuppressWarnings("deprecation") 402 public void test_readLine() throws IOException { 403 oos.writeBytes("HelloWorld\nSecondLine"); 404 oos.close(); 405 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 406 ois.readLine(); 407 assertEquals("Read incorrect string value", "SecondLine", ois 408 .readLine()); 409 ois.close(); 410 } 411 412 /** 413 * java.io.ObjectInputStream#readLong() 414 */ 415 public void test_readLong() throws IOException { 416 oos.writeLong(Long.MAX_VALUE); 417 oos.close(); 418 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 419 assertTrue("Read incorrect long value", 420 ois.readLong() == Long.MAX_VALUE); 421 ois.close(); 422 } 423 424 /** 425 * java.io.ObjectInputStream#readObject() 426 */ 427 public void test_readObject() throws Exception { 428 String s = "HelloWorld"; 429 oos.writeObject(s); 430 oos.close(); 431 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 432 assertEquals("Read incorrect Object value", s, ois.readObject()); 433 ois.close(); 434 435 // Regression for HARMONY-91 436 // dynamically create serialization byte array for the next hierarchy: 437 // - class A implements Serializable 438 // - class C extends A 439 440 byte[] cName = C.class.getName().getBytes("UTF-8"); 441 byte[] aName = A.class.getName().getBytes("UTF-8"); 442 443 ByteArrayOutputStream out = new ByteArrayOutputStream(); 444 445 byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC 446 (byte) 0x00, (byte) 0x05, // STREAM_VERSION 447 (byte) 0x73, // TC_OBJECT 448 (byte) 0x72, // TC_CLASSDESC 449 (byte) 0x00, // only first byte for C class name length 450 }; 451 452 out.write(begStream, 0, begStream.length); 453 out.write(cName.length); // second byte for C class name length 454 out.write(cName, 0, cName.length); // C class name 455 456 byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, 457 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 458 (byte) 0x21, // serialVersionUID = 33L 459 (byte) 0x02, // flags 460 (byte) 0x00, (byte) 0x00, // fields : none 461 (byte) 0x78, // TC_ENDBLOCKDATA 462 (byte) 0x72, // Super class for C: TC_CLASSDESC for A class 463 (byte) 0x00, // only first byte for A class name length 464 }; 465 466 out.write(midStream, 0, midStream.length); 467 out.write(aName.length); // second byte for A class name length 468 out.write(aName, 0, aName.length); // A class name 469 470 byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00, 471 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, 472 (byte) 0x0b, // serialVersionUID = 11L 473 (byte) 0x02, // flags 474 (byte) 0x00, (byte) 0x01, // fields 475 476 (byte) 0x4c, // field description: type L (object) 477 (byte) 0x00, (byte) 0x04, // length 478 // field = 'name' 479 (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, 480 481 (byte) 0x74, // className1: TC_STRING 482 (byte) 0x00, (byte) 0x12, // length 483 // 484 (byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76, 485 (byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61, 486 (byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53, 487 (byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e, 488 (byte) 0x67, (byte) 0x3b, 489 490 (byte) 0x78, // TC_ENDBLOCKDATA 491 (byte) 0x70, // NULL super class for A class 492 493 // classdata 494 (byte) 0x74, // TC_STRING 495 (byte) 0x00, (byte) 0x04, // length 496 (byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value 497 }; 498 499 out.write(endStream, 0, endStream.length); 500 out.flush(); 501 502 // read created serial. form 503 ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream( 504 out.toByteArray())); 505 Object o = ois.readObject(); 506 assertEquals(C.class, o.getClass()); 507 508 // Regression for HARMONY-846 509 assertNull(new ObjectInputStream() {}.readObject()); 510 } 511 512 /** 513 * java.io.ObjectInputStream#readObjectOverride() 514 */ 515 public void test_readObjectOverride() throws Exception { 516 // Regression for HARMONY-846 517 assertNull(new ObjectInputStream() { 518 519 @Override 520 public Object readObjectOverride() throws IOException, 521 ClassNotFoundException { 522 return super.readObjectOverride(); 523 } 524 525 }.readObjectOverride()); 526 } 527 528 public static class A implements Serializable { 529 530 private static final long serialVersionUID = 11L; 531 532 public String name = "name"; 533 } 534 535 public static class B extends A {} 536 537 public static class C extends B { 538 539 private static final long serialVersionUID = 33L; 540 } 541 542 /** 543 * java.io.ObjectInputStream#readObject() 544 */ 545 public void test_readObjectCorrupt() throws IOException, ClassNotFoundException { 546 byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00, 547 00, 0x0B, (byte) 0xB8, 0x4D, 0x65 }; 548 ByteArrayInputStream bin = new ByteArrayInputStream(bytes); 549 try { 550 ObjectInputStream in = new ObjectInputStream(bin); 551 in.readObject(); 552 fail("Unexpected read of corrupted stream"); 553 } catch (StreamCorruptedException e) { 554 // Expected 555 } 556 } 557 558 /** 559 * java.io.ObjectInputStream#readShort() 560 */ 561 public void test_readShort() throws IOException { 562 oos.writeShort(Short.MAX_VALUE); 563 oos.close(); 564 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 565 assertTrue("Read incorrect short value", 566 ois.readShort() == Short.MAX_VALUE); 567 ois.close(); 568 } 569 570 /** 571 * java.io.ObjectInputStream#readUnsignedByte() 572 */ 573 public void test_readUnsignedByte() throws IOException { 574 oos.writeByte(-1); 575 oos.close(); 576 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 577 assertEquals("Read incorrect unsignedByte value", 255, ois 578 .readUnsignedByte()); 579 ois.close(); 580 } 581 582 /** 583 * java.io.ObjectInputStream#readUnsignedShort() 584 */ 585 public void test_readUnsignedShort() throws IOException { 586 oos.writeShort(-1); 587 oos.close(); 588 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 589 assertEquals("Read incorrect unsignedShort value", 65535, ois 590 .readUnsignedShort()); 591 ois.close(); 592 } 593 594 /** 595 * java.io.ObjectInputStream#readUTF() 596 */ 597 public void test_readUTF() throws IOException { 598 oos.writeUTF("HelloWorld"); 599 oos.close(); 600 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 601 assertEquals("Read incorrect utf value", "HelloWorld", ois.readUTF()); 602 ois.close(); 603 } 604 605 /** 606 * java.io.ObjectInputStream#skipBytes(int) 607 */ 608 public void test_skipBytesI() throws IOException { 609 byte[] buf = new byte[10]; 610 oos.writeBytes("HelloWorld"); 611 oos.close(); 612 ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray())); 613 ois.skipBytes(5); 614 ois.read(buf, 0, 5); 615 ois.close(); 616 assertEquals("Skipped incorrect bytes", "World", new String(buf, 0, 5, "UTF-8")); 617 618 // Regression for HARMONY-844 619 try { 620 new ObjectInputStream() {}.skipBytes(0); 621 fail("NullPointerException expected"); 622 } catch (NullPointerException e) {} 623 } 624 625 // Regression Test for JIRA 2192 626 public void test_readObject_withPrimitiveClass() throws Exception { 627 File file = new File("test.ser"); 628 file.deleteOnExit(); 629 Test test = new Test(); 630 ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream( 631 file)); 632 out.writeObject(test); 633 out.close(); 634 635 ObjectInputStream in = new ObjectInputStream(new FileInputStream(file)); 636 Test another = (Test) in.readObject(); 637 in.close(); 638 assertEquals(test, another); 639 } 640 641 //Regression Test for JIRA-2249 642 public static class ObjectOutputStreamWithWriteDesc extends 643 ObjectOutputStream { 644 public ObjectOutputStreamWithWriteDesc(OutputStream os) 645 throws IOException { 646 super(os); 647 } 648 649 @Override 650 public void writeClassDescriptor(ObjectStreamClass desc) 651 throws IOException { 652 } 653 } 654 655 public static class ObjectIutputStreamWithReadDesc extends 656 ObjectInputStream { 657 private Class returnClass; 658 659 public ObjectIutputStreamWithReadDesc(InputStream is, Class returnClass) 660 throws IOException { 661 super(is); 662 this.returnClass = returnClass; 663 } 664 665 @Override 666 public ObjectStreamClass readClassDescriptor() throws IOException, 667 ClassNotFoundException { 668 return ObjectStreamClass.lookup(returnClass); 669 670 } 671 } 672 673 static class TestClassForSerialization implements Serializable { 674 private static final long serialVersionUID = 1L; 675 } 676 677 public void test_ClassDescriptor() throws IOException, 678 ClassNotFoundException { 679 680 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 681 ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc( 682 baos); 683 oos.writeObject(String.class); 684 oos.close(); 685 Class cls = TestClassForSerialization.class; 686 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 687 ObjectIutputStreamWithReadDesc ois = new ObjectIutputStreamWithReadDesc( 688 bais, cls); 689 Object obj = ois.readObject(); 690 ois.close(); 691 assertEquals(cls, obj); 692 } 693 694 // Regression Test for JIRA-2340 695 public static class ObjectOutputStreamWithWriteDesc1 extends 696 ObjectOutputStream { 697 public ObjectOutputStreamWithWriteDesc1(OutputStream os) 698 throws IOException { 699 super(os); 700 } 701 702 @Override 703 public void writeClassDescriptor(ObjectStreamClass desc) 704 throws IOException { 705 super.writeClassDescriptor(desc); 706 } 707 } 708 709 public static class ObjectIutputStreamWithReadDesc1 extends 710 ObjectInputStream { 711 712 public ObjectIutputStreamWithReadDesc1(InputStream is) 713 throws IOException { 714 super(is); 715 } 716 717 @Override 718 public ObjectStreamClass readClassDescriptor() throws IOException, 719 ClassNotFoundException { 720 return super.readClassDescriptor(); 721 } 722 } 723 724 // Regression test for Harmony-1921 725 public static class ObjectInputStreamWithResolve extends ObjectInputStream { 726 public ObjectInputStreamWithResolve(InputStream in) throws IOException { 727 super(in); 728 } 729 730 @Override 731 @SuppressWarnings("unchecked") 732 protected Class resolveClass(ObjectStreamClass desc) 733 throws IOException, ClassNotFoundException { 734 if (desc.getName().equals( 735 "org.apache.harmony.luni.tests.pkg1.TestClass")) { 736 return org.apache.harmony.luni.tests.pkg2.TestClass.class; 737 } 738 return super.resolveClass(desc); 739 } 740 } 741 742 public void test_resolveClass() throws Exception { 743 org.apache.harmony.luni.tests.pkg1.TestClass to1 = new org.apache.harmony.luni.tests.pkg1.TestClass(); 744 to1.i = 555; 745 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 746 ObjectOutputStream oos = new ObjectOutputStream(baos); 747 oos.writeObject(to1); 748 oos.flush(); 749 byte[] bytes = baos.toByteArray(); 750 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 751 ObjectInputStream ois = new ObjectInputStreamWithResolve(bais); 752 org.apache.harmony.luni.tests.pkg2.TestClass to2 = (org.apache.harmony.luni.tests.pkg2.TestClass) ois 753 .readObject(); 754 755 if (to2.i != to1.i) { 756 fail("Wrong object read. Expected val: " + to1.i + ", got: " 757 + to2.i); 758 } 759 } 760 761 static class ObjectInputStreamWithResolveObject extends ObjectInputStream { 762 763 public static Integer intObj = Integer.valueOf(1000); 764 765 public ObjectInputStreamWithResolveObject(InputStream in) throws IOException { 766 super(in); 767 enableResolveObject(true); 768 } 769 770 @Override 771 protected Object resolveObject(Object obj) throws IOException { 772 if(obj instanceof Integer){ 773 obj = intObj; 774 } 775 return super.resolveObject(obj); 776 } 777 } 778 779 /** 780 * java.io.ObjectInputStream#resolveObject(Object) 781 */ 782 public void test_resolveObjectLjava_lang_Object() throws Exception { 783 // Write an Integer object into memory 784 Integer original = new Integer(10); 785 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 786 ObjectOutputStream oos = new ObjectOutputStream(baos); 787 oos.writeObject(original); 788 oos.flush(); 789 oos.close(); 790 791 // Read the object from memory 792 byte[] bytes = baos.toByteArray(); 793 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 794 ObjectInputStreamWithResolveObject ois = 795 new ObjectInputStreamWithResolveObject(bais); 796 Integer actual = (Integer) ois.readObject(); 797 ois.close(); 798 799 // object should be resolved from 10 to 1000 800 assertEquals(ObjectInputStreamWithResolveObject.intObj, actual); 801 } 802 803 public void test_readClassDescriptor() throws IOException, 804 ClassNotFoundException { 805 806 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 807 ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1( 808 baos); 809 ObjectStreamClass desc = ObjectStreamClass 810 .lookup(TestClassForSerialization.class); 811 oos.writeClassDescriptor(desc); 812 oos.close(); 813 814 byte[] bytes = baos.toByteArray(); 815 ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 816 ObjectIutputStreamWithReadDesc1 ois = new ObjectIutputStreamWithReadDesc1( 817 bais); 818 Object obj = ois.readClassDescriptor(); 819 ois.close(); 820 assertEquals(desc.getClass(), obj.getClass()); 821 822 //eof 823 bais = new ByteArrayInputStream(bytes); 824 ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream( 825 bais); 826 ois = new ObjectIutputStreamWithReadDesc1(bis); 827 828 bis.setEOF(true); 829 830 try { 831 obj = ois.readClassDescriptor(); 832 } catch (IOException e) { 833 //e.printStackTrace(); 834 } finally { 835 ois.close(); 836 } 837 838 //throw exception 839 bais = new ByteArrayInputStream(bytes); 840 bis = new ExceptionalBufferedInputStream(bais); 841 ois = new ObjectIutputStreamWithReadDesc1(bis); 842 843 bis.setException(new IOException()); 844 845 try { 846 obj = ois.readClassDescriptor(); 847 } catch (IOException e) { 848 //e.printStackTrace(); 849 } finally { 850 ois.close(); 851 } 852 853 //corrupt 854 bais = new ByteArrayInputStream(bytes); 855 bis = new ExceptionalBufferedInputStream(bais); 856 ois = new ObjectIutputStreamWithReadDesc1(bis); 857 858 bis.setCorrupt(true); 859 860 try { 861 obj = ois.readClassDescriptor(); 862 } catch (IOException e) { 863 //e.printStackTrace(); 864 } finally { 865 ois.close(); 866 } 867 } 868 869 static class ExceptionalBufferedInputStream extends BufferedInputStream { 870 private boolean eof = false; 871 private IOException exception = null; 872 private boolean corrupt = false; 873 874 public ExceptionalBufferedInputStream(InputStream in) { 875 super(in); 876 } 877 878 @Override 879 public int read() throws IOException { 880 if (exception != null) { 881 throw exception; 882 } 883 884 if (eof) { 885 return -1; 886 } 887 888 if (corrupt) { 889 return 0; 890 } 891 return super.read(); 892 } 893 894 public void setEOF(boolean eof) { 895 this.eof = eof; 896 } 897 898 public void setException(IOException exception) { 899 this.exception = exception; 900 } 901 902 public void setCorrupt(boolean corrupt) { 903 this.corrupt = corrupt; 904 } 905 } 906 907 public static class ObjectIutputStreamWithReadDesc2 extends 908 ObjectInputStream { 909 private Class returnClass; 910 911 public ObjectIutputStreamWithReadDesc2(InputStream is, Class returnClass) 912 throws IOException { 913 super(is); 914 this.returnClass = returnClass; 915 } 916 917 @Override 918 public ObjectStreamClass readClassDescriptor() throws IOException, 919 ClassNotFoundException { 920 ObjectStreamClass osc = super.readClassDescriptor(); 921 922 if (osc.getName().equals(returnClass.getName())) { 923 return ObjectStreamClass.lookup(returnClass); 924 } 925 return osc; 926 } 927 } 928 929 /* 930 * Testing classDescriptor replacement with the value generated by 931 * ObjectStreamClass.lookup() method. 932 * Regression test for HARMONY-4638 933 */ 934 public void test_readClassDescriptor_1() throws IOException, ClassNotFoundException { 935 A a = new A(); 936 a.name = "It's a test"; 937 PipedOutputStream pout = new PipedOutputStream(); 938 PipedInputStream pin = new PipedInputStream(pout); 939 ObjectOutputStream out = new ObjectOutputStream(pout); 940 ObjectInputStream in = new ObjectIutputStreamWithReadDesc2(pin, A.class); 941 942 // test single object 943 out.writeObject(a); 944 A a1 = (A) in.readObject(); 945 assertEquals("Single case: incorrectly read the field of A", a.name, a1.name); 946 947 // test cyclic reference 948 HashMap m = new HashMap(); 949 a = new A(); 950 a.name = "It's a test 0"; 951 a1 = new A(); 952 a1.name = "It's a test 1"; 953 m.put("0", a); 954 m.put("1", a1); 955 out.writeObject(m); 956 HashMap m1 = (HashMap) in.readObject(); 957 assertEquals("Incorrectly read the field of A", a.name, ((A) m1.get("0")).name); 958 assertEquals("Incorrectly read the field of A1", a1.name, ((A) m1.get("1")).name); 959 } 960 961 public void test_registerValidation() throws Exception { 962 // Regression Test for Harmony-2402 963 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 964 new ObjectOutputStream(baos); 965 ObjectInputStream ois = new ObjectInputStream( 966 new ByteArrayInputStream(baos.toByteArray())); 967 968 try { 969 ois.registerValidation(null, 256); 970 fail("NotActiveException should be thrown"); 971 } catch (NotActiveException nae) { 972 // expected 973 } 974 975 // Regression Test for Harmony-3916 976 baos = new ByteArrayOutputStream(); 977 ObjectOutputStream oos = new ObjectOutputStream(baos); 978 oos.writeObject(new RegisterValidationClass()); 979 oos.close(); 980 ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); 981 ObjectInputStream fis = new ObjectInputStream(bais); 982 // should not throw NotActiveException 983 fis.readObject(); 984 } 985 986 private static class RegisterValidationClass implements Serializable { 987 @SuppressWarnings("unused") 988 private A a = new A(); 989 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 990 stream.defaultReadObject(); 991 stream.registerValidation(new MockObjectInputValidation(), 0); 992 } 993 } 994 995 private static class MockObjectInputValidation implements ObjectInputValidation { 996 public void validateObject() throws InvalidObjectException { 997 998 } 999 } 1000 1001 //Regression Test for HARMONY-3726 1002 public void test_readObject_array() throws Exception { 1003 1004 final String resourcePrefix = ObjectInputStreamTest.class.getPackage().getName().replace('.', '/'); 1005 1006// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_strings.ser")); 1007// TestArray ta = new TestArray(new String[] { "AAA", "BBB" }); 1008// oos.writeObject(ta); 1009// oos.close(); 1010// oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_integers.ser")); 1011// ta = new TestArray(new Integer[] { 10, 20 }); 1012// oos.writeObject(ta); 1013// oos.close(); 1014 1015 ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream( 1016 "serialization/" + resourcePrefix + "/test_array_strings.ser")); 1017 TestArray testArray = (TestArray) oin.readObject(); 1018 String[] strings = new String[] { "AAA", "BBB" }; 1019 assertTrue(java.util.Arrays.equals(strings, testArray.array)); 1020 1021 oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream( 1022 "serialization/" + resourcePrefix + "/test_array_integers.ser")); 1023 testArray = (TestArray) oin.readObject(); 1024 Integer[] integers = new Integer[] { 10, 20 }; 1025 assertTrue(java.util.Arrays.equals(integers, testArray.array)); 1026 } 1027 1028 public static class TestExtObject implements Externalizable { 1029 public void writeExternal(ObjectOutput out) throws IOException { 1030 out.writeInt(10); 1031 } 1032 1033 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 1034 in.readInt(); 1035 } 1036 } 1037 1038 static class TestObjectOutputStream extends ObjectOutputStream { 1039 private ObjectStreamClass[] objs; 1040 private int pos = 0; 1041 1042 public TestObjectOutputStream(OutputStream out, ObjectStreamClass[] objs) throws IOException { 1043 super(out); 1044 this.objs = objs; 1045 } 1046 1047 @Override 1048 protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException { 1049 objs[pos++] = osc; } 1050 } 1051 1052 static class TestObjectInputStream extends ObjectInputStream { 1053 private ObjectStreamClass[] objs; 1054 private int pos = 0; 1055 1056 public TestObjectInputStream(InputStream in, ObjectStreamClass[] objs) throws IOException { 1057 super(in); 1058 this.objs = objs; 1059 } 1060 1061 @Override 1062 protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 1063 return objs[pos++]; 1064 } 1065 } 1066 1067 // Regression test for HARMONY-4996 1068 public void test_readObject_replacedClassDescriptor() throws Exception { 1069 ObjectStreamClass[] objs = new ObjectStreamClass[1000]; 1070 PipedOutputStream pout = new PipedOutputStream(); 1071 PipedInputStream pin = new PipedInputStream(pout); 1072 ObjectOutputStream oout = new TestObjectOutputStream(pout, objs); 1073 oout.writeObject(new TestExtObject()); 1074 oout.writeObject("test"); 1075 oout.close(); 1076 ObjectInputStream oin = new TestObjectInputStream(pin, objs); 1077 oin.readObject(); 1078 oin.readObject(); 1079 } 1080 1081 /** 1082 * Sets up the fixture, for example, open a network connection. This method 1083 * is called before a test is executed. 1084 */ 1085 @Override 1086 protected void setUp() throws Exception { 1087 super.setUp(); 1088 oos = new ObjectOutputStream(bao = new ByteArrayOutputStream()); 1089 } 1090} 1091 1092class TestArray implements Serializable 1093{ 1094 private static final long serialVersionUID = 1L; 1095 1096 public Object[] array; 1097 1098 public TestArray(Object[] array) { 1099 this.array = array; 1100 } 1101 1102} 1103 1104class Test implements Serializable { 1105 private static final long serialVersionUID = 1L; 1106 1107 Class classes[] = new Class[] { byte.class, short.class, int.class, 1108 long.class, boolean.class, char.class, float.class, double.class }; 1109 1110 @Override 1111 public boolean equals(Object o) { 1112 if (!(o instanceof Test)) { 1113 return false; 1114 } 1115 return Arrays.equals(classes, ((Test) o).classes); 1116 } 1117} 1118