summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--icu/src/main/java/com/ibm/icu4jni/util/Resources.java9
-rw-r--r--luni-kernel/src/main/java/java/lang/System.java10
-rw-r--r--luni/src/main/java/java/lang/CaseMapper.java111
-rw-r--r--luni/src/main/java/java/lang/SecurityManager.java6
-rw-r--r--luni/src/main/java/java/lang/String.java95
-rw-r--r--luni/src/main/java/java/util/Formatter.java85
-rw-r--r--luni/src/main/java/org/apache/harmony/luni/internal/net/www/protocol/http/HttpURLConnectionImpl.java10
-rw-r--r--luni/src/test/java/java/text/AllTests.java28
-rw-r--r--luni/src/test/java/java/text/NumberFormatTest.java31
-rw-r--r--luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java2
-rw-r--r--luni/src/test/java/tests/AllTests.java1
-rw-r--r--luni/src/test/java/tests/api/java/util/ScannerTest.java144
-rw-r--r--support/src/test/java/tests/support/Support_TestWebServer.java2
-rw-r--r--text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatTest.java5
-rw-r--r--tools/runner/java/dalvik/runner/Driver.java2
-rw-r--r--tools/runner/java/dalvik/runner/Dx.java5
-rw-r--r--x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java3
-rw-r--r--x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java4
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);