-
Bug
-
Resolution: Fixed
-
P3
-
6
-
b03
-
generic, x86
-
generic, windows_xp
-
Verified
Basically, using ISO-2022-CN-GB only works if you
first use ISO-2022-CN.
Likely cause:
./ext/ISO2022_CN.java:39: private static CharsetDecoder gb2312Decoder
= null;
./ext/ISO2022_CN.java:40: private static CharsetDecoder cnsDecoder =
null;
These static variables are initialized in newDecoder, an instance
method of the charset, which seems very wrong (what happens if two
threads decode?)
If ISO2022_CN.newDecoder is never called, these variables are never
initialized!
It seems these decoders should be instance variables of
ISO2022_CN.Decoder.
More precisely, this source file:
------------------
public class Decode {
private static boolean isAscii(char c) {
return c < '\u0080';
}
private static boolean isPrintable(char c) {
return ('\u0020' < c) && (c < '\u007f');
}
public static void main(String[] args) throws Throwable {
if (args.length < 2)
throw new Exception("Usage: java Decode CHARSET BYTE [BYTE ...]");
String cs = args[0];
byte[] bytes = new byte[args.length-1];
for (int i = 1; i < args.length; i++) {
String arg = args[i];
bytes[i-1] =
(arg.length() == 1 && isAscii(arg.charAt(0))) ?
(byte) arg.charAt(0) :
arg.equals("ESC") ? 0x1b :
arg.equals("SO") ? 0x0e :
arg.equals("SI") ? 0x0f :
arg.equals("SS2") ? (byte) 0x8e :
arg.equals("SS3") ? (byte) 0x8f :
arg.matches("0x.*") ? Integer.decode(arg).byteValue() :
Integer.decode("0x"+arg).byteValue();
}
String s = new String(bytes, cs);
for (int j = 0; j < s.length(); j++) {
if (j > 0)
System.out.print(' ');
char c = s.charAt(j);
if (isPrintable(c))
System.out.print(c);
else if (c == '\u001b') System.out.print("ESC");
else
System.out.printf("\\u%04x", (int) c);
}
System.out.print("\n");
}
}
------------------
demonstrates the following bug:
jr Decode ISO-2022-CN-GB 0e 42 43
==> javac -source 1.6 -Xlint:all Decode.java
==> java -esa -ea Decode ISO-2022-CN-GB 0e 42 43
Exception in thread "main" java.lang.NullPointerException
at sun.nio.cs.ext.ISO2022_CN$Decoder.SODecode(ISO2022_CN.java:114)
at sun.nio.cs.ext.ISO2022_CN$Decoder.decodeArrayLoop(ISO2022_CN.java:368)
at sun.nio.cs.ext.ISO2022_CN$Decoder.decodeLoop(ISO2022_CN.java:383)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:544)
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:136)
at java.lang.StringCoding.decode(StringCoding.java:169)
at java.lang.String.<init>(String.java:401)
at java.lang.String.<init>(String.java:429)
at Decode.main(Decode.java:28)
It would take more work to demonstrate a race condition with concurrent
access to static Decoders from different threads.
first use ISO-2022-CN.
Likely cause:
./ext/ISO2022_CN.java:39: private static CharsetDecoder gb2312Decoder
= null;
./ext/ISO2022_CN.java:40: private static CharsetDecoder cnsDecoder =
null;
These static variables are initialized in newDecoder, an instance
method of the charset, which seems very wrong (what happens if two
threads decode?)
If ISO2022_CN.newDecoder is never called, these variables are never
initialized!
It seems these decoders should be instance variables of
ISO2022_CN.Decoder.
More precisely, this source file:
------------------
public class Decode {
private static boolean isAscii(char c) {
return c < '\u0080';
}
private static boolean isPrintable(char c) {
return ('\u0020' < c) && (c < '\u007f');
}
public static void main(String[] args) throws Throwable {
if (args.length < 2)
throw new Exception("Usage: java Decode CHARSET BYTE [BYTE ...]");
String cs = args[0];
byte[] bytes = new byte[args.length-1];
for (int i = 1; i < args.length; i++) {
String arg = args[i];
bytes[i-1] =
(arg.length() == 1 && isAscii(arg.charAt(0))) ?
(byte) arg.charAt(0) :
arg.equals("ESC") ? 0x1b :
arg.equals("SO") ? 0x0e :
arg.equals("SI") ? 0x0f :
arg.equals("SS2") ? (byte) 0x8e :
arg.equals("SS3") ? (byte) 0x8f :
arg.matches("0x.*") ? Integer.decode(arg).byteValue() :
Integer.decode("0x"+arg).byteValue();
}
String s = new String(bytes, cs);
for (int j = 0; j < s.length(); j++) {
if (j > 0)
System.out.print(' ');
char c = s.charAt(j);
if (isPrintable(c))
System.out.print(c);
else if (c == '\u001b') System.out.print("ESC");
else
System.out.printf("\\u%04x", (int) c);
}
System.out.print("\n");
}
}
------------------
demonstrates the following bug:
jr Decode ISO-2022-CN-GB 0e 42 43
==> javac -source 1.6 -Xlint:all Decode.java
==> java -esa -ea Decode ISO-2022-CN-GB 0e 42 43
Exception in thread "main" java.lang.NullPointerException
at sun.nio.cs.ext.ISO2022_CN$Decoder.SODecode(ISO2022_CN.java:114)
at sun.nio.cs.ext.ISO2022_CN$Decoder.decodeArrayLoop(ISO2022_CN.java:368)
at sun.nio.cs.ext.ISO2022_CN$Decoder.decodeLoop(ISO2022_CN.java:383)
at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:544)
at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:136)
at java.lang.StringCoding.decode(StringCoding.java:169)
at java.lang.String.<init>(String.java:401)
at java.lang.String.<init>(String.java:429)
at Decode.main(Decode.java:28)
It would take more work to demonstrate a race condition with concurrent
access to static Decoders from different threads.
- duplicates
-
JDK-6577873 NPE in x-ISO-2022-CN-GB & x-ISO-2022-CN-CNS in decoding
-
- Closed
-