Commit 646e3290 by Guilhem Lavaux Committed by Michael Koch

2004-02-28 Guilhem Lavaux <guilhem@kaffe.org>

	* java/io/ObjectInputStream.java
	(readClassDescriptor): Keep elements of the mapping non null.
	(checkTypeConsistency): New method.
	(readFields): Fixed main loop and base logic. Small reindentation.
	* java/io/ObjectStreamField.java
	(lookupField): New method to update the field reference.
	(checkFieldType): New method.
	* java/io/ObjectStreamClass.java
	(setClass, setFields): Call lookupField when building the field
	database. Check the real field type.

From-SVN: r78627
parent ca67f278
2004-02-28 Guilhem Lavaux <guilhem@kaffe.org>
* java/io/ObjectInputStream.java
(readClassDescriptor): Keep elements of the mapping non null.
(checkTypeConsistency): New method.
(readFields): Fixed main loop and base logic. Small reindentation.
* java/io/ObjectStreamField.java
(lookupField): New method to update the field reference.
(checkFieldType): New method.
* java/io/ObjectStreamClass.java
(setClass, setFields): Call lookupField when building the field
database. Check the real field type.
2004-02-28 Michael Koch <konqueror@gmx.de>
* java/nio/ByteOrder.java
......
/* ObjectInputStream.java -- Class used to read serialized objects
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
......@@ -413,6 +412,64 @@ public class ObjectInputStream extends InputStream
}
/**
* This method makes a partial check of types for the fields
* contained given in arguments. It checks primitive types of
* fields1 against non primitive types of fields2. This method
* assumes the two lists has already been sorted according to
* the Java specification.
*
* @param name Name of the class owning the given fields.
* @param fields1 First list to check.
* @param fields2 Second list to check.
* @throws InvalidClassException if a field in fields1, which has a primitive type, is a present
* in the non primitive part in fields2.
*/
private void checkTypeConsistency(String name, ObjectStreamField[] fields1, ObjectStreamField[] fields2)
throws InvalidClassException
int nonPrimitive = 0;
for (nonPrimitive = 0;
nonPrimitive < fields1.length
&& fields1[nonPrimitive].isPrimitive(); nonPrimitive++)
{
}
if (nonPrimitive == fields1.length)
return;
int i = 0;
ObjectStreamField f1;
ObjectStreamField f2;
while (i < fields2.length
&& nonPrimitive < fields1.length)
{
f1 = fields1[nonPrimitive];
f2 = fields2[i];
if (!f2.isPrimitive())
break;
int compVal = f1.getName().compareTo (f2.getName());
if (compVal < 0)
{
nonPrimitive++;
}
else if (compVal > 0)
{
i++;
}
else
{
throw new InvalidClassException
("invalid field type for " + f2.getName() +
" in class " + name);
}
}
}
/**
* This method reads a class descriptor from the real input stream
* and use these data to create a new instance of ObjectStreamClass.
* Fields are sorted and ordered for the real read which occurs for
......@@ -497,6 +554,15 @@ public class ObjectInputStream extends InputStream
int real_idx = 0;
int map_idx = 0;
/*
* Check that there is no type inconsistencies between the lists.
* A special checking must be done for the two groups: primitive types and
* not primitive types.
*/
checkTypeConsistency(name, real_fields, stream_fields);
checkTypeConsistency(name, stream_fields, real_fields);
while (stream_idx < stream_fields.length
|| real_idx < real_fields.length)
{
......@@ -528,21 +594,13 @@ public class ObjectInputStream extends InputStream
{
stream_field = stream_fields[stream_idx++];
real_field = real_fields[real_idx++];
if(stream_field.getType() != real_field.getType())
if (stream_field.getType() != real_field.getType())
throw new InvalidClassException
("invalid field type for " + real_field.getName() +
" in class " + name);
}
}
if (stream_field != null)
{
if (stream_field.getOffset() < 0)
stream_field = null;
else if (!stream_field.isToSet())
real_field = null;
}
if (real_field != null && !real_field.isToSet())
real_field = null;
/* If some of stream_fields does not correspond to any of real_fields,
* or the opposite, then fieldmapping will go short.
*/
......@@ -1577,12 +1635,11 @@ public class ObjectInputStream extends InputStream
{
ObjectStreamField stream_field = fields[i];
ObjectStreamField real_field = fields[i + 1];
if(stream_field != null || real_field != null)
{
boolean read_value = stream_field != null;
boolean set_value = real_field != null;
boolean read_value = (stream_field != null && stream_field.getOffset() >= 0 && stream_field.isToSet());
boolean set_value = (real_field != null && real_field.isToSet());
String field_name;
char type;
if (stream_field != null)
{
field_name = stream_field.getName();
......@@ -1690,7 +1747,6 @@ public class ObjectInputStream extends InputStream
}
}
}
}
// Toggles writing primitive data to block-data buffer.
private boolean setBlockDataMode (boolean on)
......
......@@ -327,7 +327,7 @@ public class ObjectStreamClass implements Serializable
i = 0; j = 0; k = 0;
while (i < fields.length && j < exportedFields.length)
{
int comp = fields[i].getName().compareTo(exportedFields[j].getName());
int comp = fields[i].compareTo(exportedFields[j]);
if (comp < 0)
{
......@@ -344,10 +344,27 @@ public class ObjectStreamClass implements Serializable
newFieldList[k] = exportedFields[j];
newFieldList[k].setPersistent(true);
newFieldList[k].setToSet(false);
try
{
newFieldList[k].lookupField(clazz);
newFieldList[k].checkFieldType();
}
catch (NoSuchFieldException _)
{
}
j++;
}
else
{
try
{
exportedFields[j].lookupField(clazz);
exportedFields[j].checkFieldType();
}
catch (NoSuchFieldException _)
{
}
if (!fields[i].getType().equals(exportedFields[j].getType()))
throw new InvalidClassException
("serialPersistentFields must be compatible with" +
......@@ -554,6 +571,19 @@ outer:
if (fields != null)
{
Arrays.sort (fields);
// Retrieve field reference.
for (int i=0; i < fields.length; i++)
{
try
{
fields[i].lookupField(cl);
}
catch (NoSuchFieldException _)
{
fields[i].setToSet(false);
}
}
calculateOffsets();
return;
}
......
......@@ -41,6 +41,8 @@ package java.io;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import gnu.java.lang.reflect.TypeSignature;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* This class intends to describe the field of a class for the serialization
......@@ -99,7 +101,7 @@ public class ObjectStreamField implements Comparable
/**
* There are many cases you can not get java.lang.Class from typename
* if your context class loader cann not load it, then use typename to
* if your context class loader cannot load it, then use typename to
* construct the field.
*
* @param name Name of the field to export.
......@@ -292,7 +294,7 @@ public class ObjectStreamField implements Comparable
}
/**
* This methods returns true if the field is marked as to be
* This method returns true if the field is marked as to be
* set.
*
* @return True if it is to be set, false in the other cases.
......@@ -303,6 +305,49 @@ public class ObjectStreamField implements Comparable
return toset;
}
/**
* This method searches for its field reference in the specified class
* object. It requests privileges. If an error occurs the internal field
* reference is not modified.
*
* @throws NoSuchFieldException if the field name does not exist in this class.
* @throws SecurityException if there was an error requesting the privileges.
*/
void lookupField(Class clazz) throws NoSuchFieldException, SecurityException
{
final Field f = clazz.getDeclaredField(name);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
f.setAccessible(true);
return null;
}
});
this.field = f;
}
/**
* This method check whether the field described by this
* instance of ObjectStreamField is compatible with the
* actual implementation of this field.
*
* @throws NullPointerException if this field does not exist
* in the real class.
* @throws InvalidClassException if the types are incompatible.
*/
void checkFieldType() throws InvalidClassException
{
Class ftype = field.getType();
if (!ftype.isAssignableFrom(type))
throw new InvalidClassException
("invalid field type for " + name +
" in class " + field.getDeclaringClass());
}
public String toString ()
{
return "ObjectStreamField< " + type + " " + name + " >";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment