Index: trunk/http-core/src/test/org/apache/http/util/TestEncodingUtils.java =================================================================== --- trunk/http-core/src/test/org/apache/http/util/TestEncodingUtils.java (revision 375054) +++ trunk/http-core/src/test/org/apache/http/util/TestEncodingUtils.java (working copy) @@ -190,5 +190,54 @@ String s2 = EncodingUtils.getString(b1, "ThisJustAintRight"); assertEquals(s1, s2); } - -} \ No newline at end of file + + public void testIllegalEncoding() { + String s = constructString(SWISS_GERMAN_HELLO); + byte[] b1 = s.getBytes(); + byte[] b2 = EncodingUtils.getBytes(s, "some chars,illegal/are!"); + assertEquals(b1.length, b2.length); + for (int i = 0; i < b1.length; i++) { + assertEquals(b1[i], b2[i]); + } + String s1 = new String(b1); + String s2 = EncodingUtils.getString(b1, "some chars,illegal/are!"); + assertEquals(s1, s2); + } + + public void testCharsetProblemDetection() { + // no positive test because that would require Java 1.4 + //RuntimeException p1 = new + // java.nio.charset.IllegalCharsetNameException("white space"); + //EncodingUtils.ignoreIfCharsetProblem(p1); + + RuntimeException x1 = new NullPointerException(); + RuntimeException x2 = new IllegalArgumentException("wrong"); + RuntimeException x3 = null; // yes, that is intentional + + try { + EncodingUtils.ignoreIfCharsetProblem(x1); + fail("exception should have been thrown: " + x1); + } catch (Exception x) { + if (x != x1) + fail("wrong exception has been thrown"); + } + + try { + EncodingUtils.ignoreIfCharsetProblem(x2); + fail("exception should have been thrown: " + x2); + } catch (Exception x) { + if (x != x2) + fail("wrong exception has been thrown"); + } + + try { + EncodingUtils.ignoreIfCharsetProblem(x3); + fail("exception should have been thrown: " + x3); + } catch (Exception x) { + // some JVMs do map "throw null" to "throw new NPE" + if ((x != x3) && !(x instanceof NullPointerException)) + fail("wrong exception has been thrown"); + } + + } // testCharsetProblemDetection +} Index: trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java =================================================================== --- trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java (revision 375054) +++ trunk/http-core/src/java/org/apache/http/util/EncodingUtils.java (working copy) @@ -70,14 +70,24 @@ throw new IllegalArgumentException("charset may not be null or empty"); } + String result = null; try { - return new String(data, offset, length, charset); + result = new String(data, offset, length, charset); + } catch (UnsupportedEncodingException e) { - return new String(data, offset, length); + // ignore, use fallback below + } catch (RuntimeException rtx) { + ignoreIfCharsetProblem(rtx); + // use fallback below } - } + if (result == null) + result = new String(data, offset, length); // platform encoding + return result; + } // getString + + /** * Converts the byte array of HTTP content characters to a string. If * the specified charset is not supported, default system encoding @@ -116,12 +126,24 @@ throw new IllegalArgumentException("charset may not be null or empty"); } + byte[] result = null; try { - return data.getBytes(charset); + result = data.getBytes(charset); + } catch (UnsupportedEncodingException e) { - return data.getBytes(); + // ignore, use fallback below + } catch (RuntimeException rtx) { + ignoreIfCharsetProblem(rtx); + // use fallback below } - } + + if (result == null) + result = data.getBytes(); // fallback: platform default encoding + + return result; + + } // getBytes + /** * Converts the specified string to byte array of ASCII characters. @@ -193,4 +215,37 @@ super(); } -} + + /** + * Checks whether an exception indicates a charset problem. + * If so, this method simply returns. Otherwise, the argument + * exception is thrown. + * + * @param rtx the runtime exception to check, or + * null if null was caught + * + * @throws RuntimeException + * if the argument is not an indicator for a charset problem. + * The exception thrown is the argument exception. + * If null is passed as argument, null + * will be thrown, but the JVM might map that to a regular + * NullPointerException. + */ + public final static void ignoreIfCharsetProblem(RuntimeException rtx) + throws RuntimeException { + + // UnsupportedEncodingException is not a RuntimeException, or else... + //if (rtx instanceof UnsupportedEncodingException) + // return; + + // for compatibility with IBM JDK 1.4.2 + // check the classname to avoid a dependency on the Java 1.4 API + if ((rtx != null) && + rtx.getClass().getName().startsWith("java.nio.charset.")) + return; + + throw rtx; // do not ignore this exception + + } // ignoreIfCharsetProblem + +} // class EncodingUtils