This is the patch #5 (the last will be the #6) about serialization. It fixes the following problems: * getField handles transient and non persistent field, * readClassDescriptor uses the right class loader to decode fields, it also verifies that the available fields (and required by the input stream) are of the required types. * if getOffset() < 0 then readFields() should not try to read any field from the input stream.
Cheers, Guilhem.
ChangeLog entry:
2003-12-02 Guilhem Lavaux <[EMAIL PROTECTED]>
* java/io/ObjectInputStream.java:
(getField): Handle transient and non persistent fields.
(readClassDescriptor): Better error handling, use the right class loader.
(readFields): Fields marked as not present in the stream or not to be set are
not read and set.Index: java/io/ObjectInputStream.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v
retrieving revision 1.33
diff -u -r1.33 ObjectInputStream.java
--- java/io/ObjectInputStream.java 2 Dec 2003 18:35:51 -0000 1.33
+++ java/io/ObjectInputStream.java 2 Dec 2003 20:46:54 -0000
@@ -434,6 +434,7 @@
flags, fields);
assignNewHandle (osc);
+ int real_count;
for (int i=0; i < field_count; i++)
{
dumpElement (" TYPE CODE=");
@@ -442,18 +443,46 @@
String field_name = this.realInputStream.readUTF ();
dumpElementln (field_name);
String class_name;
-
+
+ // There're many cases you can't get java.lang.Class from
+ // typename if your context class loader can't load it,
+ // then use typename to construct the field
+ // GL => No. You lose the capability to access the class loader.
+ // Type resolution must be done here. If it is an object we
+ // create the class just here if it is something else we delegate
+ // to TypeSignature.
if (type_code == 'L' || type_code == '[')
class_name = (String)readObject ();
else
class_name = String.valueOf (type_code);
-
- // There're many cases you can't get java.lang.Class from
- // typename if your context class loader can't load it,
- // then use typename to construct the field
+
fields[i] =
- new ObjectStreamField (field_name, class_name);
+ new ObjectStreamField (field_name, class_name, currentLoader());
+ }
+
+
+ /* Now that fields have been read we may resolve the class
+ * (and read annotation if needed). */
+ Class clazz = resolveClass(osc);
+
+ for (int i=0; i < field_count; i++)
+ {
+ Field f;
+
+ try
+ {
+ f = clazz.getDeclaredField (fields[i].getName());
+ if (f != null && !f.getType().equals(fields[i].getType()))
+ throw new InvalidClassException("invalid field type for " +
+ fields[i].getName() + " in class " +
name +
+ " (requested was \"" +
fields[i].getType() +
+ " and found \"" + f.getType() + "\")");
+ }
+ catch (NoSuchFieldException _)
+ {
+ }
}
+
Class clazz = resolveClass (osc);
boolean oldmode = setBlockDataMode (true);
@@ -1424,6 +1453,15 @@
}
}
+ if (stream_field.getOffset() < 0)
+ {
+ default_initialize = true;
+ set_value = false;
+ }
+
+ if (!stream_field.isToSet())
+ set_value = false;
+
try
{
if (type == Boolean.TYPE)
@@ -1571,10 +1609,23 @@
*/
private static native ClassLoader currentClassLoader (SecurityManager sm);
- private static Field getField (Class klass, String name)
+ /**
+ * This method tries to access a precise field called in the
+ * specified class. Before accessing the field, it tries to
+ * gain control on this field. If the field is either declared as
+ * not persistent or transient then it returns null
+ * immediately.
+ *
+ * @param klass Class to get the field from.
+ * @param name Name of the field to access.
+ * @return Field instance representing the requested field.
+ * @throws NoSuchFieldException if the field does not exist.
+ */
+ private Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException
{
final Field f = klass.getDeclaredField(name);
+ ObjectStreamField sf = lookupClass (klass).getField(name);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -1584,6 +1635,14 @@
return null;
}
});
+
+ /* We do not want to modify transient fields. They should
+ * be left to 0.
+ * N.B.: Not valid if the field is in serialPersistentFields.
+ */
+ if (Modifier.isTransient(f.getModifiers()) && !sf.isPersistent())
+ return null;
+
return f;
}
_______________________________________________ Classpath mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/classpath

