This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: libgcj/2237: serialization doesn't throw exception on failure


The following reply was made to PR libgcj/2237; it has been noted by GNATS.

From: Bryce McKinlay <bryce@albatross.co.nz>
To: tromey@redhat.com
Cc: gcc-gnats@gcc.gnu.org, java-patches@gcc.gnu.org
Subject: Re: libgcj/2237: serialization doesn't throw exception on failure
Date: Mon, 12 Mar 2001 00:20:50 +1300

 This is a multi-part message in MIME format.
 --------------9BABD103EE536B49E5E2AEF4
 Content-Type: text/plain; charset=us-ascii
 Content-Transfer-Encoding: 7bit
 
 tromey@redhat.com wrote:
 
 > >Description:
 > When reading a serialized stream we should
 > throw InvalidClassException if we don't recognize
 > the data.  As far as I can tell we never do this.
 > As an example see PR 1971.
 > (If you want to use that test case you'll have
 > to back out the fix first.)
 
 This patch fixes it. It's dependent on some forthcoming fixes for
 forName() etc...
 
 regards
 
   [ bryce ]
 
 
 --------------9BABD103EE536B49E5E2AEF4
 Content-Type: text/plain; charset=us-ascii;
  name="objectstream.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: inline;
  filename="objectstream.patch"
 
 2001-03-11  Bryce McKinlay  <bryce@albatross.co.nz>
 
 	Fix PR libgcj/2237:
 	* java/io/ObjectStreamClass.java (setClass): Calculate 
 	serialVersionUID for local class and compare it against the UID
 	from the Object Stream. Throw InvalidClassException upon mismatch.
 	(setUID): Renamed to...
 	(getClassUID): this. Return the calculated class UID rather than 
 	setting uid field directly.
 	(getDefinedSUID): Removed.
 	* java/io/ObjectInputStream.java (resolveClass): Use the 
 	three-argument Class.forName(). 
 
 Index: java/io/ObjectInputStream.java
 ===================================================================
 RCS file: /cvs/gcc/egcs/libjava/java/io/ObjectInputStream.java,v
 retrieving revision 1.6.4.1
 diff -u -r1.6.4.1 ObjectInputStream.java
 --- ObjectInputStream.java	2001/02/17 01:06:44	1.6.4.1
 +++ ObjectInputStream.java	2001/03/11 11:12:24
 @@ -199,8 +199,8 @@
  				   (class_name));
  	}
  
 -	setBlockDataMode (true);
 -	osc.setClass (resolveClass (osc));
 +	Class cl = resolveClass (osc);
 +	osc.setClass (cl);
  	setBlockDataMode (false);
  
  	if (this.realInputStream.readByte () != TC_ENDBLOCKDATA)
 @@ -487,27 +487,15 @@
    protected Class resolveClass (ObjectStreamClass osc)
      throws ClassNotFoundException, IOException
    {
 -//    DEBUGln ("Resolving " + osc);
 -
      SecurityManager sm = System.getSecurityManager ();
 -
 -    if (sm == null)
 -      sm = new SecurityManager () {};
  
 +    // FIXME: currentClassLoader doesn't yet do anything useful. We need
 +    // to call forName() with the classloader of the class which called 
 +    // readObject(). See SecurityManager.getClassContext().
      ClassLoader cl = currentClassLoader (sm);
  
 -    if (cl == null)
 -    {
 -//      DEBUGln ("No class loader found");
 -      return Class.forName (osc.getName ());
 -    }
 -    else
 -    {
 -//      DEBUGln ("Using " + cl);
 -      return cl.loadClass (osc.getName ());
 -    }
 +    return Class.forName (osc.getName (), true, cl);
    }
 -
  
    /**
       Allows subclasses to resolve objects that are read from the
 Index: java/io/ObjectStreamClass.java
 ===================================================================
 RCS file: /cvs/gcc/egcs/libjava/java/io/ObjectStreamClass.java,v
 retrieving revision 1.6.4.1
 diff -u -r1.6.4.1 ObjectStreamClass.java
 --- ObjectStreamClass.java	2001/03/09 01:34:40	1.6.4.1
 +++ ObjectStreamClass.java	2001/03/11 11:12:24
 @@ -246,13 +246,27 @@
      this.fields = fields;
    }
  
 -
 -  void setClass (Class clazz)
 +  void setClass (Class cl) throws InvalidClassException
    {
 -    this.clazz = clazz;
 +    this.clazz = cl;
 +    long class_uid = getClassUID (cl);
 +    if (uid == 0)
 +      {
 +       uid = class_uid;
 +       return;
 +      }
 +    
 +    // Check that the actual UID of the resolved class matches the UID from 
 +    // the stream.    
 +    if (uid != class_uid)
 +      {
 +       String msg = cl + 
 +	 ": Local class not compatible: stream serialVersionUID="
 +	 + uid + ", local serialVersionUID=" + class_uid;
 +       throw new InvalidClassException (msg);
 +      }
    }
  
 -
    void setSuperclass (ObjectStreamClass osc)
    {
      superClass = osc;
 @@ -308,7 +322,7 @@
      name = cl.getName ();
      setFlags (cl);
      setFields (cl);
 -    setUID (cl);
 +    uid = getClassUID (cl);
      superClass = lookup (cl.getSuperclass ());
    }
  
 @@ -396,24 +410,24 @@
      calculateOffsets ();
    }
  
 -  // Sets uid to be serial version UID defined by class, or if that
 +  // Returns the serial version UID defined by class, or if that
    // isn't present, calculates value of serial version UID.
 -  private void setUID (Class cl)
 +  private long getClassUID (Class cl)
    {
      try
      {
        Field suid = cl.getDeclaredField ("serialVersionUID");
        int modifiers = suid.getModifiers ();
  
 -      if (Modifier.isStatic (modifiers)
 -	  && Modifier.isFinal (modifiers))
 -      {
 -	uid = getDefinedSUID (cl);
 -	return;
 -      }
 +      if (Modifier.isStatic (modifiers) && Modifier.isFinal (modifiers))
 +	return suid.getLong (null);	  
      }
      catch (NoSuchFieldException ignore)
 -    {}
 +    {
 +    }
 +    catch (IllegalAccessException ignore)
 +    {
 +    }
  
      // cl didn't define serialVersionUID, so we have to compute it
      try
 @@ -534,7 +548,7 @@
        for (int i=0; i < len; i++)
  	result += (long)(sha[i] & 0xFF) << (8 * i);
  
 -      uid = result;
 +      return result;
      }
      catch (NoSuchAlgorithmException e)
      {
 @@ -545,31 +559,6 @@
      {
        throw new RuntimeException (ioe.getMessage ());
      }
 -  }
 -
 -
 -  // Returns the value of CLAZZ's final static long field named
 -  // `serialVersionUID'.
 -  private long getDefinedSUID (Class clazz)
 -  {
 -    long l = 0;
 -    try
 -      {
 -	// Use getDeclaredField rather than getField, since serialVersionUID
 -	// may not be public AND we only want the serialVersionUID of this
 -	// class, not a superclass or interface.
 -	Field f = clazz.getDeclaredField ("serialVersionUID");
 -	l = f.getLong (null);
 -      }
 -    catch (java.lang.NoSuchFieldException e)
 -      {
 -      }
 -
 -    catch (java.lang.IllegalAccessException e)
 -      {
 -      }
 -
 -    return l;
    }
  
    // Returns the value of CLAZZ's private static final field named
 
 --------------9BABD103EE536B49E5E2AEF4--
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]