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

Code conversion working behavior was changed for x-IBM834

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 11
    • None
    • core-libs
    • None
    • b131
    • 9
    • b01
    • x86
    • linux_redhat_7.2

      ========================================================
      SYNOPSIS
      --------
      Side effect by JDK-8008386

      OPERATING SYSTEM(S)
      -------------------
      RHEL6 x86_64

      FULL JDK VERSION(S)
      -------------------
      java version "1.7.0_79"
      Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

      java version "1.7.0_80"
      Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
      Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

      java version "1.8.0_102"
      Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

      java version "9-ea"
      Java(TM) SE Runtime Environment (build 9-ea+131)
      Java HotSpot(TM) 64-Bit Server VM (build 9-ea+131, mixed mode)


      PROBLEM DESCRIPTION
      -------------------
      Code conversion working behavior was changed for x-IBM834 by 1.7.0_80-b15.
      \xFE\xFE should be changed to \uFFFD, but \xFE\xFE was changed to \uFFFD\uFFFD

      TESTCASE
      --------
      import java.nio.charset.*;
      import java.util.*;

      public class DBCSONLY_Test1 {
        public static void main(String[] args) throws Exception {
          String repl = "\uFFFD";
          for(String s : args) {
            Charset cs = Charset.forName(s);
            System.out.print(cs.name()+": ");
            byte[] repl_ba = repl.getBytes(cs);
            for(char c : repl.toCharArray()) System.out.printf("\\u%04X",(int)c);
            System.out.print(" -> ");
            for(byte b : repl_ba) System.out.printf("\\x%02X",(int)b&0xFF);
            System.out.print(" -> ");
            for(char c : (new String(repl_ba, cs)).toCharArray()) System.out.printf("\\u%04X",(int)c);
            System.out.println();
          }
        }
      }

      REPRODUCTION INSTRUCTIONS
      -------------------------

      For x-IBM834, \uFFFD should be converted to \xFE\xFE, and \xFE\xFE should be converted to \uFFFD for round-trip conversion
      $ ˜/jdk7_79/jdk1.7.0_79/jre/bin/java DBCSONLY_Test1 x-IBM834
      x-IBM834: \uFFFD -> \xFE\xFE -> \uFFFD

      It seems working behavior was chagend by JDK-8008386
      $ ˜/jdk7_80/jdk1.7.0_80/jre/bin/java DBCSONLY_Test1 x-IBM834
      x-IBM834: \uFFFD -> \xFE\xFE -> \uFFFD\uFFFD

      $ ˜/jdk8_102/jdk1.8.0_102/jre/bin/java DBCSONLY_Test1 x-IBM834
      x-IBM834: \uFFFD -> \xFE\xFE -> \uFFFD\uFFFD

      $ ˜/jdk9/jdk-9/bin/java DBCSONLY_Test1 x-IBM834
      x-IBM834: \uFFFD -> \xFE\xFE -> \uFFFD\uFFFD


      WORKAROUND
      ----------
      Unknown

      SUGGESTED FIX
      -------------
      diff -r 021369229cfd src/java.base/share/classes/sun/nio/cs/DoubleByte.java
      --- a/src/java.base/share/classes/sun/nio/cs/DoubleByte.java Tue Sep 06 13:09:29 2016 -0400
      +++ b/src/java.base/share/classes/sun/nio/cs/DoubleByte.java Tue Sep 20 12:16:30 2016 +0900
      @@ -482,6 +482,53 @@
               }
           }

      + // DBCS_ONLY2
      + public static class Decoder_DBCSONLY2 extends Decoder {
      + static final char[] b2cSB_UNMAPPABLE;
      + static {
      + b2cSB_UNMAPPABLE = new char[0x100];
      + Arrays.fill(b2cSB_UNMAPPABLE, UNMAPPABLE_DECODING);
      + }
      +
      + public Decoder_DBCSONLY2(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max,
      + boolean isASCIICompatible) {
      + super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, isASCIICompatible);
      + }
      +
      + public Decoder_DBCSONLY2(Charset cs, char[][] b2c, char[] b2cSB, int b2Min, int b2Max) {
      + super(cs, 0.5f, 1.0f, b2c, b2cSB_UNMAPPABLE, b2Min, b2Max, false);
      + }
      +
      + @Override
      + protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
      + if (b2c[b1] != B2C_UNMAPPABLE && (b2 >= b2Min && b2 <= b2Max)) {
      + return CoderResult.unmappableForLength(2);
      + }
      + return CoderResult.malformedForLength(2);
      + }
      + @Override
      + public int decode(byte[] src, int sp, int len, char[] dst) {
      + int dp = 0;
      + int sl = sp + len;
      + char repl = replacement().charAt(0);
      + while (sp < sl) {
      + int b1 = src[sp++] & 0xff;
      + char c = UNMAPPABLE_DECODING;
      + if (sp < sl) {
      + int b2 = src[sp++] & 0xff;
      + if (b2 >= b2Min && b2 <= b2Max) {
      + c = b2c[b1][b2 - b2Min];
      + }
      + }
      + if (c == UNMAPPABLE_DECODING) {
      + c = repl;
      + }
      + dst[dp++] = c;
      + }
      + return dp;
      + }
      + }
      +
           // EUC_SIMPLE
           // The only thing we need to "override" is to check SS2/SS3 and
           // return "malformed" if found
      diff -r 021369229cfd src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java
      --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java Tue Sep 06 13:09:29 2016 -0400
      +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/IBM834.java Tue Sep 20 12:16:30 2016 +0900
      @@ -50,7 +50,7 @@

           public CharsetDecoder newDecoder() {
               IBM933.initb2c();
      - return new DoubleByte.Decoder_DBCSONLY(
      + return new DoubleByte.Decoder_DBCSONLY2(
                   this, IBM933.b2c, null, 0x40, 0xfe); // hardcode the b2min/max
           }


      ========================================================

            sherman Xueming Shen
            youdwei Deven You (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: