--- old/src/java.base/share/classes/java/lang/StringCoding.java 2018-06-26 12:01:34.123385512 -0700 +++ new/src/java.base/share/classes/java/lang/StringCoding.java 2018-06-26 12:01:33.703340489 -0700 @@ -36,6 +36,8 @@ import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.MalformedInputException; +import java.nio.charset.UnmappableCharacterException; import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; import jdk.internal.HotSpotIntrinsicCandidate; @@ -607,7 +609,7 @@ dp = dp + ret; if (ret != len) { if (!doReplace) { - throwMalformed(sp, 1); + throwUnmappable(sp, 1); } char c = StringUTF16.getChar(val, sp++); if (Character.isHighSurrogate(c) && sp < sl && @@ -679,8 +681,8 @@ } private static void throwMalformed(int off, int nb) { - throw new IllegalArgumentException("malformed input off : " + off + - ", length : " + nb); + String msg = "malformed input off : " + off + ", length : " + nb; + throw new IllegalArgumentException(msg, new MalformedInputException(nb)); } private static void throwMalformed(byte[] val) { @@ -689,6 +691,17 @@ throwMalformed(dp, 1); } + private static void throwUnmappable(int off, int nb) { + String msg = "malformed input off : " + off + ", length : " + nb; + throw new IllegalArgumentException(msg, new UnmappableCharacterException(nb)); + } + + private static void throwUnmappable(byte[] val) { + int dp = 0; + while (dp < val.length && val[dp] >=0) { dp++; } + throwUnmappable(dp, 1); + } + private static char repl = '\ufffd'; private static Result decodeUTF8(byte[] src, int sp, int len, boolean doReplace) { @@ -919,7 +932,7 @@ if (doReplace) { dst[dp++] = '?'; } else { - throwMalformed(sp - 1, 1); // or 2, does not matter here + throwUnmappable(sp - 1, 1); // or 2, does not matter here } } else { dst[dp++] = (byte)(0xf0 | ((uc >> 18))); @@ -972,7 +985,19 @@ return new String(StringLatin1.inflate(src, 0, src.length), UTF16); } - static String newStringNoRepl(byte[] src, Charset cs) { + static String newStringNoRepl(byte[] src, Charset cs) throws CharacterCodingException { + try { + return newStringNoRepl1(src, cs); + } catch (IllegalArgumentException e) { + Throwable cause = e.getCause(); + if (cause != null && cause instanceof MalformedInputException) { + throw (MalformedInputException)cause; + } + throw new UnmappableCharacterException(1); + } + } + + static String newStringNoRepl1(byte[] src, Charset cs) { if (cs == UTF_8) { if (COMPACT_STRINGS && isASCII(src)) return new String(src, LATIN1); @@ -1025,7 +1050,19 @@ /* * Throws iae, instead of replacing, if unmappable. */ - static byte[] getBytesNoRepl(String s, Charset cs) { + static byte[] getBytesNoRepl(String s, Charset cs) throws CharacterCodingException { + try { + return getBytesNoRepl1(s, cs); + } catch (IllegalArgumentException e) { + Throwable cause = e.getCause(); + if (cause != null && cause instanceof UnmappableCharacterException) { + throw (UnmappableCharacterException)cause; + } + throw new UnmappableCharacterException(1); + } + } + + static byte[] getBytesNoRepl1(String s, Charset cs) { byte[] val = s.value(); byte coder = s.coder(); if (cs == UTF_8) { @@ -1045,7 +1082,7 @@ if (isASCII(val)) { return val; } else { - throwMalformed(val); + throwUnmappable(val); } } } @@ -1083,7 +1120,7 @@ if (!cr.isUnderflow()) cr.throwException(); } catch (CharacterCodingException x) { - throw new Error(x); + throw new IllegalArgumentException(x); } return safeTrim(ba, bb.position(), isTrusted); }