This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: libgcj/2237: serialization doesn't throw exception on failure
- To: nobody at gcc dot gnu dot org
- Subject: Re: libgcj/2237: serialization doesn't throw exception on failure
- From: Bryce McKinlay <bryce at albatross dot co dot nz>
- Date: 11 Mar 2001 11:26:01 -0000
- Cc: gcc-prs at gcc dot gnu dot org,
- Reply-To: Bryce McKinlay <bryce at albatross dot co dot nz>
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--