classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Serialization #5


From: Guilhem Lavaux
Subject: [PATCH] Serialization #5
Date: Tue, 02 Dec 2003 22:01:52 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030630

Hi,

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 <address@hidden>

        * 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;
   }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]