• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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