diff options
author | Narayan Kamath <narayan@google.com> | 2015-01-20 16:11:21 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-01-20 16:11:21 +0000 |
commit | b131ebca5c4aaab6aef7975a819d86c1afadbb4d (patch) | |
tree | 3ee3747efd26b918b7f7346041ab168c45e4f61c | |
parent | 66630ea2bf4c23d6396f24e5d3f56317efc980f0 (diff) | |
parent | 6dc0ed7247a7520bf14a89db9b4bc3015d3cdcb2 (diff) | |
download | libcore-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
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 |