[Top][All Lists]
[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.