blob: 7120dd6d93202c3dd0bd0a7a9f8af8e516359771 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.luni.tests.java.io;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.NotActiveException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectInputValidation;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Serializable;
import java.io.SerializablePermission;
import java.io.StreamCorruptedException;
import java.lang.reflect.Proxy;
import java.security.Permission;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Vector;
import junit.framework.TestCase;
import org.apache.harmony.testframework.serialization.SerializationTest;
import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert;
@SuppressWarnings("serial")
public class ObjectInputStreamTest extends TestCase implements
Serializable {
ObjectInputStream ois;
ObjectOutputStream oos;
ByteArrayOutputStream bao;
public class SerializableTestHelper implements Serializable {
public String aField1;
public String aField2;
SerializableTestHelper() {
aField1 = null;
aField2 = null;
}
SerializableTestHelper(String s, String t) {
aField1 = s;
aField2 = t;
}
private void readObject(ObjectInputStream ois) throws Exception {
// note aField2 is not read
ObjectInputStream.GetField fields = ois.readFields();
aField1 = (String) fields.get("aField1", "Zap");
}
private void writeObject(ObjectOutputStream oos) throws IOException {
// note aField2 is not written
ObjectOutputStream.PutField fields = oos.putFields();
fields.put("aField1", aField1);
oos.writeFields();
}
public String getText1() {
return aField1;
}
public void setText1(String s) {
aField1 = s;
}
public String getText2() {
return aField2;
}
public void setText2(String s) {
aField2 = s;
}
}
public static class A1 implements Serializable {
private static final long serialVersionUID = 5942584913446079661L;
B1 b1 = new B1();
B1 b2 = b1;
Vector v = new Vector();
}
public static class B1 implements Serializable {
int i = 5;
Hashtable h = new Hashtable();
}
/**
* @tests java.io.ObjectInputStream#readObject()
*/
public void test_readObjectMissingClasses() throws Exception {
SerializationTest.verifySelf(new A1(), new SerializableAssert() {
public void assertDeserialized(Serializable initial,
Serializable deserialized) {
assertEquals(5, ((A1) deserialized).b1.i);
}
});
}
/**
* @tests java.io.ObjectInputStream#ObjectInputStream(java.io.InputStream)
*/
public void test_ConstructorLjava_io_InputStream() throws IOException {
oos.writeDouble(Double.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.close();
oos.close();
try {
ois = new ObjectInputStream(new ByteArrayInputStream(new byte[90]));
fail("StreamCorruptedException expected");
} catch (StreamCorruptedException e) {
// Expected
}
}
/**
* @tests {@link java.io.ObjectInputStream#resolveProxyClass(String[])}
*/
public void test_resolveProxyClass() throws IOException,
ClassNotFoundException {
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
MockObjectInputStream mockIn = new MockObjectInputStream(
new ByteArrayInputStream(bao.toByteArray()));
Class[] clazzs = { java.io.ObjectInputStream.class,
java.io.Reader.class };
for (int i = 0; i < clazzs.length; i++) {
Class clazz = clazzs[i];
Class[] interfaceNames = clazz.getInterfaces();
String[] interfaces = new String[interfaceNames.length];
int index = 0;
for (Class c : interfaceNames) {
interfaces[index] = c.getName();
index++;
}
Class<?> s = mockIn.resolveProxyClass(interfaces);
if (Proxy.isProxyClass(s)) {
Class[] implementedInterfaces = s.getInterfaces();
for (index = 0; index < implementedInterfaces.length; index++) {
assertEquals(interfaceNames[index],
implementedInterfaces[index]);
}
} else {
fail("Should return a proxy class that implements the interfaces named in a proxy class descriptor");
}
}
mockIn.close();
}
class MockObjectInputStream extends ObjectInputStream {
public MockObjectInputStream(InputStream input)
throws StreamCorruptedException, IOException {
super(input);
}
@Override
public Class<?> resolveProxyClass(String[] interfaceNames) throws IOException, ClassNotFoundException {
return super.resolveProxyClass(interfaceNames);
}
}
/**
* @tests java.io.ObjectInputStream#available()
*/
public void test_available() throws IOException {
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect bytes", 10, ois.available());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#close()
*/
public void test_close() throws IOException {
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.close();
}
/**
* @tests java.io.ObjectInputStream#defaultReadObject()
*/
public void test_defaultReadObject() throws Exception {
// SM. This method may as well be private, as if called directly it
// throws an exception.
String s = "HelloWorld";
oos.writeObject(s);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
try {
ois.defaultReadObject();
fail("NotActiveException expected");
} catch (NotActiveException e) {
// Desired behavior
} finally {
ois.close();
}
}
/**
* @tests java.io.ObjectInputStream#read()
*/
public void test_read() throws IOException {
oos.write('T');
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect byte value", 'T', ois.read());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#read(byte[], int, int)
*/
public void test_read$BII() throws IOException {
byte[] buf = new byte[10];
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.read(buf, 0, 10);
ois.close();
assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
10, "UTF-8"));
}
/**
* @tests java.io.ObjectInputStream#readBoolean()
*/
public void test_readBoolean() throws IOException {
oos.writeBoolean(true);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect boolean value", ois.readBoolean());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readByte()
*/
public void test_readByte() throws IOException {
oos.writeByte(127);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect byte value", 127, ois.readByte());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readChar()
*/
public void test_readChar() throws IOException {
oos.writeChar('T');
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect char value", 'T', ois.readChar());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readDouble()
*/
public void test_readDouble() throws IOException {
oos.writeDouble(Double.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect double value",
ois.readDouble() == Double.MAX_VALUE);
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readFields()
*/
public void test_readFields() throws Exception {
SerializableTestHelper sth;
/*
* "SerializableTestHelper" is an object created for these tests with
* two fields (Strings) and simple implementations of readObject and
* writeObject which simply read and write the first field but not the
* second
*/
oos.writeObject(new SerializableTestHelper("Gabba", "Jabba"));
oos.flush();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
sth = (SerializableTestHelper) (ois.readObject());
assertEquals("readFields / writeFields failed--first field not set",
"Gabba", sth.getText1());
assertNull(
"readFields / writeFields failed--second field should not have been set",
sth.getText2());
}
/**
* @tests java.io.ObjectInputStream#readFloat()
*/
public void test_readFloat() throws IOException {
oos.writeFloat(Float.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect float value",
ois.readFloat() == Float.MAX_VALUE);
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readFully(byte[])
*/
public void test_readFully$B() throws IOException {
byte[] buf = new byte[10];
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.readFully(buf);
ois.close();
assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
10, "UTF-8"));
}
/**
* @tests java.io.ObjectInputStream#readFully(byte[], int, int)
*/
public void test_readFully$BII() throws IOException {
byte[] buf = new byte[10];
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.readFully(buf, 0, 10);
ois.close();
assertEquals("Read incorrect bytes", "HelloWorld", new String(buf, 0,
10, "UTF-8"));
}
/**
* @tests java.io.ObjectInputStream#readInt()
*/
public void test_readInt() throws IOException {
oos.writeInt(Integer.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect int value",
ois.readInt() == Integer.MAX_VALUE);
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readLine()
*/
@SuppressWarnings("deprecation")
public void test_readLine() throws IOException {
oos.writeBytes("HelloWorld\nSecondLine");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.readLine();
assertEquals("Read incorrect string value", "SecondLine", ois
.readLine());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readLong()
*/
public void test_readLong() throws IOException {
oos.writeLong(Long.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect long value",
ois.readLong() == Long.MAX_VALUE);
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readObject()
*/
public void test_readObject() throws Exception {
String s = "HelloWorld";
oos.writeObject(s);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect Object value", s, ois.readObject());
ois.close();
// Regression for HARMONY-91
// dynamically create serialization byte array for the next hierarchy:
// - class A implements Serializable
// - class C extends A
byte[] cName = C.class.getName().getBytes("UTF-8");
byte[] aName = A.class.getName().getBytes("UTF-8");
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] begStream = new byte[] { (byte) 0xac, (byte) 0xed, // STREAM_MAGIC
(byte) 0x00, (byte) 0x05, // STREAM_VERSION
(byte) 0x73, // TC_OBJECT
(byte) 0x72, // TC_CLASSDESC
(byte) 0x00, // only first byte for C class name length
};
out.write(begStream, 0, begStream.length);
out.write(cName.length); // second byte for C class name length
out.write(cName, 0, cName.length); // C class name
byte[] midStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x21, // serialVersionUID = 33L
(byte) 0x02, // flags
(byte) 0x00, (byte) 0x00, // fields : none
(byte) 0x78, // TC_ENDBLOCKDATA
(byte) 0x72, // Super class for C: TC_CLASSDESC for A class
(byte) 0x00, // only first byte for A class name length
};
out.write(midStream, 0, midStream.length);
out.write(aName.length); // second byte for A class name length
out.write(aName, 0, aName.length); // A class name
byte[] endStream = new byte[] { (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x0b, // serialVersionUID = 11L
(byte) 0x02, // flags
(byte) 0x00, (byte) 0x01, // fields
(byte) 0x4c, // field description: type L (object)
(byte) 0x00, (byte) 0x04, // length
// field = 'name'
(byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65,
(byte) 0x74, // className1: TC_STRING
(byte) 0x00, (byte) 0x12, // length
//
(byte) 0x4c, (byte) 0x6a, (byte) 0x61, (byte) 0x76,
(byte) 0x61, (byte) 0x2f, (byte) 0x6c, (byte) 0x61,
(byte) 0x6e, (byte) 0x67, (byte) 0x2f, (byte) 0x53,
(byte) 0x74, (byte) 0x72, (byte) 0x69, (byte) 0x6e,
(byte) 0x67, (byte) 0x3b,
(byte) 0x78, // TC_ENDBLOCKDATA
(byte) 0x70, // NULL super class for A class
// classdata
(byte) 0x74, // TC_STRING
(byte) 0x00, (byte) 0x04, // length
(byte) 0x6e, (byte) 0x61, (byte) 0x6d, (byte) 0x65, // value
};
out.write(endStream, 0, endStream.length);
out.flush();
// read created serial. form
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
out.toByteArray()));
Object o = ois.readObject();
assertEquals(C.class, o.getClass());
// Regression for HARMONY-846
assertNull(new ObjectInputStream() {}.readObject());
}
/**
* @tests java.io.ObjectInputStream#readObjectOverride()
*/
public void test_readObjectOverride() throws Exception {
// Regression for HARMONY-846
assertNull(new ObjectInputStream() {
@Override
public Object readObjectOverride() throws IOException,
ClassNotFoundException {
return super.readObjectOverride();
}
}.readObjectOverride());
}
public static class A implements Serializable {
private static final long serialVersionUID = 11L;
public String name = "name";
}
public static class B extends A {}
public static class C extends B {
private static final long serialVersionUID = 33L;
}
/**
* @tests java.io.ObjectInputStream#readObject()
*/
public void test_readObjectCorrupt() throws IOException, ClassNotFoundException {
byte[] bytes = { 00, 00, 00, 0x64, 0x43, 0x48, (byte) 0xFD, 0x71, 00,
00, 0x0B, (byte) 0xB8, 0x4D, 0x65 };
ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
try {
ObjectInputStream in = new ObjectInputStream(bin);
in.readObject();
fail("Unexpected read of corrupted stream");
} catch (StreamCorruptedException e) {
// Expected
}
}
/**
* @tests java.io.ObjectInputStream#readShort()
*/
public void test_readShort() throws IOException {
oos.writeShort(Short.MAX_VALUE);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertTrue("Read incorrect short value",
ois.readShort() == Short.MAX_VALUE);
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readUnsignedByte()
*/
public void test_readUnsignedByte() throws IOException {
oos.writeByte(-1);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect unsignedByte value", 255, ois
.readUnsignedByte());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readUnsignedShort()
*/
public void test_readUnsignedShort() throws IOException {
oos.writeShort(-1);
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect unsignedShort value", 65535, ois
.readUnsignedShort());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#readUTF()
*/
public void test_readUTF() throws IOException {
oos.writeUTF("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
assertEquals("Read incorrect utf value", "HelloWorld", ois.readUTF());
ois.close();
}
/**
* @tests java.io.ObjectInputStream#skipBytes(int)
*/
public void test_skipBytesI() throws IOException {
byte[] buf = new byte[10];
oos.writeBytes("HelloWorld");
oos.close();
ois = new ObjectInputStream(new ByteArrayInputStream(bao.toByteArray()));
ois.skipBytes(5);
ois.read(buf, 0, 5);
ois.close();
assertEquals("Skipped incorrect bytes", "World", new String(buf, 0, 5, "UTF-8"));
// Regression for HARMONY-844
try {
new ObjectInputStream() {}.skipBytes(0);
fail("NullPointerException expected");
} catch (NullPointerException e) {}
}
// Regression Test for JIRA 2192
public void test_readObject_withPrimitiveClass() throws Exception {
File file = new File("test.ser");
file.deleteOnExit();
Test test = new Test();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
file));
out.writeObject(test);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream(file));
Test another = (Test) in.readObject();
in.close();
assertEquals(test, another);
}
//Regression Test for JIRA-2249
public static class ObjectOutputStreamWithWriteDesc extends
ObjectOutputStream {
public ObjectOutputStreamWithWriteDesc(OutputStream os)
throws IOException {
super(os);
}
@Override
public void writeClassDescriptor(ObjectStreamClass desc)
throws IOException {
}
}
public static class ObjectIutputStreamWithReadDesc extends
ObjectInputStream {
private Class returnClass;
public ObjectIutputStreamWithReadDesc(InputStream is, Class returnClass)
throws IOException {
super(is);
this.returnClass = returnClass;
}
@Override
public ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
return ObjectStreamClass.lookup(returnClass);
}
}
static class TestClassForSerialization implements Serializable {
private static final long serialVersionUID = 1L;
}
public void test_ClassDescriptor() throws IOException,
ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStreamWithWriteDesc oos = new ObjectOutputStreamWithWriteDesc(
baos);
oos.writeObject(String.class);
oos.close();
Class cls = TestClassForSerialization.class;
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectIutputStreamWithReadDesc ois = new ObjectIutputStreamWithReadDesc(
bais, cls);
Object obj = ois.readObject();
ois.close();
assertEquals(cls, obj);
}
// Regression Test for JIRA-2340
public static class ObjectOutputStreamWithWriteDesc1 extends
ObjectOutputStream {
public ObjectOutputStreamWithWriteDesc1(OutputStream os)
throws IOException {
super(os);
}
@Override
public void writeClassDescriptor(ObjectStreamClass desc)
throws IOException {
super.writeClassDescriptor(desc);
}
}
public static class ObjectIutputStreamWithReadDesc1 extends
ObjectInputStream {
public ObjectIutputStreamWithReadDesc1(InputStream is)
throws IOException {
super(is);
}
@Override
public ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
return super.readClassDescriptor();
}
}
// Regression test for Harmony-1921
public static class ObjectInputStreamWithResolve extends ObjectInputStream {
public ObjectInputStreamWithResolve(InputStream in) throws IOException {
super(in);
}
@Override
@SuppressWarnings("unchecked")
protected Class resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
if (desc.getName().equals(
"org.apache.harmony.luni.tests.pkg1.TestClass")) {
return org.apache.harmony.luni.tests.pkg2.TestClass.class;
}
return super.resolveClass(desc);
}
}
public void test_resolveClass() throws Exception {
org.apache.harmony.luni.tests.pkg1.TestClass to1 = new org.apache.harmony.luni.tests.pkg1.TestClass();
to1.i = 555;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(to1);
oos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStreamWithResolve(bais);
org.apache.harmony.luni.tests.pkg2.TestClass to2 = (org.apache.harmony.luni.tests.pkg2.TestClass) ois
.readObject();
if (to2.i != to1.i) {
fail("Wrong object read. Expected val: " + to1.i + ", got: "
+ to2.i);
}
}
static class ObjectInputStreamWithResolveObject extends ObjectInputStream {
public static Integer intObj = Integer.valueOf(1000);
public ObjectInputStreamWithResolveObject(InputStream in) throws IOException {
super(in);
enableResolveObject(true);
}
@Override
protected Object resolveObject(Object obj) throws IOException {
if(obj instanceof Integer){
obj = intObj;
}
return super.resolveObject(obj);
}
}
/**
* @tests java.io.ObjectInputStream#resolveObject(Object)
*/
public void test_resolveObjectLjava_lang_Object() throws Exception {
// Write an Integer object into memory
Integer original = new Integer(10);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(original);
oos.flush();
oos.close();
// Read the object from memory
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStreamWithResolveObject ois =
new ObjectInputStreamWithResolveObject(bais);
Integer actual = (Integer) ois.readObject();
ois.close();
// object should be resolved from 10 to 1000
assertEquals(ObjectInputStreamWithResolveObject.intObj, actual);
}
public void test_readClassDescriptor() throws IOException,
ClassNotFoundException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStreamWithWriteDesc1 oos = new ObjectOutputStreamWithWriteDesc1(
baos);
ObjectStreamClass desc = ObjectStreamClass
.lookup(TestClassForSerialization.class);
oos.writeClassDescriptor(desc);
oos.close();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectIutputStreamWithReadDesc1 ois = new ObjectIutputStreamWithReadDesc1(
bais);
Object obj = ois.readClassDescriptor();
ois.close();
assertEquals(desc.getClass(), obj.getClass());
//eof
bais = new ByteArrayInputStream(bytes);
ExceptionalBufferedInputStream bis = new ExceptionalBufferedInputStream(
bais);
ois = new ObjectIutputStreamWithReadDesc1(bis);
bis.setEOF(true);
try {
obj = ois.readClassDescriptor();
} catch (IOException e) {
//e.printStackTrace();
} finally {
ois.close();
}
//throw exception
bais = new ByteArrayInputStream(bytes);
bis = new ExceptionalBufferedInputStream(bais);
ois = new ObjectIutputStreamWithReadDesc1(bis);
bis.setException(new IOException());
try {
obj = ois.readClassDescriptor();
} catch (IOException e) {
//e.printStackTrace();
} finally {
ois.close();
}
//corrupt
bais = new ByteArrayInputStream(bytes);
bis = new ExceptionalBufferedInputStream(bais);
ois = new ObjectIutputStreamWithReadDesc1(bis);
bis.setCorrupt(true);
try {
obj = ois.readClassDescriptor();
} catch (IOException e) {
//e.printStackTrace();
} finally {
ois.close();
}
}
static class ExceptionalBufferedInputStream extends BufferedInputStream {
private boolean eof = false;
private IOException exception = null;
private boolean corrupt = false;
public ExceptionalBufferedInputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
if (exception != null) {
throw exception;
}
if (eof) {
return -1;
}
if (corrupt) {
return 0;
}
return super.read();
}
public void setEOF(boolean eof) {
this.eof = eof;
}
public void setException(IOException exception) {
this.exception = exception;
}
public void setCorrupt(boolean corrupt) {
this.corrupt = corrupt;
}
}
public static class ObjectIutputStreamWithReadDesc2 extends
ObjectInputStream {
private Class returnClass;
public ObjectIutputStreamWithReadDesc2(InputStream is, Class returnClass)
throws IOException {
super(is);
this.returnClass = returnClass;
}
@Override
public ObjectStreamClass readClassDescriptor() throws IOException,
ClassNotFoundException {
ObjectStreamClass osc = super.readClassDescriptor();
if (osc.getName().equals(returnClass.getName())) {
return ObjectStreamClass.lookup(returnClass);
}
return osc;
}
}
/*
* Testing classDescriptor replacement with the value generated by
* ObjectStreamClass.lookup() method.
* Regression test for HARMONY-4638
*/
public void test_readClassDescriptor_1() throws IOException, ClassNotFoundException {
A a = new A();
a.name = "It's a test";
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
ObjectOutputStream out = new ObjectOutputStream(pout);
ObjectInputStream in = new ObjectIutputStreamWithReadDesc2(pin, A.class);
// test single object
out.writeObject(a);
A a1 = (A) in.readObject();
assertEquals("Single case: incorrectly read the field of A", a.name, a1.name);
// test cyclic reference
HashMap m = new HashMap();
a = new A();
a.name = "It's a test 0";
a1 = new A();
a1.name = "It's a test 1";
m.put("0", a);
m.put("1", a1);
out.writeObject(m);
HashMap m1 = (HashMap) in.readObject();
assertEquals("Incorrectly read the field of A", a.name, ((A) m1.get("0")).name);
assertEquals("Incorrectly read the field of A1", a1.name, ((A) m1.get("1")).name);
}
public void test_registerValidation() throws Exception {
// Regression Test for Harmony-2402
ByteArrayOutputStream baos = new ByteArrayOutputStream();
new ObjectOutputStream(baos);
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream(baos.toByteArray()));
try {
ois.registerValidation(null, 256);
fail("NotActiveException should be thrown");
} catch (NotActiveException nae) {
// expected
}
// Regression Test for Harmony-3916
baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(new RegisterValidationClass());
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream fis = new ObjectInputStream(bais);
// should not throw NotActiveException
fis.readObject();
}
private static class RegisterValidationClass implements Serializable {
@SuppressWarnings("unused")
private A a = new A();
private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
stream.defaultReadObject();
stream.registerValidation(new MockObjectInputValidation(), 0);
}
}
private static class MockObjectInputValidation implements ObjectInputValidation {
public void validateObject() throws InvalidObjectException {
}
}
//Regression Test for HARMONY-3726
public void test_readObject_array() throws Exception {
final String resourcePrefix = ObjectInputStreamTest.class.getPackage().getName().replace('.', '/');
// ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_strings.ser"));
// TestArray ta = new TestArray(new String[] { "AAA", "BBB" });
// oos.writeObject(ta);
// oos.close();
// oos = new ObjectOutputStream(new FileOutputStream("/temp/test_array_integers.ser"));
// ta = new TestArray(new Integer[] { 10, 20 });
// oos.writeObject(ta);
// oos.close();
ObjectInputStream oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
"serialization/" + resourcePrefix + "/test_array_strings.ser"));
TestArray testArray = (TestArray) oin.readObject();
String[] strings = new String[] { "AAA", "BBB" };
assertTrue(java.util.Arrays.equals(strings, testArray.array));
oin = new ObjectInputStream(this.getClass().getClassLoader().getResourceAsStream(
"serialization/" + resourcePrefix + "/test_array_integers.ser"));
testArray = (TestArray) oin.readObject();
Integer[] integers = new Integer[] { 10, 20 };
assertTrue(java.util.Arrays.equals(integers, testArray.array));
}
public static class TestExtObject implements Externalizable {
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(10);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
in.readInt();
}
}
static class TestObjectOutputStream extends ObjectOutputStream {
private ObjectStreamClass[] objs;
private int pos = 0;
public TestObjectOutputStream(OutputStream out, ObjectStreamClass[] objs) throws IOException {
super(out);
this.objs = objs;
}
@Override
protected void writeClassDescriptor(ObjectStreamClass osc) throws IOException {
objs[pos++] = osc; }
}
static class TestObjectInputStream extends ObjectInputStream {
private ObjectStreamClass[] objs;
private int pos = 0;
public TestObjectInputStream(InputStream in, ObjectStreamClass[] objs) throws IOException {
super(in);
this.objs = objs;
}
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
return objs[pos++];
}
}
// Regression test for HARMONY-4996
public void test_readObject_replacedClassDescriptor() throws Exception {
ObjectStreamClass[] objs = new ObjectStreamClass[1000];
PipedOutputStream pout = new PipedOutputStream();
PipedInputStream pin = new PipedInputStream(pout);
ObjectOutputStream oout = new TestObjectOutputStream(pout, objs);
oout.writeObject(new TestExtObject());
oout.writeObject("test");
oout.close();
ObjectInputStream oin = new TestObjectInputStream(pin, objs);
oin.readObject();
oin.readObject();
}
/**
* Sets up the fixture, for example, open a network connection. This method
* is called before a test is executed.
*/
@Override
protected void setUp() throws Exception {
super.setUp();
oos = new ObjectOutputStream(bao = new ByteArrayOutputStream());
}
}
class TestArray implements Serializable
{
private static final long serialVersionUID = 1L;
public Object[] array;
public TestArray(Object[] array) {
this.array = array;
}
}
class Test implements Serializable {
private static final long serialVersionUID = 1L;
Class classes[] = new Class[] { byte.class, short.class, int.class,
long.class, boolean.class, char.class, float.class, double.class };
@Override
public boolean equals(Object o) {
if (!(o instanceof Test)) {
return false;
}
return Arrays.equals(classes, ((Test) o).classes);
}
}