Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6392664

Initialization and Concurrency bugs in ISO-2022-CN-GB, ISO-2022-CN-CNS

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 7
    • 6
    • core-libs
    • 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.

            sherman Xueming Shen
            martin Martin Buchholz
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: