--- old/src/share/classes/sun/nio/cs/ext/DoubleByte.java 2013-10-21 12:43:49.000000000 -0700 +++ new/src/share/classes/sun/nio/cs/ext/DoubleByte.java 2013-10-21 12:43:49.000000000 -0700 @@ -111,7 +111,6 @@ public static class Decoder extends CharsetDecoder implements DelegatableDecoder, ArrayDecoder { - final char[][] b2c; final char[] b2cSB; final int b2Min; @@ -122,7 +121,12 @@ 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); } @@ -161,7 +165,7 @@ 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++; } @@ -190,7 +194,7 @@ 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); @@ -221,8 +225,13 @@ 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) { @@ -466,8 +475,8 @@ 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); }