Skip to content

Commit 5c41d00

Browse files
author
mgricken
committed
Fixed bug 2976104:
java.lang.StringIndexOutOfBoundsException: String index out of range: 94 at java.lang.String.substring(Unknown Source) at edu.rice.cs.drjava.platform.WindowsRegistry.nullTerminatedToString(WindowsRegistry.java:612) According to the String Javadocs, "The length of the new String is a function of the charset, and hence may not be equal to the length of the byte array." We cannot use barr.length to index in the string, we need to index in the array. Cannot test this on a Chinese system, but I'm fairly certain this should work. git-svn-id: file:///tmp/test-svn/trunk@5353 fe72c1cf-3628-48e9-8b72-1c46755d3cff
1 parent d6d5a09 commit 5c41d00

File tree

4 files changed

+99
-10
lines changed

4 files changed

+99
-10
lines changed

drjava/lib/platform.jar

338 Bytes
Binary file not shown.
Binary file not shown.

platform/src-windows/edu/rice/cs/drjava/platform/WindowsRegistry.java

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -596,20 +596,52 @@ public static void delKey(int hKey, String subKey) throws RegistryException {
596596
deleteKey(hKey, subKey);
597597
}
598598

599-
/** @return this Java string as a null-terminated byte array */
599+
/** @return this Java string as a null-terminated byte array in the default Charset */
600600
public static byte[] stringToNullTerminated(String str) {
601-
byte[] result = new byte[str.length() + 1];
602-
for (int i = 0; i<str.length(); i++) {
603-
result[i] = (byte) str.charAt(i);
604-
}
605-
result[str.length()] = 0;
606-
return result;
601+
return stringToNullTerminated(str, java.nio.charset.Charset.defaultCharset());
602+
}
603+
604+
/** @return this Java string as a null-terminated byte array */
605+
public static byte[] stringToNullTerminated(String str, java.nio.charset.Charset charset) {
606+
return stringToNullTerminated(str, charset.toString());
607607
}
608608

609-
/** @return this a null-terminated byte array as Java String */
609+
/** @return this Java string as a null-terminated byte array */
610+
public static byte[] stringToNullTerminated(String str, String charset) {
611+
try {
612+
byte[] barr = str.getBytes(charset);
613+
byte[] result = new byte[barr.length + 1];
614+
System.arraycopy(barr, 0, result, 0, barr.length);
615+
result[result.length-1] = 0;
616+
return result;
617+
}
618+
catch(java.io.UnsupportedEncodingException uee) {
619+
return new byte[] { 0 };
620+
}
621+
}
622+
623+
/** @return this null-terminated byte array as Java String using the default Charset */
610624
public static String nullTerminatedToString(byte[] barr) {
611-
if (barr==null) return null;
612-
return new String(barr).substring(0, barr.length-1);
625+
return nullTerminatedToString(barr, java.nio.charset.Charset.defaultCharset());
626+
}
627+
628+
/** @return this null-terminated byte array as Java String */
629+
public static String nullTerminatedToString(byte[] barr, java.nio.charset.Charset charset) {
630+
return nullTerminatedToString(barr, charset.toString());
631+
}
632+
633+
/** @return this null-terminated byte array as Java String */
634+
public static String nullTerminatedToString(byte[] barr, String charset) {
635+
try {
636+
if (barr==null) return null;
637+
// bugfix for 2976104: according to the String Javadocs, "The length of the new String is a function of the
638+
// charset, and hence may not be equal to the length of the byte array."
639+
// We cannot use barr.length to index in the string, we need to index in the array.
640+
int len = barr.length;
641+
if (barr[len-1] == 0) { --len; } // do not copy null terminator
642+
return new String(barr, 0, len, charset);
643+
}
644+
catch(Exception e) { return ""; } // defensive programming for bug 2976104
613645
}
614646

615647
/** @return a name for the hive (HKEY_???). */
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*BEGIN_COPYRIGHT_BLOCK
2+
*
3+
* Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
* * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
14+
* names of its contributors may be used to endorse or promote products
15+
* derived from this software without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*
29+
* This software is Open Source Initiative approved Open Source Software.
30+
* Open Source Initative Approved is a trademark of the Open Source Initiative.
31+
*
32+
* This file is part of DrJava. Download the current version of this project
33+
* from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
34+
*
35+
* END_COPYRIGHT_BLOCK*/
36+
37+
package edu.rice.cs.drjava.platform;
38+
39+
import junit.framework.*;
40+
41+
/**
42+
* Tests for WindowsRegistry.
43+
*/
44+
public class WindowsRegistryTest extends TestCase {
45+
/** Tests different charsets and null-terminated strings. */
46+
public void testNullTerminatedCharsets() {
47+
String s = "ABCDE";
48+
byte[] utf8 = WindowsRegistry.stringToNullTerminated(s, "UTF-8");
49+
assertTrue(utf8.length-1==s.length());
50+
byte[] utf16 = WindowsRegistry.stringToNullTerminated(s, "UTF-16");
51+
assertFalse(utf16.length-1==s.length());
52+
String s8 = WindowsRegistry.nullTerminatedToString(utf8, "UTF-8");
53+
assertEquals(s, s8);
54+
String s16 = WindowsRegistry.nullTerminatedToString(utf16, "UTF-16");
55+
assertEquals(s, s16);
56+
}
57+
}

0 commit comments

Comments
 (0)