diff options
18 files changed, 376 insertions, 177 deletions
diff --git a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java index 8f09029..efc55d1 100644 --- a/icu/src/main/java/com/ibm/icu4jni/util/Resources.java +++ b/icu/src/main/java/com/ibm/icu4jni/util/Resources.java @@ -343,8 +343,13 @@ public class Resources { localeData.fullTimeFormat = localeData.fullTimeFormat.replace('v', 'z'); } if (localeData.numberPattern != null) { - String numberPattern = localeData.numberPattern; - localeData.integerPattern = numberPattern.substring(0, numberPattern.indexOf('.')); + // The number pattern might contain positive and negative subpatterns. Arabic, for + // example, might look like "#,##0.###;#,##0.###-" because the minus sign should be + // written last. Macedonian supposedly looks something like "#,##0.###;(#,##0.###)". + // (The negative subpattern is optional, though, and not present in most locales.) + // By only swallowing '#'es and ','s after the '.', we ensure that we don't + // accidentally eat too much. + localeData.integerPattern = localeData.numberPattern.replaceAll("\\.[#,]*", ""); } return localeData; } diff --git a/luni-kernel/src/main/java/java/lang/System.java b/luni-kernel/src/main/java/java/lang/System.java index b97a75a..aa78b1b 100644 --- a/luni-kernel/src/main/java/java/lang/System.java +++ b/luni-kernel/src/main/java/java/lang/System.java @@ -603,10 +603,14 @@ public final class System { } /** - * Sets the active security manager. Note that once the security manager has - * been set, it can not be changed. Attempts to do that will cause a + * <strong>Warning:</strong> security managers do <strong>not</strong> + * provide a secure environment for executing untrusted code. Untrusted code + * cannot be safely isolated within the Dalvik VM. + * + * <p>Sets the active security manager. Note that once the security manager + * has been set, it can not be changed. Attempts to do that will cause a * security exception. - * + * * @param sm * the new security manager. * @throws SecurityException diff --git a/luni/src/main/java/java/lang/CaseMapper.java b/luni/src/main/java/java/lang/CaseMapper.java new file mode 100644 index 0000000..c74bda0 --- /dev/null +++ b/luni/src/main/java/java/lang/CaseMapper.java @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2010 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 java.lang; + +import java.util.Locale; + +/** + * Performs case operations as described by http://unicode.org/reports/tr21/tr21-5.html. + */ +class CaseMapper { + // Intention-revealing constants for various important characters. + private static final char LATIN_CAPITAL_I = 'I'; + private static final char LATIN_SMALL_I = 'i'; + private static final char LATIN_CAPITAL_I_WITH_DOT = '\u0130'; + private static final char LATIN_SMALL_DOTLESS_I = '\u0131'; + private static final char COMBINING_DOT_ABOVE = '\u0307'; + private static final char GREEK_CAPITAL_SIGMA = '\u03a3'; + private static final char GREEK_SMALL_FINAL_SIGMA = '\u03c2'; + + /** + * Our current GC makes short-lived objects more expensive than we'd like. When that's fixed, + * this class should be changed so that you instantiate it with the String and its value, + * offset, and count fields. + */ + private CaseMapper() { + } + + /** + * Implements String.toLowerCase. We need 's' so that we can return the original String instance + * if nothing changes. We need 'value', 'offset', and 'count' because they're not otherwise + * accessible. + */ + public static String toLowerCase(Locale locale, String s, char[] value, int offset, int count) { + String languageCode = locale.getLanguage(); + boolean turkishOrAzeri = languageCode.equals("tr") || languageCode.equals("az"); + + char[] newValue = null; + int newCount = 0; + for (int i = offset, end = offset + count; i < end; ++i) { + char ch = value[i]; + char newCh = ch; + if (turkishOrAzeri && ch == LATIN_CAPITAL_I_WITH_DOT) { + newCh = LATIN_SMALL_I; + } else if (turkishOrAzeri && ch == LATIN_CAPITAL_I && !followedBy(value, offset, count, i, COMBINING_DOT_ABOVE)) { + newCh = LATIN_SMALL_DOTLESS_I; + } else if (turkishOrAzeri && ch == COMBINING_DOT_ABOVE && precededBy(value, offset, count, i, LATIN_CAPITAL_I)) { + continue; // (We've already converted the preceding I, so we don't need to create newValue.) + } else if (ch == GREEK_CAPITAL_SIGMA && isFinalSigma(value, offset, count, i)) { + newCh = GREEK_SMALL_FINAL_SIGMA; + } else { + newCh = Character.toLowerCase(ch); + } + if (newValue == null && ch != newCh) { + newValue = new char[count]; // The result can't be longer than the input. + newCount = i - offset; + System.arraycopy(value, offset, newValue, 0, newCount); + } + if (newValue != null) { + newValue[newCount++] = newCh; + } + } + return newValue != null ? new String(0, newCount, newValue) : s; + } + + private static boolean followedBy(char[] value, int offset, int count, int index, char ch) { + return index + 1 < offset + count && value[index + 1] == ch; + } + + private static boolean precededBy(char[] value, int offset, int count, int index, char ch) { + return index > offset && value[index - 1] == ch; + } + + /** + * True if 'index' is preceded by a sequence consisting of a cased letter and a case-ignorable + * sequence, and 'index' is not followed by a sequence consisting of an ignorable sequence and + * then a cased letter. + */ + private static boolean isFinalSigma(char[] value, int offset, int count, int index) { + // TODO: we don't skip case-ignorable sequences like we should. + // TODO: we should add a more direct way to test for a cased letter. + if (index <= offset) { + return false; + } + char previous = value[index - 1]; + if (!(Character.isLowerCase(previous) || Character.isUpperCase(previous) || Character.isTitleCase(previous))) { + return false; + } + if (index + 1 >= offset + count) { + return true; + } + char next = value[index + 1]; + if (Character.isLowerCase(next) || Character.isUpperCase(next) || Character.isTitleCase(next)) { + return false; + } + return true; + } +} diff --git a/luni/src/main/java/java/lang/SecurityManager.java b/luni/src/main/java/java/lang/SecurityManager.java index 8a04e92..736d537 100644 --- a/luni/src/main/java/java/lang/SecurityManager.java +++ b/luni/src/main/java/java/lang/SecurityManager.java @@ -41,7 +41,11 @@ import java.util.StringTokenizer; import org.apache.harmony.luni.util.PriviAction; /** - * Provides security verification facilities for applications. {@code + * <strong>Warning:</strong> security managers do <strong>not</strong> provide a + * secure environment for executing untrusted code. Untrusted code cannot be + * safely isolated within the Dalvik VM. + * + * <p>Provides security verification facilities for applications. {@code * SecurityManager} contains a set of {@code checkXXX} methods which determine * if it is safe to perform a specific operation such as establishing network * connections, modifying files, and many more. In general, these methods simply diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java index be9e71f..1556389 100644 --- a/luni/src/main/java/java/lang/String.java +++ b/luni/src/main/java/java/lang/String.java @@ -654,28 +654,6 @@ public final class String implements Serializable, Comparable<String>, return Character.toLowerCase(Character.toUpperCase(ch)); } - // Optimized for ASCII - private char toLowerCase(char ch) { - if (ch < 128) { - if ('A' <= ch && ch <= 'Z') { - return (char) (ch + ('a' - 'A')); - } - return ch; - } - return Character.toLowerCase(ch); - } - - // Optimized for ASCII - private char toUpperCase(char ch) { - if (ch < 128) { - if ('a' <= ch && ch <= 'z') { - return (char) (ch - ('a' - 'A')); - } - return ch; - } - return Character.toUpperCase(ch); - } - /** * Compares the specified string to this string using the Unicode values of * the characters. Returns 0 if the strings contain the same characters in @@ -904,9 +882,9 @@ public final class String implements Serializable, Comparable<String>, char[] target = string.value; while (o1 < end) { if ((c1 = value[o1++]) != (c2 = target[o2++]) - && toUpperCase(c1) != toUpperCase(c2) + && Character.toUpperCase(c1) != Character.toUpperCase(c2) // Required for unicode that we test both cases - && toLowerCase(c1) != toLowerCase(c2)) { + && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { return false; } } @@ -1435,9 +1413,9 @@ public final class String implements Serializable, Comparable<String>, char[] target = string.value; while (thisStart < end) { if ((c1 = value[thisStart++]) != (c2 = target[start++]) - && toUpperCase(c1) != toUpperCase(c2) + && Character.toUpperCase(c1) != Character.toUpperCase(c2) // Required for unicode that we test both cases - && toLowerCase(c1) != toLowerCase(c2)) { + && Character.toLowerCase(c1) != Character.toLowerCase(c2)) { return false; } } @@ -1613,48 +1591,31 @@ public final class String implements Serializable, Comparable<String>, } /** - * Converts the characters in this string to lowercase, using the default - * Locale. + * Converts this string to lowercase, using the rules of the default locale. * - * @return a new string containing the lowercase characters equivalent to - * the characters in this string. + * @return a new lowercase string, or {@code this} if it's already all-lowercase. */ public String toLowerCase() { - return toLowerCase(Locale.getDefault()); + return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count); } /** - * Converts the characters in this string to lowercase, using the specified - * Locale. + * Converts this string to lowercase, using the rules of the specified locale. + * <p> + * Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include + * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in + * Lithuanian locales. On the other hand, it isn't necessary to provide, a Greek locale to get + * correct case mapping of Greek characters: any locale will do. + * <p> + * See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a> + * for full details of context- and language-specific special cases. * * @param locale * the Locale to use. - * @return a new string containing the lowercase characters equivalent to - * the characters in this string. + * @return a new lowercase string, or {@code this} if it's already all-lowercase. */ public String toLowerCase(Locale locale) { - for (int o = offset, end = offset + count; o < end; o++) { - char ch = value[o]; - if (ch != toLowerCase(ch)) { - char[] buffer = new char[count]; - int i = o - offset; - // Not worth checking for i == 0 case - System.arraycopy(value, offset, buffer, 0, i); - // Turkish - if (!"tr".equals(locale.getLanguage())) { //$NON-NLS-1$ - while (i < count) { - buffer[i++] = toLowerCase(value[o++]); - } - } else { - while (i < count) { - buffer[i++] = (ch = value[o++]) != 0x49 ? toLowerCase(ch) - : (char) 0x131; - } - } - return new String(0, count, buffer); - } - } - return this; + return CaseMapper.toLowerCase(locale, this, value, offset, count); } /** @@ -1751,7 +1712,10 @@ public final class String implements Serializable, Comparable<String>, * the characters in this string. */ public String toUpperCase(Locale locale) { - boolean turkish = "tr".equals(locale.getLanguage()); //$NON-NLS-1$ + // BEGIN android-changed: support Azeri. + String languageCode = locale.getLanguage(); + boolean turkishOrAzeri = languageCode.equals("tr") || languageCode.equals("az"); + char[] output = null; int i = 0; for (int o = offset, end = offset + count; o < end; o++) { @@ -1763,15 +1727,14 @@ public final class String implements Serializable, Comparable<String>, System.arraycopy(output, 0, newoutput, 0, output.length); output = newoutput; } - char upch = !turkish ? toUpperCase(ch) - : (ch != 0x69 ? toUpperCase(ch) + char upch = !turkishOrAzeri ? Character.toUpperCase(ch) + : (ch != 0x69 ? Character.toUpperCase(ch) : (char) 0x130); if (ch != upch) { if (output == null) { output = new char[count]; i = o - offset; System.arraycopy(value, offset, output, 0, i); - } output[i++] = upch; } else if (output != null) { @@ -1804,6 +1767,7 @@ public final class String implements Serializable, Comparable<String>, } return output.length == i || output.length - i < 8 ? new String(0, i, output) : new String(output, 0, i); + // END android-changed } /** @@ -2287,7 +2251,7 @@ public final class String implements Serializable, Comparable<String>, * substantially better than the default algorithm if the "needle" (the * subString being searched for) is a constant string. * - * For example, a JIT, upon encoutering a call to String.indexOf(String), + * For example, a JIT, upon encountering a call to String.indexOf(String), * where the needle is a constant string, may compute the values cache, md2 * and lastChar, and change the call to the following method. */ @@ -2325,11 +2289,4 @@ public final class String implements Serializable, Comparable<String>, } return -1; } - - /* - * Returns the character array for this string. - */ - char[] getValue() { - return value; - } } diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java index 0b92a87..1114786 100644 --- a/luni/src/main/java/java/util/Formatter.java +++ b/luni/src/main/java/java/util/Formatter.java @@ -905,29 +905,27 @@ public final class Formatter implements Closeable, Flushable { transformer = new Transformer(this, locale); } - FormatSpecifierParser fsp = new FormatSpecifierParser(); + FormatSpecifierParser fsp = new FormatSpecifierParser(format); int currentObjectIndex = 0; Object lastArgument = null; boolean hasLastArgumentSet = false; - char[] chars = format.toCharArray(); - int length = chars.length; + int length = format.length(); int i = 0; while (i < length) { // Find the maximal plain-text sequence... int plainTextStart = i; - while (i < length && chars[i] != '%') { - ++i; - } + int nextPercent = format.indexOf('%', i); + int plainTextEnd = (nextPercent == -1) ? length : nextPercent; // ...and output it. - int plainTextEnd = i; if (plainTextEnd > plainTextStart) { outputCharSequence(format, plainTextStart, plainTextEnd); } + i = plainTextEnd; // Do we have a format specifier? if (i < length) { - FormatToken token = fsp.parseFormatToken(chars, i + 1); + FormatToken token = fsp.parseFormatToken(i + 1); Object argument = null; if (token.requireArgument()) { @@ -1029,10 +1027,15 @@ public final class Formatter implements Closeable, Flushable { private StringBuilder strFlags; - private char dateSuffix;// will be used in new feature. + private char dateSuffix; private char conversionType = (char) UNSET; + // Tests whether there were no flags, no width, and no precision specified. + boolean isDefault() { + return flags == 0 && width == UNSET && precision == UNSET; + } + boolean isPrecisionSet() { return precision != UNSET; } @@ -1202,11 +1205,30 @@ public final class Formatter implements Closeable, Flushable { * argument. */ CharSequence transform(FormatToken token, Object argument) { - - /* init data member to print */ this.formatToken = token; this.arg = argument; + // There are only two format specifiers that matter: "%d" and "%s". + // Nothing else is common in the wild. We fast-path these two to + // avoid the heavyweight machinery needed to cope with flags, width, + // and precision. + if (token.isDefault()) { + switch (token.getConversionType()) { + case 's': + if (!(arg instanceof Formattable)) { + return arg.toString(); + } + break; + case 'd': + if (arg instanceof Integer || arg instanceof Long || arg instanceof Short || arg instanceof Byte) { + // TODO: when we fix the rest of formatter to correctly use locale-specific + // digits when getDecimalFormatSymbols().getZeroDigit() != '0', we'll need + // to add a special case here too. + return arg.toString(); + } + } + } + CharSequence result; switch (token.getConversionType()) { case 'B': @@ -1270,7 +1292,7 @@ public final class Formatter implements Closeable, Flushable { } if (Character.isUpperCase(token.getConversionType())) { - if (null != result) { + if (result != null) { result = result.toString().toUpperCase(locale); } } @@ -2573,16 +2595,25 @@ public final class Formatter implements Closeable, Flushable { } private static class FormatSpecifierParser { - private char[] chars; + private String format; + private int length; + private int startIndex; private int i; /** - * Returns a FormatToken representing the format specifier starting at 'offset' in 'chars'. + * Constructs a new parser for the given format string. + */ + FormatSpecifierParser(String format) { + this.format = format; + this.length = format.length(); + } + + /** + * Returns a FormatToken representing the format specifier starting at 'offset'. * @param offset the first character after the '%' */ - FormatToken parseFormatToken(char[] chars, int offset) { - this.chars = chars; + FormatToken parseFormatToken(int offset) { this.startIndex = offset; this.i = offset; return parseArgumentIndexAndFlags(new FormatToken()); @@ -2593,18 +2624,18 @@ public final class Formatter implements Closeable, Flushable { * Used to construct error messages. */ String getFormatSpecifierText() { - return new String(chars, startIndex, i - startIndex); + return format.substring(startIndex, i); } private int peek() { - return (i < chars.length) ? chars[i] : -1; + return (i < length) ? format.charAt(i) : -1; } private char advance() { - if (i >= chars.length) { + if (i >= length) { throw new UnknownFormatConversionException(getFormatSpecifierText()); } - return chars[i++]; + return format.charAt(i++); } private FormatToken parseArgumentIndexAndFlags(FormatToken token) { @@ -2677,20 +2708,20 @@ public final class Formatter implements Closeable, Flushable { } private FormatToken parseConversionType(FormatToken token) { - char ch = advance(); // This is mandatory, so no need to peek. - token.setConversionType(ch); - if (ch == 't' || ch == 'T') { - token.setDateSuffix(advance()); + char conversionType = advance(); // A conversion type is mandatory. + token.setConversionType(conversionType); + if (conversionType == 't' || conversionType == 'T') { + char dateSuffix = advance(); // A date suffix is mandatory for 't' or 'T'. + token.setDateSuffix(dateSuffix); } return token; } // Parses an integer (of arbitrary length, but typically just one digit). private int nextInt() { - int length = chars.length; long value = 0; - while (i < length && Character.isDigit(chars[i])) { - value = 10 * value + (chars[i++] - '0'); + while (i < length && Character.isDigit(format.charAt(i))) { + value = 10 * value + (format.charAt(i++) - '0'); if (value > Integer.MAX_VALUE) { return failNextInt(); } diff --git a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java index a082b47..b078727 100644 --- a/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java +++ b/luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java @@ -1403,11 +1403,11 @@ public class HttpURLConnectionImpl extends HttpURLConnection { } output.append("\r\n"); //$NON-NLS-1$ } - if (reqHeader.get("Accept") == null) { //$NON-NLS-1$ - // BEGIN android-changed - output.append("Accept: *, */*\r\n"); //$NON-NLS-1$ - // END android-changed - } + // BEGIN android-removed + // there's no utility in sending an "accept everything" header "*/*" + // if (reqHeader.get("Accept") == null) { //$NON-NLS-1$ + // } + // END android-removed if (httpVersion > 0 && reqHeader.get("Connection") == null) { //$NON-NLS-1$ output.append("Connection: Keep-Alive\r\n"); //$NON-NLS-1$ } diff --git a/luni/src/test/java/java/text/AllTests.java b/luni/src/test/java/java/text/AllTests.java new file mode 100644 index 0000000..9d13a1a --- /dev/null +++ b/luni/src/test/java/java/text/AllTests.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2010 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 java.text; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class AllTests { + public static final Test suite() { + TestSuite suite = tests.TestSuiteFactory.createTestSuite(); + suite.addTestSuite(java.text.NumberFormatTest.class); + return suite; + } +} diff --git a/luni/src/test/java/java/text/NumberFormatTest.java b/luni/src/test/java/java/text/NumberFormatTest.java new file mode 100644 index 0000000..3626a44 --- /dev/null +++ b/luni/src/test/java/java/text/NumberFormatTest.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 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 java.text; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.util.Locale; + +public class NumberFormatTest extends junit.framework.TestCase { + public void test_getIntegerInstance_ar() throws Exception { + NumberFormat numberFormat = NumberFormat.getNumberInstance(new Locale("ar")); + assertEquals("#,##0.###;#,##0.###-", ((DecimalFormat) numberFormat).toPattern()); + NumberFormat integerFormat = NumberFormat.getIntegerInstance(new Locale("ar")); + assertEquals("#,##0;#,##0-", ((DecimalFormat) integerFormat).toPattern()); + } +} diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java index 68ccb91..a74bf35 100644 --- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java +++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java @@ -474,7 +474,7 @@ public class URLConnectionTest extends TestCase { // validate the request by asking the server what was received Map<String, String> headers = server.pathToRequest().get(path).getHeaders(); - assertEquals("*, */*", headers.get("Accept")); + assertNull(headers.get("Accept")); assertEquals("application/x-www-form-urlencoded", headers.get("Content-Type")); assertEquals("5", headers.get("Content-Length")); assertEquals("localhost:" + port, headers.get("Host")); diff --git a/luni/src/test/java/tests/AllTests.java b/luni/src/test/java/tests/AllTests.java index bd969f2..950156e 100644 --- a/luni/src/test/java/tests/AllTests.java +++ b/luni/src/test/java/tests/AllTests.java @@ -62,6 +62,7 @@ public class AllTests suite.addTest(java.lang.reflect.AllTests.suite()); suite.addTest(java.net.AllTests.suite()); suite.addTest(java.nio.charset.AllTests.suite()); + suite.addTest(java.text.AllTests.suite()); suite.addTest(java.util.AllTests.suite()); suite.addTest(javax.xml.parsers.AllTests.suite()); suite.addTest(org.apache.harmony.luni.platform.AllTests.suite()); diff --git a/luni/src/test/java/tests/api/java/util/ScannerTest.java b/luni/src/test/java/tests/api/java/util/ScannerTest.java index 6e7f1d4..bd13383 100644 --- a/luni/src/test/java/tests/api/java/util/ScannerTest.java +++ b/luni/src/test/java/tests/api/java/util/ScannerTest.java @@ -58,7 +58,7 @@ import junit.framework.TestCase; @TestTargetClass(Scanner.class) public class ScannerTest extends TestCase { - static final boolean disableRIBugs = true; + static final boolean disableRIBugs = false; private Scanner s; @@ -1290,34 +1290,37 @@ public class ScannerTest extends TestCase { // expected } - s = new Scanner("-123 123- (123)"); - s.useLocale(new Locale("mk", "MK")); - assertEquals(-123, s.nextInt(10)); - try { - s.nextInt(); - fail("Should throw InputMismatchException"); - } catch (InputMismatchException e) { - // expected - } - // Skip the un-recognizable token 123-. - assertEquals("123-", s.next()); - // The following test case fails on RI - if (!disableRIBugs) { + // locale dependent test, bug 1943269 + if (Support_Locale.areLocalesAvailable(new Locale[] { new Locale("mk", "MK")})) { + s = new Scanner("-123 123- (123)"); + s.useLocale(new Locale("mk", "MK")); assertEquals(-123, s.nextInt(10)); - - // If the parameter radix is illegal, the following test cases fail on - // RI try { - s.nextInt(Character.MIN_RADIX - 1); - fail("Should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected + s.nextInt(); + fail("Should throw InputMismatchException"); + } catch (InputMismatchException e) { + // expected } - try { - s.nextInt(Character.MAX_RADIX + 1); - fail("Should throw IllegalArgumentException"); - } catch (IllegalArgumentException e) { - // Expected + // Skip the un-recognizable token 123-. + assertEquals("123-", s.next()); + // The following test case fails on RI + if (!disableRIBugs) { + assertEquals(-123, s.nextInt(10)); + + // If the parameter radix is illegal, the following test cases fail on + // RI + try { + s.nextInt(Character.MIN_RADIX - 1); + fail("Should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected + } + try { + s.nextInt(Character.MAX_RADIX + 1); + fail("Should throw IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected + } } } @@ -1515,20 +1518,23 @@ public class ScannerTest extends TestCase { // expected } - s = new Scanner("-123 123- (123)"); - s.useLocale(new Locale("mk", "MK")); - assertEquals(-123, s.nextInt()); - try { - s.nextInt(); - fail("Should throw InputMismatchException"); - } catch (InputMismatchException e) { - // expected - } - // Skip the un-recognizable token 123-. - assertEquals("123-", s.next()); - // The following test case fails on RI - if (!disableRIBugs) { + // locale dependent test, bug 1943269 + if (Support_Locale.areLocalesAvailable(new Locale[] { new Locale("mk", "MK")})) { + s = new Scanner("-123 123- (123)"); + s.useLocale(new Locale("mk", "MK")); assertEquals(-123, s.nextInt()); + try { + s.nextInt(); + fail("Should throw InputMismatchException"); + } catch (InputMismatchException e) { + // expected + } + // Skip the un-recognizable token 123-. + assertEquals("123-", s.next()); + // The following test case fails on RI + if (!disableRIBugs) { + assertEquals(-123, s.nextInt()); + } } s.close(); @@ -1808,35 +1814,43 @@ public class ScannerTest extends TestCase { s.useLocale(Locale.GERMANY); assertEquals((float)23456.7, s.nextFloat()); - s = new Scanner("-123.4 123.4- -123.4-"); - s.useLocale(new Locale("ar", "AE")); - assertEquals((float)-123.4, s.nextFloat()); - //The following test case fails on RI - if (!disableRIBugs) { + // locale dependent test, bug 1943269 + // Note: although "123.4-" is the correct localized form for ar_AE, the + // RI only accepts "-123.4". + if (false) { + s = new Scanner("-123.4 123.4- -123.4-"); + s.useLocale(new Locale("ar", "AE")); assertEquals((float)-123.4, s.nextFloat()); - } - try { - s.nextFloat(); - fail("Should throw InputMismatchException"); - } catch (InputMismatchException e) { - // Expected + //The following test case fails on RI + if (!disableRIBugs) { + assertEquals((float)-123.4, s.nextFloat()); + } + try { + s.nextFloat(); + fail("Should throw InputMismatchException"); + } catch (InputMismatchException e) { + // Expected + } } - s = new Scanner("(123) 123- -123"); - s.useLocale(new Locale("mk", "MK")); - if (!disableRIBugs) { - assertEquals((float)-123.0, s.nextFloat()); - } - try { - s.nextFloat(); - fail("Should throw InputMismatchException"); - } catch (InputMismatchException e) { - // Expected - } - // Skip the un-recognizable token 123-. - if (!disableRIBugs) { - assertEquals("123-", s.next()); - assertEquals((float)-123.0, s.nextFloat()); + // locale dependent test, bug 1943269 + if (Support_Locale.areLocalesAvailable(new Locale[] { new Locale("mk", "MK") })) { + s = new Scanner("(123) 123- -123"); + s.useLocale(new Locale("mk", "MK")); + if (!disableRIBugs) { + assertEquals((float)-123.0, s.nextFloat()); + } + try { + s.nextFloat(); + fail("Should throw InputMismatchException"); + } catch (InputMismatchException e) { + // Expected + } + // Skip the un-recognizable token 123-. + if (!disableRIBugs) { + assertEquals("123-", s.next()); + assertEquals((float)-123.0, s.nextFloat()); + } } s.close(); diff --git a/support/src/test/java/tests/support/Support_TestWebServer.java b/support/src/test/java/tests/support/Support_TestWebServer.java index b7e8b38..7d20237 100644 --- a/support/src/test/java/tests/support/Support_TestWebServer.java +++ b/support/src/test/java/tests/support/Support_TestWebServer.java @@ -561,7 +561,7 @@ public class Support_TestWebServer implements Support_HttpConstants { while (buf[i] == ' ') { i++; } - String headerValue = new String(buf, i, nread-i); + String headerValue = new String(buf, i, nread - i - 2); // drop \r\n headers.put(headerName, headerValue); return nread; diff --git a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java index 2bd9260..ef70bf2 100644 --- a/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java +++ b/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java @@ -2467,6 +2467,11 @@ public class DecimalFormatTest extends TestCase { args = {} ) public void test_serializationHarmonyRICompatible() throws Exception { + Locale[] requiredLocales = {Locale.FRANCE}; + if (!Support_Locale.areLocalesAvailable(requiredLocales)) { + // locale dependent test, bug 1943269 + return; + } NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE); DecimalFormat df = null; diff --git a/tools/runner/java/dalvik/runner/Driver.java b/tools/runner/java/dalvik/runner/Driver.java index cf29d9c..78ab3dd 100644 --- a/tools/runner/java/dalvik/runner/Driver.java +++ b/tools/runner/java/dalvik/runner/Driver.java @@ -208,6 +208,8 @@ final class Driver { private void printResult(TestRun testRun) { if (testRun.isExpectedResult()) { logger.info("OK " + testRun.getQualifiedName() + " (" + testRun.getResult() + ")"); + // In --verbose mode, show the output even on success. + logger.fine(" " + testRun.getFailureMessage().replace("\n", "\n ")); return; } diff --git a/tools/runner/java/dalvik/runner/Dx.java b/tools/runner/java/dalvik/runner/Dx.java index 83f1265..d36a99d 100644 --- a/tools/runner/java/dalvik/runner/Dx.java +++ b/tools/runner/java/dalvik/runner/Dx.java @@ -22,8 +22,13 @@ package dalvik.runner; final class Dx { public void dex(String output, Classpath classpath) { + // We pass --core-library so that we can write tests in the same package they're testing, + // even when that's a core library package. If you're actually just using this tool to + // execute arbitrary code, this has the unfortunate side-effect of preventing "dx" from + // protecting you from yourself. new Command.Builder() .args("dx") + .args("--core-library") .args("--dex") .args("--output=" + output) .args(Strings.objectsToStrings(classpath.getElements())) diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java index b488a0e..34252f0 100644 --- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java +++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java @@ -88,6 +88,7 @@ public class ClientHandshakeImpl extends HandshakeProtocol { } else if (parameters.getEnableSessionCreation()){ isResuming = false; session = new SSLSessionImpl(parameters.getSecureRandom()); + session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort()); session.protocol = ProtocolVersion.getLatestVersion(parameters .getEnabledProtocols()); recordProtocol.setVersion(session.protocol.version); @@ -105,6 +106,7 @@ public class ClientHandshakeImpl extends HandshakeProtocol { if (parameters.getEnableSessionCreation()){ isResuming = false; session = new SSLSessionImpl(parameters.getSecureRandom()); + session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort()); session.protocol = ProtocolVersion.getLatestVersion(parameters .getEnabledProtocols()); recordProtocol.setVersion(session.protocol.version); @@ -625,4 +627,3 @@ public class ClientHandshakeImpl extends HandshakeProtocol { } } - diff --git a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java index 3bb096b..782bb39 100644 --- a/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java +++ b/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java @@ -428,8 +428,8 @@ public class ServerHandshakeImpl extends HandshakeProtocol { fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created"); } - session = new SSLSessionImpl(cipher_suite, parameters - .getSecureRandom()); + session = new SSLSessionImpl(cipher_suite, parameters.getSecureRandom()); + session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort()); } recordProtocol.setVersion(clientHello.client_version); |