[cp-patches] FYI: java.util.Locale - fix broken serialization and equals()

2006-08-12 Thread Sven de Marothy
This is a major embarassment. 

2006-08-13  Sven de Marothy  [EMAIL PROTECTED]

* java/util/Locale.java
(hashcode): Is a serialized field, not transient.
(equals): Should NOT compare strings by reference.
(readObject/writeObject): Use the default methods and handle the hash
seperately.


Index: java/util/Locale.java
===
RCS file: /sources/classpath/classpath/java/util/Locale.java,v
retrieving revision 1.33
diff -U3 -r1.33 Locale.java
--- java/util/Locale.java	20 Apr 2006 09:29:27 -	1.33
+++ java/util/Locale.java	13 Aug 2006 00:17:42 -
@@ -192,7 +192,7 @@
*
* @serial should be -1 in serial streams
*/
-  private transient int hashcode;
+  private int hashcode;
 
   /**
* Array storing all available locales.
@@ -917,9 +917,9 @@
   return false;
 Locale l = (Locale) obj;
 
-return (language == l.language
- country == l.country
- variant == l.variant);
+return (language.equals( l.language )
+ country.equals( l.country )
+ variant.equals( l.variant ) );
   }
 
   /**
@@ -935,11 +935,11 @@
   private void writeObject(ObjectOutputStream s)
 throws IOException
   {
-s.writeObject(language);
-s.writeObject(country);
-s.writeObject(variant);
 // Hashcode field is always written as -1.
-s.writeInt(-1);
+int temp = hashcode;
+hashcode = -1;
+s.defaultWriteObject();
+hashcode = temp;
   }
 
   /**
@@ -953,9 +953,7 @@
   private void readObject(ObjectInputStream s)
 throws IOException, ClassNotFoundException
   {
-language = ((String) s.readObject()).intern();
-country = ((String) s.readObject()).intern();
-variant = ((String) s.readObject()).intern();
+s.defaultReadObject();
 // Recompute hashcode.
 hashcode = language.hashCode() ^ country.hashCode() ^ variant.hashCode();
   }


Re: [cp-patches] FYI: java.util.Locale - fix broken serialization and equals()

2006-08-12 Thread Mark Wielaard
On Sun, 2006-08-13 at 02:21 +0200, Sven de Marothy wrote:
 2006-08-13  Sven de Marothy  [EMAIL PROTECTED]
 
   * java/util/Locale.java
   (hashcode): Is a serialized field, not transient.
   (equals): Should NOT compare strings by reference.
   (readObject/writeObject): Use the default methods and handle the hash
   seperately.
 [...]
 +int temp = hashcode;
 +hashcode = -1;
 +s.defaultWriteObject();
 +hashcode = temp;

This is not thread-safe. If one thread serializes the Locale and another
uses its hashCode() method.

 [...]
 -language = ((String) s.readObject()).intern();
 -country = ((String) s.readObject()).intern();
 -variant = ((String) s.readObject()).intern();
 +s.defaultReadObject();

There are a couple of places in this class that depend on these three
fields to be interned. Please see the comments in the class that say so.

Cheers,

Mark


signature.asc
Description: This is a digitally signed message part