-
Bug
-
Resolution: Fixed
-
P3
-
None
-
None
-
b131
-
b01
-
x86
-
linux_redhat_7.2
========================================================
SYNOPSIS
--------
Side effect byJDK-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 byJDK-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
}
========================================================
SYNOPSIS
--------
Side effect by
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
$ ˜/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
}
========================================================