classpath
[Top][All Lists]
Advanced

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

Re: [Classpath] Re: Bug(s) in java.lang.String


From: Mark Wielaard
Subject: Re: [Classpath] Re: Bug(s) in java.lang.String
Date: 11 Aug 2002 19:38:16 +0200

Hi,

On Fri, 2002-08-09 at 17:48, Stephen Crawley wrote:
> I've finally found time to track down the cause of this bug.  It turns out
> that it is a consequence of the way that Kissme unpacks "asciz" strings
> with multi-byte characters.  In this case Kissme is creating a String object 
> with count == 204, offset == 0, value.length == 443, and the value array 
> padded beyond position 203 with '\000' characters.  
> 
> I believe that this is a legitimate (though suboptimal) representation
> for the String object. If so, it is unsafe for java.lang.String to use
> value.length instead of count to determine length of the CharData
> strings; e.g. in upperCaseIndex.
> 
> We could fix this (pretty easily) in Kissme, but the same problem may
> conceivably crop up in other VMs.

Yeah. It seems to be legal for a VM to do tricks like this. Eric Blake
suggested to just use System.arraycopy to make sure that the array is
always zero based. The attached patch does that when the char[] is not
already zero based. I have not yet tested it. Could you test if this
works with Kissme?

Thanks,

Mark
Index: java/lang/Character.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Character.java,v
retrieving revision 1.30
diff -u -r1.30 Character.java
--- java/lang/Character.java    12 Jul 2002 21:25:53 -0000      1.30
+++ java/lang/Character.java    11 Aug 2002 17:32:18 -0000
@@ -1384,40 +1384,63 @@
   public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18;
 
   /**
+   * Returns the value array of the given string if it is zero based or a
+   * copy of it that is zero based (stripping offset and making length equal
+   * to count). Used for accessing the char[]s of gnu.java.lang.CharData.
+   * Package private for use in String.
+   */
+  static char[] zeroBasedStringValue(String s)
+  {
+    char[] value;
+
+    if (s.offset == 0 && s.count == s.value.length)
+      value = s.value;
+    else
+      {
+       int count = s.count;
+       value = new char[count];
+       System.arraycopy(s.value, s.offset, value, 0, count);
+      }
+
+    return value;
+  }
+
+  /**
    * Stores unicode block offset lookup table. Exploit package visibility of
    * String.value to avoid copying the array.
    * @see #readChar(char)
    * @see CharData#BLOCKS
    */
-  private static final char[] blocks = CharData.BLOCKS.value;
+  private static final char[] blocks = zeroBasedStringValue(CharData.BLOCKS);
 
   /**
    * Stores unicode attribute offset lookup table. Exploit package visibility
    * of String.value to avoid copying the array.
    * @see CharData#DATA
    */
-  private static final char[] data = CharData.DATA.value;
+  private static final char[] data = zeroBasedStringValue(CharData.DATA);
 
   /**
    * Stores unicode numeric value attribute table. Exploit package visibility
    * of String.value to avoid copying the array.
    * @see CharData#NUM_VALUE
    */
-  private static final char[] numValue = CharData.NUM_VALUE.value;
+  private static final char[] numValue
+         = zeroBasedStringValue(CharData.NUM_VALUE);
 
   /**
    * Stores unicode uppercase attribute table. Exploit package visibility
    * of String.value to avoid copying the array.
    * @see CharData#UPPER
    */
-  private static final char[] upper = CharData.UPPER.value;
+  private static final char[] upper = zeroBasedStringValue(CharData.UPPER);
 
   /**
    * Stores unicode lowercase attribute table. Exploit package visibility
    * of String.value to avoid copying the array.
    * @see CharData#LOWER
    */
-  private static final char[] lower = CharData.LOWER.value;
+  private static final char[] lower = zeroBasedStringValue(CharData.LOWER);
 
   /**
    * Stores unicode direction attribute table. Exploit package visibility
@@ -1425,14 +1448,14 @@
    * @see CharData#DIRECTION
    */
   // Package visible for use by String.
-  static final char[] direction = CharData.DIRECTION.value;
+  static final char[] direction = zeroBasedStringValue(CharData.DIRECTION);
 
   /**
    * Stores unicode titlecase table. Exploit package visibility of
    * String.value to avoid copying the array.
    * @see CharData#TITLE
    */
-  private static final char[] title = CharData.TITLE.value;
+  private static final char[] title = zeroBasedStringValue(CharData.TITLE);
 
   /**
    * Mask for grabbing the type out of the contents of data.
Index: java/lang/String.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/String.java,v
retrieving revision 1.49
diff -u -r1.49 String.java
--- java/lang/String.java       30 Jul 2002 21:17:55 -0000      1.49
+++ java/lang/String.java       11 Aug 2002 17:32:19 -0000
@@ -98,15 +98,17 @@
    * @see #toUpperCase(char)
    * @see CharData#UPPER_EXPAND
    */
-  private static final char[] upperExpand = CharData.UPPER_EXPAND.value;
+  private static final char[] upperExpand
+       = Character.zeroBasedStringValue(CharData.UPPER_EXPAND);
 
   /**
    * Stores unicode multi-character uppercase special casing table.
    * @see #upperCaseExpansion(char)
    * @see CharData#UPPER_SPECIAL
    */
-  private static final char[] upperSpecial = CharData.UPPER_SPECIAL.value;
-
+  private static final char[] upperSpecial
+         = Character.zeroBasedStringValue(CharData.UPPER_SPECIAL);
+  
   /**
    * Characters which make up the String.
    * Package access is granted for use by StringBuffer.

reply via email to

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