summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2015-01-20 16:11:21 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-01-20 16:11:21 +0000
commitb131ebca5c4aaab6aef7975a819d86c1afadbb4d (patch)
tree3ee3747efd26b918b7f7346041ab168c45e4f61c
parent66630ea2bf4c23d6396f24e5d3f56317efc980f0 (diff)
parent6dc0ed7247a7520bf14a89db9b4bc3015d3cdcb2 (diff)
downloadlibcore-b131ebca5c4aaab6aef7975a819d86c1afadbb4d.zip
libcore-b131ebca5c4aaab6aef7975a819d86c1afadbb4d.tar.gz
libcore-b131ebca5c4aaab6aef7975a819d86c1afadbb4d.tar.bz2
am 6dc0ed72: Merge "Add a unit test to demonstrate ICU CharsetProvider problems"
* commit '6dc0ed7247a7520bf14a89db9b4bc3015d3cdcb2': Add a unit test to demonstrate ICU CharsetProvider problems
-rw-r--r--expectations/knownfailures.txt7
-rw-r--r--harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java110
-rw-r--r--harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider2
-rw-r--r--luni/src/test/java/libcore/java/nio/charset/SettableCharsetProvider.java57
-rw-r--r--luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider1
5 files changed, 141 insertions, 36 deletions
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 0526b64..d85df07 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -1494,5 +1494,12 @@
names: [
"org.apache.harmony.tests.java.lang.MathTest#test_cbrt_D"
]
+},
+{
+ description: "Recursive calls to Charset.forName from within providers will overflow the stack.",
+ result: EXEC_FAILED,
+ names: [
+ "org.apache.harmony.tests.java.nio.charset.CharsetTest#testForName_withProviderWithRecursiveCall"
+ ]
}
]
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
index 01cf40e..2cf278d 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/nio/charset/CharsetTest.java
@@ -25,15 +25,14 @@ import java.nio.charset.CoderResult;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.spi.CharsetProvider;
import java.nio.charset.UnsupportedCharsetException;
-import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
-import java.util.SortedMap;
import java.util.Vector;
+import libcore.java.nio.charset.SettableCharsetProvider;
import junit.framework.TestCase;
@@ -819,51 +818,94 @@ public class CharsetTest extends TestCase {
// Test the method isSupported(String) with charset supported by multiple providers.
public void testIsSupported_And_ForName_NormalProvider() throws Exception {
- assertTrue(Charset.isSupported("mockCharset10"));
- // ignore case problem in mock, intended
- assertTrue(Charset.isSupported("MockCharset11"));
- assertTrue(Charset.isSupported("MockCharset12"));
- assertTrue(Charset.isSupported("MOCKCharset10"));
- // intended case problem in mock
- assertTrue(Charset.isSupported("MOCKCharset11"));
- assertTrue(Charset.isSupported("MOCKCharset12"));
+ SettableCharsetProvider.setDelegate(new MockCharsetProvider());
+ try {
+ assertTrue(Charset.isSupported("mockCharset10"));
+ // ignore case problem in mock, intended
+ assertTrue(Charset.isSupported("MockCharset11"));
+ assertTrue(Charset.isSupported("MockCharset12"));
+ assertTrue(Charset.isSupported("MOCKCharset10"));
+ // intended case problem in mock
+ assertTrue(Charset.isSupported("MOCKCharset11"));
+ assertTrue(Charset.isSupported("MOCKCharset12"));
- assertTrue(Charset.forName("mockCharset10") instanceof MockCharset);
- assertTrue(Charset.forName("mockCharset11") instanceof MockCharset);
- assertTrue(Charset.forName("mockCharset12") instanceof MockCharset);
+ assertTrue(Charset.forName("mockCharset10") instanceof MockCharset);
+ assertTrue(Charset.forName("mockCharset11") instanceof MockCharset);
+ assertTrue(Charset.forName("mockCharset12") instanceof MockCharset);
- assertTrue(Charset.forName("mockCharset10") == charset2);
- // intended case problem in mock
- Charset.forName("mockCharset11");
- assertTrue(Charset.forName("mockCharset12") == charset2);
+ assertTrue(Charset.forName("mockCharset10") == charset2);
+ // intended case problem in mock
+ Charset.forName("mockCharset11");
+ assertTrue(Charset.forName("mockCharset12") == charset2);
+ } finally {
+ SettableCharsetProvider.clearDelegate();
+ }
}
// Test the method availableCharsets() with charset supported by multiple providers.
public void testAvailableCharsets_NormalProvider() throws Exception {
- assertTrue(Charset.availableCharsets().containsKey("mockCharset00"));
- assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00"));
- assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset);
- assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset01"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset02"));
+ SettableCharsetProvider.setDelegate(new MockCharsetProvider());
+ try {
+ assertTrue(Charset.availableCharsets().containsKey("mockCharset00"));
+ assertTrue(Charset.availableCharsets().containsKey("MOCKCharset00"));
+ assertTrue(Charset.availableCharsets().get("mockCharset00") instanceof MockCharset);
+ assertTrue(Charset.availableCharsets().get("MOCKCharset00") instanceof MockCharset);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset01"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset02"));
- assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
- assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
+ assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
+ assertTrue(Charset.availableCharsets().get("MOCKCharset10") == charset2);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
- assertTrue(Charset.availableCharsets().containsKey("mockCharset10"));
- assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10"));
- assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
- assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
- assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
+ assertTrue(Charset.availableCharsets().containsKey("mockCharset10"));
+ assertTrue(Charset.availableCharsets().containsKey("MOCKCharset10"));
+ assertTrue(Charset.availableCharsets().get("mockCharset10") == charset2);
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset11"));
+ assertFalse(Charset.availableCharsets().containsKey("mockCharset12"));
+ } finally {
+ SettableCharsetProvider.clearDelegate();
+ }
}
// Test the method forName(String) when the charset provider supports a
// built-in charset.
public void testForName_DuplicateWithBuiltInCharset() throws Exception {
- assertFalse(Charset.forName("us-ascii") instanceof MockCharset);
- assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset);
+ SettableCharsetProvider.setDelegate(new MockCharsetProviderASCII());
+ try {
+ assertFalse(Charset.forName("us-ascii") instanceof MockCharset);
+ assertFalse(Charset.availableCharsets().get("us-ascii") instanceof MockCharset);
+ } finally {
+ SettableCharsetProvider.clearDelegate();
+ }
+ }
+
+ // Fails on Android with a StackOverflowException.
+ public void testForName_withProviderWithRecursiveCall() throws Exception {
+ SettableCharsetProvider.setDelegate(new MockCharsetProviderWithRecursiveCall());
+ try {
+ Charset.forName("poop");
+ fail();
+ } catch (UnsupportedCharsetException expected) {
+ } finally {
+ SettableCharsetProvider.clearDelegate();
+ }
+ }
+
+ public static class MockCharsetProviderWithRecursiveCall extends CharsetProvider {
+ @Override
+ public Iterator<Charset> charsets() {
+ return null;
+ }
+
+ @Override
+ public Charset charsetForName(String charsetName) {
+ if (Charset.isSupported(charsetName)) {
+ return Charset.forName(charsetName);
+ }
+
+ return null;
+ }
}
public static class MockCharsetProvider extends CharsetProvider {
diff --git a/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider b/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
deleted file mode 100644
index 9cc124a..0000000
--- a/harmony-tests/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
+++ /dev/null
@@ -1,2 +0,0 @@
-org.apache.harmony.tests.java.nio.charset.CharsetTest$MockCharsetProvider
-org.apache.harmony.tests.java.nio.charset.CharsetTest$MockCharsetProviderASCII
diff --git a/luni/src/test/java/libcore/java/nio/charset/SettableCharsetProvider.java b/luni/src/test/java/libcore/java/nio/charset/SettableCharsetProvider.java
new file mode 100644
index 0000000..b4886d2
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/charset/SettableCharsetProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package libcore.java.nio.charset;
+
+import java.nio.charset.Charset;
+import java.nio.charset.spi.CharsetProvider;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * This class is registered as a charset provider by the META-INF in the libcore
+ * tests jar. Since there isn't any convenient API to dynamically register and de-register
+ * charset-providers, this class allows tests to plug in a delegate that lives for the
+ * duration of the test.
+ */
+public final class SettableCharsetProvider extends CharsetProvider {
+ private static CharsetProvider delegate;
+
+ public static void setDelegate(CharsetProvider cp) {
+ delegate = cp;
+ }
+
+ public static void clearDelegate() {
+ delegate = null;
+ }
+
+ @Override
+ public Iterator<Charset> charsets() {
+ if (delegate != null) {
+ return delegate.charsets();
+ }
+
+ return Collections.emptyIterator();
+ }
+
+ @Override
+ public Charset charsetForName(String charsetName) {
+ if (delegate != null) {
+ return delegate.charsetForName(charsetName);
+ }
+
+ return null;
+ }
+}
diff --git a/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider b/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
new file mode 100644
index 0000000..1a53312
--- /dev/null
+++ b/luni/src/test/resources/META-INF/services/java.nio.charset.spi.CharsetProvider
@@ -0,0 +1 @@
+libcore.java.nio.charset.SettableCharsetProvider