src/share/classes/sun/nio/cs/ext/DoubleByte.java

Print this page

        

@@ -109,22 +109,26 @@
     }
 
     public static class Decoder extends CharsetDecoder
                                 implements DelegatableDecoder, ArrayDecoder
     {
-
         final char[][] b2c;
         final char[] b2cSB;
         final int b2Min;
         final int b2Max;
 
         // for SimpleEUC override
         protected CoderResult crMalformedOrUnderFlow(int b) {
             return CoderResult.UNDERFLOW;
         }
 
-        protected CoderResult crMalformedOrUnmappable(int b) {
+        protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
+            if (b2c[b1] == B2C_UNMAPPABLE ||                // isNotLeadingByte(b1)
+                b2c[b2] != B2C_UNMAPPABLE ||                // isLeadingByte(b2)
+                decodeSingle(b2) != UNMAPPABLE_DECODING) {  // isSingle(b2)
+                return CoderResult.malformedForLength(1);
+            }
             return CoderResult.unmappableForLength(2);
         }
 
         Decoder(Charset cs, float avgcpb, float maxcpb,
                 char[][] b2c, char[] b2cSB,

@@ -159,11 +163,11 @@
                         if (sl - sp < 2)
                             return crMalformedOrUnderFlow(b1);
                         int b2 = sa[sp + 1] & 0xff;
                         if (b2 < b2Min || b2 > b2Max ||
                             (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
-                            return crMalformedOrUnmappable(b1);
+                            return crMalformedOrUnmappable(b1, b2);
                         }
                         inSize++;
                     }
                     da[dp++] = c;
                     sp += inSize;

@@ -188,11 +192,11 @@
                         if (src.remaining() < 1)
                             return crMalformedOrUnderFlow(b1);
                         int b2 = src.get() & 0xff;
                         if (b2 < b2Min || b2 > b2Max ||
                             (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING)
-                            return crMalformedOrUnmappable(b1);
+                            return crMalformedOrUnmappable(b1, b2);
                         inSize++;
                     }
                     dst.put(c);
                     mark += inSize;
                 }

@@ -219,12 +223,17 @@
                 int b1 = src[sp++] & 0xff;
                 char c = b2cSB[b1];
                 if (c == UNMAPPABLE_DECODING) {
                     if (sp < sl) {
                         int b2 = src[sp++] & 0xff;
-                        if (b2 >= b2Min && b2 <= b2Max) {
-                            c = b2c[b1][b2 - b2Min];
+                        if (b2 < b2Min || b2 > b2Max ||
+                            (c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
+                            if (b2c[b1] == B2C_UNMAPPABLE ||  // isNotLeadingByte
+                                b2c[b2] != B2C_UNMAPPABLE ||  // isLeadingByte
+                                decodeSingle(b2) != UNMAPPABLE_DECODING) {
+                                sp--;
+                            }
                         }
                     }
                     if (c == UNMAPPABLE_DECODING) {
                         c = repl;
                     }

@@ -464,12 +473,12 @@
             if (b == SS2 || b == SS3 )
                 return CoderResult.malformedForLength(1);
             return CoderResult.UNDERFLOW;
         }
 
-        protected CoderResult crMalformedOrUnmappable(int b) {
-            if (b == SS2 || b == SS3 )
+        protected CoderResult crMalformedOrUnmappable(int b1, int b2) {
+            if (b1 == SS2 || b1 == SS3 )
                 return CoderResult.malformedForLength(1);
             return CoderResult.unmappableForLength(2);
         }
 
         public int decode(byte[] src, int sp, int len, char[] dst) {