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