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