diff options
82 files changed, 1328 insertions, 1696 deletions
diff --git a/dalvik/src/main/java/dalvik/system/CloseGuard.java b/dalvik/src/main/java/dalvik/system/CloseGuard.java index 136be2f930..df368674c7 100644 --- a/dalvik/src/main/java/dalvik/system/CloseGuard.java +++ b/dalvik/src/main/java/dalvik/system/CloseGuard.java @@ -197,7 +197,7 @@ public final class CloseGuard { /** * If CloseGuard is enabled, logs a warning if the caller did not * properly cleanup by calling an explicit close method - * before finalization. If CloseGuard is disable, no action is + * before finalization. If CloseGuard is disabled, no action is * performed. */ public void warnIfOpen() { @@ -223,7 +223,7 @@ public final class CloseGuard { * Default Reporter which reports CloseGuard violations to the log. */ private static final class DefaultReporter implements Reporter { - public void report (String message, Throwable allocationSite) { + @Override public void report (String message, Throwable allocationSite) { System.logW(message, allocationSite); } } diff --git a/dalvik/src/main/java/dalvik/system/Zygote.java b/dalvik/src/main/java/dalvik/system/Zygote.java index 28c99127a0..ec114ed623 100644 --- a/dalvik/src/main/java/dalvik/system/Zygote.java +++ b/dalvik/src/main/java/dalvik/system/Zygote.java @@ -107,20 +107,23 @@ public class Zygote { * dimension having a length of 3 and representing * (resource, rlim_cur, rlim_max). These are set via the posix * setrlimit(2) call. + * @param seInfo null-ok a string specifying SEAndroid information for + * the new process. + * @param niceName null-ok a string specifying the process name. * * @return 0 if this is the child, pid of the child * if this is the parent, or -1 on error. */ public static int forkAndSpecialize(int uid, int gid, int[] gids, - int debugFlags, int[][] rlimits) { + int debugFlags, int[][] rlimits, String seInfo, String niceName) { preFork(); - int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits); + int pid = nativeForkAndSpecialize(uid, gid, gids, debugFlags, rlimits, seInfo, niceName); postFork(); return pid; } native public static int nativeForkAndSpecialize(int uid, int gid, - int[] gids, int debugFlags, int[][] rlimits); + int[] gids, int debugFlags, int[][] rlimits, String seInfo, String niceName); /** * Forks a new VM instance. @@ -130,7 +133,7 @@ public class Zygote { public static int forkAndSpecialize(int uid, int gid, int[] gids, boolean enableDebugger, int[][] rlimits) { int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0; - return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits); + return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits, null, null); } /** @@ -175,7 +178,7 @@ public class Zygote { public static int forkSystemServer(int uid, int gid, int[] gids, boolean enableDebugger, int[][] rlimits) { int debugFlags = enableDebugger ? DEBUG_ENABLE_DEBUGGER : 0; - return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits); + return forkAndSpecialize(uid, gid, gids, debugFlags, rlimits, null, null); } native public static int nativeForkSystemServer(int uid, int gid, diff --git a/luni/src/main/java/java/io/File.java b/luni/src/main/java/java/io/File.java index 968f0218e7..ac67e7c5b8 100644 --- a/luni/src/main/java/java/io/File.java +++ b/luni/src/main/java/java/io/File.java @@ -855,57 +855,65 @@ public class File implements Serializable, Comparable<File> { } /** - * Creates the directory named by the trailing filename of this file. Does - * not create the complete path required to create this directory. + * Creates the directory named by this file, assuming its parents exist. + * Use {@link #mkdirs} if you also want to create missing parents. * * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. - * Callers must check the return value. + * Callers must check the return value. Note also that this method returns + * false if the directory already existed. If you want to know whether the + * directory exists on return, either use {@code (f.mkdir() || f.isDirectory())} + * or simply ignore the return value from this method and simply call {@link #isDirectory}. * - * @return {@code true} if the directory has been created, {@code false} - * otherwise. - * @see #mkdirs + * @return {@code true} if the directory was created, + * {@code false} on failure or if the directory already existed. */ public boolean mkdir() { try { - // On Android, we don't want default permissions to allow global access. - Libcore.os.mkdir(path, S_IRWXU); + mkdirErrno(); return true; } catch (ErrnoException errnoException) { return false; } } + private void mkdirErrno() throws ErrnoException { + // On Android, we don't want default permissions to allow global access. + Libcore.os.mkdir(path, S_IRWXU); + } + /** - * Creates the directory named by the trailing filename of this file, - * including the complete directory path required to create this directory. + * Creates the directory named by this file, creating missing parent + * directories if necessary. + * Use {@link #mkdir} if you don't want to create missing parents. * * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. - * Callers must check the return value. + * Callers must check the return value. Note also that this method returns + * false if the directory already existed. If you want to know whether the + * directory exists on return, either use {@code (f.mkdirs() || f.isDirectory())} + * or simply ignore the return value from this method and simply call {@link #isDirectory}. * - * @return {@code true} if the necessary directories have been created, - * {@code false} if the target directory already exists or one of - * the directories can not be created. - * @see #mkdir + * @return {@code true} if the directory was created, + * {@code false} on failure or if the directory already existed. */ public boolean mkdirs() { - /* If the terminal directory already exists, answer false */ - if (exists()) { - return false; - } + return mkdirs(false); + } - /* If the receiver can be created, answer true */ - if (mkdir()) { + private boolean mkdirs(boolean resultIfExists) { + try { + // Try to create the directory directly. + mkdirErrno(); return true; - } - - String parentDir = getParent(); - /* If there is no parent and we were not created, answer false */ - if (parentDir == null) { + } catch (ErrnoException errnoException) { + if (errnoException.errno == ENOENT) { + // If the parent was missing, try to create it and then try again. + File parent = getParentFile(); + return parent != null && parent.mkdirs(true) && mkdir(); + } else if (errnoException.errno == EEXIST) { + return resultIfExists; + } return false; } - - /* Otherwise, try to create a parent directory and then this directory */ - return (new File(parentDir).mkdirs() && mkdir()); } /** diff --git a/luni/src/main/java/java/io/ObjectInputStream.java b/luni/src/main/java/java/io/ObjectInputStream.java index 4541f1b9ae..449204fec6 100644 --- a/luni/src/main/java/java/io/ObjectInputStream.java +++ b/luni/src/main/java/java/io/ObjectInputStream.java @@ -23,6 +23,7 @@ import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.security.PrivilegedAction; import java.util.ArrayList; @@ -1089,8 +1090,11 @@ public class ObjectInputStream extends InputStream implements ObjectInput, Objec for (ObjectStreamField fieldDesc : fields) { Field field = classDesc.getReflectionField(fieldDesc); - // We may not have been able to find the field, but we still need to read the value - // and do the other checking, so there's no null check on 'field' here. + if (field != null && Modifier.isTransient(field.getModifiers())) { + field = null; // No setting transient fields! (http://b/4471249) + } + // We may not have been able to find the field, or it may be transient, but we still + // need to read the value and do the other checking... try { Class<?> type = fieldDesc.getTypeInternal(); if (type == byte.class) { diff --git a/luni/src/main/java/java/io/ObjectStreamClass.java b/luni/src/main/java/java/io/ObjectStreamClass.java index e87fcd4851..a28489adb4 100644 --- a/luni/src/main/java/java/io/ObjectStreamClass.java +++ b/luni/src/main/java/java/io/ObjectStreamClass.java @@ -481,16 +481,14 @@ public class ObjectStreamClass implements Serializable { Field field = fields[i]; int modifiers = field.getModifiers() & FIELD_MODIFIERS_MASK; - boolean skip = Modifier.isPrivate(modifiers) - && (Modifier.isTransient(modifiers) || Modifier - .isStatic(modifiers)); + boolean skip = Modifier.isPrivate(modifiers) && + (Modifier.isTransient(modifiers) || Modifier.isStatic(modifiers)); if (!skip) { // write name, modifier & "descriptor" of all but private // static and private transient output.writeUTF(field.getName()); output.writeInt(modifiers); - output - .writeUTF(descriptorForFieldSignature(getFieldSignature(field))); + output.writeUTF(descriptorForFieldSignature(getFieldSignature(field))); } } diff --git a/luni/src/main/java/java/lang/String.java b/luni/src/main/java/java/lang/String.java index efd4210087..224a268c97 100644 --- a/luni/src/main/java/java/lang/String.java +++ b/luni/src/main/java/java/lang/String.java @@ -168,17 +168,7 @@ public final class String implements Serializable, Comparable<String>, CharSeque * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. */ public String(byte[] data, int offset, int byteCount) { - if ((offset | byteCount) < 0 || byteCount > data.length - offset) { - throw failedBoundsCheck(data.length, offset, byteCount); - } - CharBuffer cb = Charset.defaultCharset().decode(ByteBuffer.wrap(data, offset, byteCount)); - this.count = cb.length(); - this.offset = 0; - if (count > 0) { - value = cb.array(); - } else { - value = EmptyArray.CHAR; - } + this(data, offset, byteCount, Charset.defaultCharset()); } /** diff --git a/luni/src/main/java/java/lang/System.java b/luni/src/main/java/java/lang/System.java index 24ebf6bde1..de99161cf7 100644 --- a/luni/src/main/java/java/lang/System.java +++ b/luni/src/main/java/java/lang/System.java @@ -34,6 +34,7 @@ package java.lang; import dalvik.system.VMRuntime; import dalvik.system.VMStack; +import java.io.BufferedInputStream; import java.io.Console; import java.io.FileDescriptor; import java.io.FileInputStream; @@ -83,10 +84,9 @@ public final class System { private static Properties systemProperties; static { - // TODO: all three streams are buffered in Harmony. err = new PrintStream(new FileOutputStream(FileDescriptor.err)); out = new PrintStream(new FileOutputStream(FileDescriptor.out)); - in = new FileInputStream(FileDescriptor.in); + in = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); lineSeparator = System.getProperty("line.separator"); } diff --git a/luni/src/main/java/java/net/NetworkInterface.java b/luni/src/main/java/java/net/NetworkInterface.java index e06b811c79..ad81f32da0 100644 --- a/luni/src/main/java/java/net/NetworkInterface.java +++ b/luni/src/main/java/java/net/NetworkInterface.java @@ -122,7 +122,9 @@ public final class NetworkInterface extends Object { private static void collectIpv6Addresses(String interfaceName, int interfaceIndex, List<InetAddress> addresses, List<InterfaceAddress> interfaceAddresses) throws SocketException { - // Format of /proc/net/if_inet6 (all numeric fields are implicit hex). + // Format of /proc/net/if_inet6. + // All numeric fields are implicit hex, + // but not necessarily two-digit (http://code.google.com/p/android/issues/detail?id=34022). // 1. IPv6 address // 2. interface index // 3. prefix length @@ -130,6 +132,7 @@ public final class NetworkInterface extends Object { // 5. flags // 6. interface name // "00000000000000000000000000000001 01 80 10 80 lo" + // "fe800000000000000000000000000000 407 40 20 80 wlan0" BufferedReader in = null; try { in = new BufferedReader(new FileReader("/proc/net/if_inet6")); @@ -139,13 +142,22 @@ public final class NetworkInterface extends Object { if (!line.endsWith(suffix)) { continue; } + + // Extract the IPv6 address. byte[] addressBytes = new byte[16]; for (int i = 0; i < addressBytes.length; ++i) { addressBytes[i] = (byte) Integer.parseInt(line.substring(2*i, 2*i + 2), 16); } - short prefixLength = Short.parseShort(line.substring(36, 38), 16); - Inet6Address inet6Address = new Inet6Address(addressBytes, null, interfaceIndex); + // Extract the prefix length. + // Skip the IPv6 address and its trailing space. + int prefixLengthStart = 32 + 1; + // Skip the interface index and its trailing space. + prefixLengthStart = line.indexOf(' ', prefixLengthStart) + 1; + int prefixLengthEnd = line.indexOf(' ', prefixLengthStart); + short prefixLength = Short.parseShort(line.substring(prefixLengthStart, prefixLengthEnd), 16); + + Inet6Address inet6Address = new Inet6Address(addressBytes, null, interfaceIndex); addresses.add(inet6Address); interfaceAddresses.add(new InterfaceAddress(inet6Address, prefixLength)); } diff --git a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java index 5d014692b1..32265276e4 100644 --- a/luni/src/main/java/java/net/PlainDatagramSocketImpl.java +++ b/luni/src/main/java/java/net/PlainDatagramSocketImpl.java @@ -216,6 +216,8 @@ public class PlainDatagramSocketImpl extends DatagramSocketImpl { Libcore.os.connect(fd, InetAddress.UNSPECIFIED, 0); } catch (ErrnoException errnoException) { throw new AssertionError(errnoException); + } catch (SocketException ignored) { + // Thrown if the socket has already been closed, but this method can't throw anything. } connectedPort = -1; connectedAddress = null; diff --git a/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java b/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java index 3ad46d7930..8b32efa975 100644 --- a/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java +++ b/luni/src/main/java/java/nio/charset/CharsetDecoderICU.java @@ -16,7 +16,7 @@ package java.nio.charset; import java.nio.ByteBuffer; import java.nio.CharBuffer; -import libcore.icu.ErrorCode; +import libcore.icu.ICU; import libcore.icu.NativeConverter; import libcore.util.EmptyArray; @@ -46,7 +46,6 @@ final class CharsetDecoderICU extends CharsetDecoder { // is inherently thread-unsafe so we don't have to worry about synchronization. private int inEnd; private int outEnd; - private int ec; public static CharsetDecoderICU newInstance(Charset cs, String icuCanonicalName) { // This complexity is necessary to ensure that even if the constructor, superclass @@ -84,10 +83,7 @@ final class CharsetDecoderICU extends CharsetDecoder { } private void updateCallback() { - ec = NativeConverter.setCallbackDecode(converterHandle, this); - if (ErrorCode.isFailure(ec)) { - throw ErrorCode.throwException(ec); - } + NativeConverter.setCallbackDecode(converterHandle, this); } @Override protected void implReset() { @@ -99,7 +95,6 @@ final class CharsetDecoderICU extends CharsetDecoder { input = null; allocatedInput = null; allocatedOutput = null; - ec = 0; inEnd = 0; outEnd = 0; } @@ -114,16 +109,14 @@ final class CharsetDecoderICU extends CharsetDecoder { data[OUTPUT_OFFSET] = getArray(out); data[INVALID_BYTES] = 0; // Make sure we don't see earlier errors. - ec = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, true); - if (ErrorCode.isFailure(ec)) { - if (ec == ErrorCode.U_BUFFER_OVERFLOW_ERROR) { + int error = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, true); + if (ICU.U_FAILURE(error)) { + if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { return CoderResult.OVERFLOW; - } else if (ec == ErrorCode.U_TRUNCATED_CHAR_FOUND) { + } else if (error == ICU.U_TRUNCATED_CHAR_FOUND) { if (data[INPUT_OFFSET] > 0) { return CoderResult.malformedForLength(data[INPUT_OFFSET]); } - } else { - throw ErrorCode.throwException(ec); } } return CoderResult.UNDERFLOW; @@ -142,13 +135,17 @@ final class CharsetDecoderICU extends CharsetDecoder { data[OUTPUT_OFFSET]= getArray(out); try { - ec = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, false); - if (ec == ErrorCode.U_BUFFER_OVERFLOW_ERROR) { - return CoderResult.OVERFLOW; - } else if (ec == ErrorCode.U_INVALID_CHAR_FOUND) { - return CoderResult.unmappableForLength(data[INVALID_BYTES]); - } else if (ec == ErrorCode.U_ILLEGAL_CHAR_FOUND) { - return CoderResult.malformedForLength(data[INVALID_BYTES]); + int error = NativeConverter.decode(converterHandle, input, inEnd, output, outEnd, data, false); + if (ICU.U_FAILURE(error)) { + if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { + return CoderResult.OVERFLOW; + } else if (error == ICU.U_INVALID_CHAR_FOUND) { + return CoderResult.unmappableForLength(data[INVALID_BYTES]); + } else if (error == ICU.U_ILLEGAL_CHAR_FOUND) { + return CoderResult.malformedForLength(data[INVALID_BYTES]); + } else { + throw new AssertionError(error); + } } // Decoding succeeded: give us more data. return CoderResult.UNDERFLOW; diff --git a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java index cf071ca2dc..76807b00c2 100644 --- a/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java +++ b/luni/src/main/java/java/nio/charset/CharsetEncoderICU.java @@ -18,7 +18,7 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.HashMap; import java.util.Map; -import libcore.icu.ErrorCode; +import libcore.icu.ICU; import libcore.icu.NativeConverter; import libcore.util.EmptyArray; @@ -61,7 +61,6 @@ final class CharsetEncoderICU extends CharsetEncoder { // is inherently thread-unsafe so we don't have to worry about synchronization. private int inEnd; private int outEnd; - private int ec; public static CharsetEncoderICU newInstance(Charset cs, String icuCanonicalName) { // This complexity is necessary to ensure that even if the constructor, superclass @@ -112,10 +111,7 @@ final class CharsetEncoderICU extends CharsetEncoder { } private void updateCallback() { - ec = NativeConverter.setCallbackEncode(converterHandle, this); - if (ErrorCode.isFailure(ec)) { - throw ErrorCode.throwException(ec); - } + NativeConverter.setCallbackEncode(converterHandle, this); } @Override protected void implReset() { @@ -127,7 +123,6 @@ final class CharsetEncoderICU extends CharsetEncoder { input = null; allocatedInput = null; allocatedOutput = null; - ec = 0; inEnd = 0; outEnd = 0; } @@ -142,16 +137,14 @@ final class CharsetEncoderICU extends CharsetEncoder { data[OUTPUT_OFFSET] = getArray(out); data[INVALID_CHARS] = 0; // Make sure we don't see earlier errors. - ec = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, true); - if (ErrorCode.isFailure(ec)) { - if (ec == ErrorCode.U_BUFFER_OVERFLOW_ERROR) { + int error = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, true); + if (ICU.U_FAILURE(error)) { + if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { return CoderResult.OVERFLOW; - } else if (ec == ErrorCode.U_TRUNCATED_CHAR_FOUND) { + } else if (error == ICU.U_TRUNCATED_CHAR_FOUND) { if (data[INPUT_OFFSET] > 0) { return CoderResult.malformedForLength(data[INPUT_OFFSET]); } - } else { - throw ErrorCode.throwException(ec); } } return CoderResult.UNDERFLOW; @@ -171,16 +164,16 @@ final class CharsetEncoderICU extends CharsetEncoder { data[INVALID_CHARS] = 0; // Make sure we don't see earlier errors. try { - ec = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, false); - if (ErrorCode.isFailure(ec)) { - if (ec == ErrorCode.U_BUFFER_OVERFLOW_ERROR) { + int error = NativeConverter.encode(converterHandle, input, inEnd, output, outEnd, data, false); + if (ICU.U_FAILURE(error)) { + if (error == ICU.U_BUFFER_OVERFLOW_ERROR) { return CoderResult.OVERFLOW; - } else if (ec == ErrorCode.U_INVALID_CHAR_FOUND) { + } else if (error == ICU.U_INVALID_CHAR_FOUND) { return CoderResult.unmappableForLength(data[INVALID_CHARS]); - } else if (ec == ErrorCode.U_ILLEGAL_CHAR_FOUND) { + } else if (error == ICU.U_ILLEGAL_CHAR_FOUND) { return CoderResult.malformedForLength(data[INVALID_CHARS]); } else { - throw new AssertionError("unexpected failure: " + ec); + throw new AssertionError(error); } } // Decoding succeeded: give us more data. diff --git a/luni/src/main/java/java/security/Provider.java b/luni/src/main/java/java/security/Provider.java index 2de3751e83..018e268b42 100644 --- a/luni/src/main/java/java/security/Provider.java +++ b/luni/src/main/java/java/security/Provider.java @@ -27,12 +27,13 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; -import org.apache.harmony.luni.util.TwoKeyHashMap; import org.apache.harmony.security.fortress.Services; /** @@ -57,18 +58,18 @@ public abstract class Provider extends Properties { // Contains "Service.Algorithm" and Provider.Service classes added using // putService() - private transient TwoKeyHashMap<String, String, Service> serviceTable; + private transient LinkedHashMap<String, Service> serviceTable; // Contains "Service.Alias" and Provider.Service classes added using // putService() - private transient TwoKeyHashMap<String, String, Service> aliasTable; + private transient LinkedHashMap<String, Service> aliasTable; // Contains "Service.Algorithm" and Provider.Service classes added using // put() - private transient TwoKeyHashMap<String, String, Service> propertyServiceTable; + private transient LinkedHashMap<String, Service> propertyServiceTable; // Contains "Service.Alias" and Provider.Service classes added using put() - private transient TwoKeyHashMap<String, String, Service> propertyAliasTable; + private transient LinkedHashMap<String, Service> propertyAliasTable; // The properties changed via put() private transient Properties changedProperties; @@ -414,22 +415,22 @@ public abstract class Provider extends Properties { return returnedService; } - String alg = algorithm.toUpperCase(Locale.US); + String key = key(type, algorithm); Object o = null; if (serviceTable != null) { - o = serviceTable.get(type, alg); + o = serviceTable.get(key); } if (o == null && aliasTable != null) { - o = aliasTable.get(type, alg); + o = aliasTable.get(key); } if (o == null) { updatePropertyServiceTable(); } if (o == null && propertyServiceTable != null) { - o = propertyServiceTable.get(type, alg); + o = propertyServiceTable.get(key); } if (o == null && propertyAliasTable != null) { - o = propertyAliasTable.get(type, alg); + o = propertyAliasTable.get(key); } if (o != null) { @@ -454,9 +455,9 @@ public abstract class Provider extends Properties { return lastServicesSet; } if (serviceTable != null) { - lastServicesSet = new HashSet<Service>(serviceTable.values()); + lastServicesSet = new LinkedHashSet<Service>(serviceTable.values()); } else { - lastServicesSet = new HashSet<Service>(); + lastServicesSet = new LinkedHashSet<Service>(); } if (propertyServiceTable != null) { lastServicesSet.addAll(propertyServiceTable.values()); @@ -481,15 +482,15 @@ public abstract class Provider extends Properties { } servicesChanged(); if (serviceTable == null) { - serviceTable = new TwoKeyHashMap<String, String, Service>(128); + serviceTable = new LinkedHashMap<String, Service>(128); } - serviceTable.put(s.type, s.algorithm.toUpperCase(Locale.US), s); + serviceTable.put(key(s.type, s.algorithm), s); if (s.aliases != null) { if (aliasTable == null) { - aliasTable = new TwoKeyHashMap<String, String, Service>(256); + aliasTable = new LinkedHashMap<String, Service>(256); } for (String alias : s.getAliases()) { - aliasTable.put(s.type, alias.toUpperCase(Locale.US), s); + aliasTable.put(key(s.type, alias), s); } } serviceInfoToProperties(s); @@ -510,11 +511,11 @@ public abstract class Provider extends Properties { } servicesChanged(); if (serviceTable != null) { - serviceTable.remove(s.type, s.algorithm.toUpperCase(Locale.US)); + serviceTable.remove(key(s.type, s.algorithm)); } if (aliasTable != null && s.aliases != null) { for (String alias: s.getAliases()) { - aliasTable.remove(s.type, alias.toUpperCase(Locale.US)); + aliasTable.remove(key(s.type, alias)); } } serviceInfoFromProperties(s); @@ -584,7 +585,7 @@ public abstract class Provider extends Properties { serviceName = service_alias.substring(0, i); aliasName = service_alias.substring(i + 1); if (propertyAliasTable != null) { - propertyAliasTable.remove(serviceName, aliasName.toUpperCase(Locale.US)); + propertyAliasTable.remove(key(serviceName, aliasName)); } if (propertyServiceTable != null) { for (Iterator<Service> it = propertyServiceTable.values().iterator(); it @@ -608,12 +609,11 @@ public abstract class Provider extends Properties { serviceName = k.substring(0, j); algorithm = k.substring(j + 1); if (propertyServiceTable != null) { - Provider.Service ser = propertyServiceTable.remove(serviceName, - algorithm.toUpperCase(Locale.US)); + Provider.Service ser = propertyServiceTable.remove(key(serviceName, algorithm)); if (ser != null && propertyAliasTable != null && ser.aliases != null) { for (String alias : ser.aliases) { - propertyAliasTable.remove(serviceName, alias.toUpperCase(Locale.US)); + propertyAliasTable.remove(key(serviceName, alias)); } } } @@ -624,7 +624,7 @@ public abstract class Provider extends Properties { serviceName = k.substring(0, j); algorithm = k.substring(j + 1, i); if (propertyServiceTable != null) { - Object o = propertyServiceTable.get(serviceName, algorithm.toUpperCase(Locale.US)); + Object o = propertyServiceTable.get(key(serviceName, algorithm)); if (o != null) { s = (Provider.Service) o; s.attributes.remove(attribute); @@ -667,20 +667,20 @@ public abstract class Provider extends Properties { serviceName = service_alias.substring(0, i); aliasName = service_alias.substring(i + 1); algorithm = value; - String algUp = algorithm.toUpperCase(Locale.US); + String propertyServiceTableKey = key(serviceName, algorithm); Object o = null; if (propertyServiceTable == null) { - propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128); + propertyServiceTable = new LinkedHashMap<String, Service>(128); } else { - o = propertyServiceTable.get(serviceName, algUp); + o = propertyServiceTable.get(propertyServiceTableKey); } if (o != null) { s = (Provider.Service) o; s.addAlias(aliasName); if (propertyAliasTable == null) { - propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256); + propertyAliasTable = new LinkedHashMap<String, Service>(256); } - propertyAliasTable.put(serviceName, aliasName.toUpperCase(Locale.US), s); + propertyAliasTable.put(key(serviceName, aliasName), s); } else { String className = (String) changedProperties .get(serviceName + "." + algorithm); @@ -689,11 +689,11 @@ public abstract class Provider extends Properties { l.add(aliasName); s = new Provider.Service(this, serviceName, algorithm, className, l, new HashMap<String, String>()); - propertyServiceTable.put(serviceName, algUp, s); + propertyServiceTable.put(propertyServiceTableKey, s); if (propertyAliasTable == null) { - propertyAliasTable = new TwoKeyHashMap<String, String, Service>(256); + propertyAliasTable = new LinkedHashMap<String, Service>(256); } - propertyAliasTable.put(serviceName, aliasName.toUpperCase(Locale.US), s); + propertyAliasTable.put(key(serviceName, aliasName), s); } } continue; @@ -706,10 +706,10 @@ public abstract class Provider extends Properties { if (i == -1) { // <crypto_service>.<algorithm_or_type>=<className> serviceName = key.substring(0, j); algorithm = key.substring(j + 1); - String alg = algorithm.toUpperCase(Locale.US); + String propertyServiceTableKey = key(serviceName, algorithm); Object o = null; if (propertyServiceTable != null) { - o = propertyServiceTable.get(serviceName, alg); + o = propertyServiceTable.get(propertyServiceTableKey); } if (o != null) { s = (Provider.Service) o; @@ -719,21 +719,20 @@ public abstract class Provider extends Properties { value, Collections.<String>emptyList(), Collections.<String,String>emptyMap()); if (propertyServiceTable == null) { - propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128); + propertyServiceTable = new LinkedHashMap<String, Service>(128); } - propertyServiceTable.put(serviceName, alg, s); + propertyServiceTable.put(propertyServiceTableKey, s); } } else { - // <crypto_service>.<algorithm_or_type> - // <attribute_name>=<attrValue> + // <crypto_service>.<algorithm_or_type> <attribute_name>=<attrValue> serviceName = key.substring(0, j); algorithm = key.substring(j + 1, i); String attribute = key.substring(i + 1); - String alg = algorithm.toUpperCase(Locale.US); + String propertyServiceTableKey = key(serviceName, algorithm); Object o = null; if (propertyServiceTable != null) { - o = propertyServiceTable.get(serviceName, alg); + o = propertyServiceTable.get(propertyServiceTableKey); } if (o != null) { s = (Provider.Service) o; @@ -747,9 +746,9 @@ public abstract class Provider extends Properties { s = new Provider.Service(this, serviceName, algorithm, className, new ArrayList<String>(), m); if (propertyServiceTable == null) { - propertyServiceTable = new TwoKeyHashMap<String, String, Service>(128); + propertyServiceTable = new LinkedHashMap<String, Service>(128); } - propertyServiceTable.put(serviceName, alg, s); + propertyServiceTable.put(propertyServiceTableKey, s); } } } @@ -794,6 +793,10 @@ public abstract class Provider extends Properties { return null; } + private static String key(String type, String algorithm) { + return type + '.' + algorithm.toUpperCase(Locale.US); + } + /** * {@code Service} represents a service in the Java Security infrastructure. * Each service describes its type, the algorithm it implements, to which diff --git a/luni/src/main/java/java/sql/DataTruncation.java b/luni/src/main/java/java/sql/DataTruncation.java index b01100e800..c1bf11c0dc 100644 --- a/luni/src/main/java/java/sql/DataTruncation.java +++ b/luni/src/main/java/java/sql/DataTruncation.java @@ -49,7 +49,7 @@ public class DataTruncation extends SQLWarning implements Serializable { /** * Creates the {@code DataTruncation} object. The reason is set to {@code - * "Data truncation"}, the {@code ErrorCode} is set to the {@code + * "Data truncation"}, the error code is set to the {@code * SQLException} default value, and the other fields are set to the values * supplied as arguments. * @@ -79,7 +79,7 @@ public class DataTruncation extends SQLWarning implements Serializable { /** * Creates a DataTruncation. The Reason is set to "Data truncation", the - * ErrorCode is set to the SQLException default value and other fields are + * error code is set to the SQLException default value and other fields are * set to the values supplied on this method. * * @param index diff --git a/luni/src/main/java/java/util/Random.java b/luni/src/main/java/java/util/Random.java index 7ce74cc95a..cc9de5883b 100644 --- a/luni/src/main/java/java/util/Random.java +++ b/luni/src/main/java/java/util/Random.java @@ -140,25 +140,21 @@ public class Random implements Serializable { * section 3.4.1, subsection C, algorithm P. */ public synchronized double nextGaussian() { - if (haveNextNextGaussian) { // if X1 has been returned, return the - // second Gaussian + if (haveNextNextGaussian) { haveNextNextGaussian = false; return nextNextGaussian; } double v1, v2, s; do { - v1 = 2 * nextDouble() - 1; // Generates two independent random - // variables U1, U2 + v1 = 2 * nextDouble() - 1; v2 = 2 * nextDouble() - 1; s = v1 * v1 + v2 * v2; - } while (s >= 1); - double norm = Math.sqrt(-2 * Math.log(s) / s); - nextNextGaussian = v2 * norm; // should that not be norm instead - // of multiplier ? + } while (s >= 1 || s == 0); + double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s); + nextNextGaussian = v2 * multiplier; haveNextNextGaussian = true; - return v1 * norm; // should that not be norm instead of multiplier - // ? + return v1 * multiplier; } /** diff --git a/luni/src/main/java/java/util/TimeZone.java b/luni/src/main/java/java/util/TimeZone.java index 34763cc1fd..969e164de2 100644 --- a/luni/src/main/java/java/util/TimeZone.java +++ b/luni/src/main/java/java/util/TimeZone.java @@ -18,6 +18,8 @@ package java.util; import java.io.Serializable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import libcore.icu.TimeZones; import libcore.util.ZoneInfoDB; @@ -28,7 +30,7 @@ import libcore.util.ZoneInfoDB; * <p>Most applications will use {@link #getDefault} which returns a {@code TimeZone} based on * the time zone where the program is running. * - * <p>You can also get a specific {@code TimeZone} {@link #getTimeZone by id}. + * <p>You can also get a specific {@code TimeZone} {@link #getTimeZone by Olson ID}. * * <p>It is highly unlikely you'll ever want to use anything but the factory methods yourself. * Let classes like {@link Calendar} and {@link java.text.SimpleDateFormat} do the date @@ -64,6 +66,8 @@ import libcore.util.ZoneInfoDB; public abstract class TimeZone implements Serializable, Cloneable { private static final long serialVersionUID = 3581463369166924961L; + private static final Pattern CUSTOM_ZONE_ID_PATTERN = Pattern.compile("^GMT[-+](\\d{1,2})(:?(\\d\\d))?$"); + /** * The short display name style, such as {@code PDT}. Requests for this * style may yield GMT offsets like {@code GMT-08:00}. @@ -265,17 +269,19 @@ public abstract class TimeZone implements Serializable, Cloneable { public abstract int getRawOffset(); /** - * Returns a {@code TimeZone} suitable for {@code id}, or {@code GMT} for unknown ids. + * Returns a {@code TimeZone} corresponding to the given {@code id}, or {@code GMT} + * for unknown ids. * - * <p>An id can be an Olson name of the form <i>Area</i>/<i>Location</i>, such + * <p>An ID can be an Olson name of the form <i>Area</i>/<i>Location</i>, such * as {@code America/Los_Angeles}. The {@link #getAvailableIDs} method returns * the supported names. * - * <p>This method can also create a custom {@code TimeZone} using the following - * syntax: {@code GMT[+|-]hh[[:]mm]}. For example, {@code TimeZone.getTimeZone("GMT+14:00")} - * would return an object with a raw offset of +14 hours from UTC, and which does <i>not</i> - * use daylight savings. These are rarely useful, because they don't correspond to time - * zones actually in use. + * <p>This method can also create a custom {@code TimeZone} given an ID with the following + * syntax: {@code GMT[+|-]hh[[:]mm]}. For example, {@code "GMT+05:00"}, {@code "GMT+0500"}, + * {@code "GMT+5:00"}, {@code "GMT+500"}, {@code "GMT+05"}, and {@code "GMT+5"} all return + * an object with a raw offset of +5 hours from UTC, and which does <i>not</i> use daylight + * savings. These are rarely useful, because they don't correspond to time zones actually + * in use by humans. * * <p>Other than the special cases "UTC" and "GMT" (which are synonymous in this context, * both corresponding to UTC), Android does not support the deprecated three-letter time @@ -299,66 +305,37 @@ public abstract class TimeZone implements Serializable, Cloneable { } /** - * Returns a new SimpleTimeZone for an id of the form "GMT[+|-]hh[[:]mm]", or null. + * Returns a new SimpleTimeZone for an ID of the form "GMT[+|-]hh[[:]mm]", or null. */ private static TimeZone getCustomTimeZone(String id) { - char sign = id.charAt(3); - if (sign != '+' && sign != '-') { - return null; - } - int[] position = new int[1]; - String formattedName = formatTimeZoneName(id, 4); - int hour = parseNumber(formattedName, 4, position); - if (hour < 0 || hour > 23) { - return null; - } - int index = position[0]; - if (index == -1) { + Matcher m = CUSTOM_ZONE_ID_PATTERN.matcher(id); + if (!m.matches()) { return null; } - int raw = hour * 3600000; - if (index < formattedName.length() && formattedName.charAt(index) == ':') { - int minute = parseNumber(formattedName, index + 1, position); - if (position[0] == -1 || minute < 0 || minute > 59) { - return null; - } - raw += minute * 60000; - } else if (hour >= 30 || index > 6) { - raw = (hour / 100 * 3600000) + (hour % 100 * 60000); - } - if (sign == '-') { - raw = -raw; - } - return new SimpleTimeZone(raw, formattedName); - } - private static String formatTimeZoneName(String name, int offset) { - StringBuilder buf = new StringBuilder(); - int index = offset, length = name.length(); - buf.append(name.substring(0, offset)); - - while (index < length) { - if (Character.digit(name.charAt(index), 10) != -1) { - buf.append(name.charAt(index)); - if ((length - (index + 1)) == 2) { - buf.append(':'); - } - } else if (name.charAt(index) == ':') { - buf.append(':'); + int hour; + int minute = 0; + try { + hour = Integer.parseInt(m.group(1)); + if (m.group(3) != null) { + minute = Integer.parseInt(m.group(3)); } - index++; + } catch (NumberFormatException impossible) { + throw new AssertionError(impossible); } - if (buf.toString().indexOf(":") == -1) { - buf.append(':'); - buf.append("00"); + if (hour < 0 || hour > 23 || minute < 0 || minute > 59) { + return null; } - if (buf.toString().indexOf(":") == 5) { - buf.insert(4, '0'); + char sign = id.charAt(3); + int raw = (hour * 3600000) + (minute * 60000); + if (sign == '-') { + raw = -raw; } - return buf.toString(); + String cleanId = String.format("GMT%c%02d:%02d", sign, hour, minute); + return new SimpleTimeZone(raw, cleanId); } /** @@ -380,17 +357,6 @@ public abstract class TimeZone implements Serializable, Cloneable { */ public abstract boolean inDaylightTime(Date time); - private static int parseNumber(String string, int offset, int[] position) { - int index = offset, length = string.length(), digit, result = 0; - while (index < length - && (digit = Character.digit(string.charAt(index), 10)) != -1) { - index++; - result = result * 10 + digit; - } - position[0] = index == offset ? -1 : index; - return result; - } - /** * Overrides the default time zone for the current process only. * diff --git a/luni/src/main/java/java/util/regex/Matcher.java b/luni/src/main/java/java/util/regex/Matcher.java index 58bcf9e9db..cfd4432336 100644 --- a/luni/src/main/java/java/util/regex/Matcher.java +++ b/luni/src/main/java/java/util/regex/Matcher.java @@ -50,11 +50,6 @@ public final class Matcher implements MatchResult { private int regionEnd; /** - * Holds the position where the next find operation will take place. - */ - private int findPos; - - /** * Holds the position where the next append operation will take place. */ private int appendPos; @@ -212,7 +207,6 @@ public final class Matcher implements MatchResult { resetForInput(); matchFound = false; - findPos = regionStart; appendPos = 0; return this; @@ -377,30 +371,17 @@ public final class Matcher implements MatchResult { } /** - * Returns the next occurrence of the {@link Pattern} in the input. The - * method starts the search from the given character in the input. + * Returns true if there is another match in the input, starting + * from the given position. The region is ignored. * - * @param start - * The index in the input at which the find operation is to - * begin. If this is less than the start of the region, it is - * automatically adjusted to that value. If it is beyond the end - * of the region, the method will fail. - * @return true if (and only if) a match has been found. + * @throws IndexOutOfBoundsException if {@code start < 0 || start > input.length()} */ public boolean find(int start) { - findPos = start; - - if (findPos < regionStart) { - findPos = regionStart; - } else if (findPos >= regionEnd) { - matchFound = false; - return false; + if (start < 0 || start > input.length()) { + throw new IndexOutOfBoundsException("start=" + start + "; length=" + input.length()); } - matchFound = findImpl(address, input, findPos, matchOffsets); - if (matchFound) { - findPos = matchOffsets[1]; - } + matchFound = findImpl(address, input, start, matchOffsets); return matchFound; } @@ -414,9 +395,6 @@ public final class Matcher implements MatchResult { */ public boolean find() { matchFound = findNextImpl(address, input, matchOffsets); - if (matchFound) { - findPos = matchOffsets[1]; - } return matchFound; } @@ -429,9 +407,6 @@ public final class Matcher implements MatchResult { */ public boolean lookingAt() { matchFound = lookingAtImpl(address, input, matchOffsets); - if (matchFound) { - findPos = matchOffsets[1]; - } return matchFound; } @@ -444,9 +419,6 @@ public final class Matcher implements MatchResult { */ public boolean matches() { matchFound = matchesImpl(address, input, matchOffsets); - if (matchFound) { - findPos = matchOffsets[1]; - } return matchFound; } diff --git a/luni/src/main/java/java/util/regex/Pattern.java b/luni/src/main/java/java/util/regex/Pattern.java index 46984b9b8c..cbd5965431 100644 --- a/luni/src/main/java/java/util/regex/Pattern.java +++ b/luni/src/main/java/java/util/regex/Pattern.java @@ -82,16 +82,23 @@ import java.io.Serializable; * </table> * <p>Most of the time, the built-in character classes are more useful: * <table> - * <tr> <td> \d </td> <td>Any digit character.</td> </tr> - * <tr> <td> \D </td> <td>Any non-digit character.</td> </tr> - * <tr> <td> \s </td> <td>Any whitespace character.</td> </tr> - * <tr> <td> \S </td> <td>Any non-whitespace character.</td> </tr> - * <tr> <td> \w </td> <td>Any word character.</td> </tr> - * <tr> <td> \W </td> <td>Any non-word character.</td> </tr> + * <tr> <td> \d </td> <td>Any digit character (see note below).</td> </tr> + * <tr> <td> \D </td> <td>Any non-digit character (see note below).</td> </tr> + * <tr> <td> \s </td> <td>Any whitespace character (see note below).</td> </tr> + * <tr> <td> \S </td> <td>Any non-whitespace character (see note below).</td> </tr> + * <tr> <td> \w </td> <td>Any word character (see note below).</td> </tr> + * <tr> <td> \W </td> <td>Any non-word character (see note below).</td> </tr> * <tr> <td> \p{<i>NAME</i>} </td> <td> Any character in the class with the given <i>NAME</i>. </td> </tr> * <tr> <td> \P{<i>NAME</i>} </td> <td> Any character <i>not</i> in the named class. </td> </tr> * </table> - * <p>There are a variety of named classes: + * <p>Note that these built-in classes don't just cover the traditional ASCII range. For example, + * <code>\w</code> is equivalent to the character class <code>[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}]</code>. + * For more details see <a href="http://www.unicode.org/reports/tr18/#Compatibility_Properties">Unicode TR-18</a>, + * and bear in mind that the set of characters in each class can vary between Unicode releases. + * If you actually want to match only ASCII characters, specify the explicit characters you want; + * if you mean 0-9 use <code>[0-9]</code> rather than <code>\d</code>, which would also include + * Gurmukhi digits and so forth. + * <p>There are also a variety of named classes: * <ul> * <li><a href="../../lang/Character.html#unicode_categories">Unicode category names</a>, * prefixed by {@code Is}. For example {@code \p{IsLu}} for all uppercase letters. diff --git a/luni/src/main/java/javax/crypto/SealedObject.java b/luni/src/main/java/javax/crypto/SealedObject.java index c9c1534563..cfb970bf23 100644 --- a/luni/src/main/java/javax/crypto/SealedObject.java +++ b/luni/src/main/java/javax/crypto/SealedObject.java @@ -33,12 +33,12 @@ import java.security.NoSuchProviderException; /** * A {@code SealedObject} is a wrapper around a {@code serializable} object * instance and encrypts it using a cryptographic cipher. - * <p> - * Since a {@code SealedObject} instance is a serializable object itself it can + * + * <p>Since a {@code SealedObject} instance is serializable it can * either be stored or transmitted over an insecure channel. - * <p> - * The wrapped object can later be decrypted (unsealed) using the corresponding - * key and then be deserialized to retrieve the original object.The sealed + * + * <p>The wrapped object can later be decrypted (unsealed) using the corresponding + * key and then be deserialized to retrieve the original object. The sealed * object itself keeps track of the cipher and corresponding parameters. */ public class SealedObject implements Serializable { @@ -46,19 +46,25 @@ public class SealedObject implements Serializable { private static final long serialVersionUID = 4482838265551344752L; /** - * The {@link AlgorithmParameters} in encoded format. + * The cipher's {@link AlgorithmParameters} in encoded format. + * Equivalent to {@code cipher.getParameters().getEncoded()}, + * or null if the cipher did not use any parameters. */ protected byte[] encodedParams; + private byte[] encryptedContent; private String sealAlg; private String paramsAlg; - private void readObject(ObjectInputStream s) - throws IOException, ClassNotFoundException { - encodedParams = (byte []) s.readUnshared(); - encryptedContent = (byte []) s.readUnshared(); - sealAlg = (String) s.readUnshared(); - paramsAlg = (String) s.readUnshared(); + private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { + // We do unshared reads here to ensure we have our own clones of the byte[]s. + encodedParams = (byte[]) s.readUnshared(); + encryptedContent = (byte[]) s.readUnshared(); + // These are regular shared reads because the algorithms used by a given stream are + // almost certain to the be same for each object, and String is immutable anyway, + // so there's no security concern about sharing. + sealAlg = (String) s.readObject(); + paramsAlg = (String) s.readObject(); } /** diff --git a/luni/src/main/java/javax/xml/xpath/package.html b/luni/src/main/java/javax/xml/xpath/package.html index edeb44860a..202a29cf00 100644 --- a/luni/src/main/java/javax/xml/xpath/package.html +++ b/luni/src/main/java/javax/xml/xpath/package.html @@ -165,7 +165,7 @@ or more nodes from an XML document:</p> XPath xpath = XPathFactory.newInstance().newXPath(); String expression = "/widgets/widget"; InputSource inputSource = new InputSource("widgets.xml"); -NodeSet nodes = (NodeSet) xpath.evaluate(expression, inputSource, XPathConstants.NODESET); +NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET); </pre> <h3>XPath Expressions and Types</h3> diff --git a/luni/src/main/java/libcore/icu/ErrorCode.java b/luni/src/main/java/libcore/icu/ErrorCode.java deleted file mode 100644 index c093af2430..0000000000 --- a/luni/src/main/java/libcore/icu/ErrorCode.java +++ /dev/null @@ -1,71 +0,0 @@ -/** -****************************************************************************** -* Copyright (C) 1996-2005, International Business Machines Corporation and * -* others. All Rights Reserved. * -****************************************************************************** -* -****************************************************************************** -*/ - -package libcore.icu; - -/** - * Error exception class mapping ICU error codes of the enum UErrorCode - * @author syn wee quek -*/ -public final class ErrorCode extends Exception { - public static boolean isFailure(int error) { - return error > U_ZERO_ERROR && error < U_ERROR_LIMIT; - } - - public static RuntimeException throwException(int error) { - if (error <= U_ZERO_ERROR && error >= U_ERROR_LIMIT) { - return null; - } - switch (error) { - case U_ILLEGAL_ARGUMENT_ERROR: - return new IllegalArgumentException(ERROR_NAMES[error]); - case U_INDEX_OUTOFBOUNDS_ERROR: - case U_BUFFER_OVERFLOW_ERROR: - return new ArrayIndexOutOfBoundsException(ERROR_NAMES[error]); - case U_UNSUPPORTED_ERROR: - return new UnsupportedOperationException(ERROR_NAMES[error]); - } - throw new RuntimeException(ERROR_NAMES[error]); - } - - // The errors needed by our CharsetDecoderICU/CharsetEncoderICU. - public static final int U_ZERO_ERROR = 0; - private static final int U_ILLEGAL_ARGUMENT_ERROR = 1; - private static final int U_INDEX_OUTOFBOUNDS_ERROR = 8; - public static final int U_INVALID_CHAR_FOUND = 10; - public static final int U_TRUNCATED_CHAR_FOUND = 11; - public static final int U_ILLEGAL_CHAR_FOUND = 12; - public static final int U_BUFFER_OVERFLOW_ERROR = 15; - private static final int U_UNSUPPORTED_ERROR = 16; - private static final int U_ERROR_LIMIT = 21; - - // TODO: this list is incomplete; get these from native code! - private static final String ERROR_NAMES[] = { - "U_ZERO_ERROR", - "U_ILLEGAL_ARGUMENT_ERROR", - "U_MISSING_RESOURCE_ERROR", - "U_INVALID_FORMAT_ERROR", - "U_FILE_ACCESS_ERROR", - "U_INTERNAL_PROGRAM_ERROR", - "U_MESSAGE_PARSE_ERROR", - "U_MEMORY_ALLOCATION_ERROR", - "U_INDEX_OUTOFBOUNDS_ERROR", - "U_PARSE_ERROR", - "U_INVALID_CHAR_FOUND", - "U_TRUNCATED_CHAR_FOUND", - "U_ILLEGAL_CHAR_FOUND", - "U_INVALID_TABLE_FORMAT", - "U_INVALID_TABLE_FILE", - "U_BUFFER_OVERFLOW_ERROR", - "U_UNSUPPORTED_ERROR", - "U_RESOURCE_TYPE_MISMATCH", - "U_ILLEGAL_ESCAPE_SEQUENCE", - "U_UNSUPPORTED_ESCAPE_SEQUENCE" - }; -} diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java index 7f3303e5d7..99844142fa 100644 --- a/luni/src/main/java/libcore/icu/ICU.java +++ b/luni/src/main/java/libcore/icu/ICU.java @@ -142,6 +142,19 @@ public final class ICU { public static native String toLowerCase(String s, String localeName); public static native String toUpperCase(String s, String localeName); + // --- Errors. + + // Just the subset of error codes needed by CharsetDecoderICU/CharsetEncoderICU. + public static final int U_ZERO_ERROR = 0; + public static final int U_INVALID_CHAR_FOUND = 10; + public static final int U_TRUNCATED_CHAR_FOUND = 11; + public static final int U_ILLEGAL_CHAR_FOUND = 12; + public static final int U_BUFFER_OVERFLOW_ERROR = 15; + + public static boolean U_FAILURE(int error) { + return error > U_ZERO_ERROR; + } + // --- Native methods accessing ICU's database. private static native String[] getAvailableBreakIteratorLocalesNative(); diff --git a/luni/src/main/java/libcore/icu/NativeConverter.java b/luni/src/main/java/libcore/icu/NativeConverter.java index 2d8630cae8..e18f483c1d 100644 --- a/luni/src/main/java/libcore/icu/NativeConverter.java +++ b/luni/src/main/java/libcore/icu/NativeConverter.java @@ -54,19 +54,19 @@ public final class NativeConverter { } } - public static int setCallbackDecode(long converterHandle, CharsetDecoder decoder) { - return setCallbackDecode(converterHandle, - translateCodingErrorAction(decoder.malformedInputAction()), - translateCodingErrorAction(decoder.unmappableCharacterAction()), - decoder.replacement()); + public static void setCallbackDecode(long converterHandle, CharsetDecoder decoder) { + setCallbackDecode(converterHandle, + translateCodingErrorAction(decoder.malformedInputAction()), + translateCodingErrorAction(decoder.unmappableCharacterAction()), + decoder.replacement()); } - private static native int setCallbackDecode(long converterHandle, int onMalformedInput, int onUnmappableInput, String subChars); + private static native void setCallbackDecode(long converterHandle, int onMalformedInput, int onUnmappableInput, String subChars); - public static int setCallbackEncode(long converterHandle, CharsetEncoder encoder) { - return setCallbackEncode(converterHandle, - translateCodingErrorAction(encoder.malformedInputAction()), - translateCodingErrorAction(encoder.unmappableCharacterAction()), - encoder.replacement()); + public static void setCallbackEncode(long converterHandle, CharsetEncoder encoder) { + setCallbackEncode(converterHandle, + translateCodingErrorAction(encoder.malformedInputAction()), + translateCodingErrorAction(encoder.unmappableCharacterAction()), + encoder.replacement()); } - private static native int setCallbackEncode(long converterHandle, int onMalformedInput, int onUnmappableInput, byte[] subBytes); + private static native void setCallbackEncode(long converterHandle, int onMalformedInput, int onUnmappableInput, byte[] subBytes); } diff --git a/luni/src/main/java/libcore/io/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java index 4f2858d0c0..61c9765fe5 100644 --- a/luni/src/main/java/libcore/io/BlockGuardOs.java +++ b/luni/src/main/java/libcore/io/BlockGuardOs.java @@ -50,7 +50,7 @@ public class BlockGuardOs extends ForwardingOs { } } - @Override public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException { + @Override public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { BlockGuard.getThreadPolicy().onNetwork(); return tagSocket(os.accept(fd, peerAddress)); } @@ -80,7 +80,7 @@ public class BlockGuardOs extends ForwardingOs { return linger.isOn() && linger.l_linger > 0; } - @Override public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException { + @Override public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { BlockGuard.getThreadPolicy().onNetwork(); os.connect(fd, address, port); } @@ -154,22 +154,22 @@ public class BlockGuardOs extends ForwardingOs { return os.readv(fd, buffers, offsets, byteCounts); } - @Override public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException { + @Override public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { BlockGuard.getThreadPolicy().onNetwork(); return os.recvfrom(fd, buffer, flags, srcAddress); } - @Override public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException { + @Override public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { BlockGuard.getThreadPolicy().onNetwork(); return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); } - @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException { + @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { BlockGuard.getThreadPolicy().onNetwork(); return os.sendto(fd, buffer, flags, inetAddress, port); } - @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException { + @Override public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { // We permit datagrams without hostname lookups. if (inetAddress != null) { BlockGuard.getThreadPolicy().onNetwork(); diff --git a/luni/src/main/java/libcore/io/DiskLruCache.java b/luni/src/main/java/libcore/io/DiskLruCache.java index 46997662d3..b7d246dec5 100644 --- a/luni/src/main/java/libcore/io/DiskLruCache.java +++ b/luni/src/main/java/libcore/io/DiskLruCache.java @@ -458,9 +458,14 @@ public final class DiskLruCache implements Closeable { // if this edit is creating the entry for the first time, every index must have a value if (success && !entry.readable) { for (int i = 0; i < valueCount; i++) { + if (!editor.written[i]) { + editor.abort(); + throw new IllegalStateException("Newly created entry didn't create value for index " + i); + } if (!entry.getDirtyFile(i).exists()) { editor.abort(); - throw new IllegalStateException("edit didn't create file " + i); + System.logW("DiskLruCache: Newly created entry doesn't have file for index " + i); + return; } } } @@ -659,10 +664,12 @@ public final class DiskLruCache implements Closeable { */ public final class Editor { private final Entry entry; + private final boolean[] written; private boolean hasErrors; private Editor(Entry entry) { this.entry = entry; + this.written = (entry.readable) ? null : new boolean[valueCount]; } /** @@ -702,6 +709,9 @@ public final class DiskLruCache implements Closeable { if (entry.currentEditor != this) { throw new IllegalStateException(); } + if (!entry.readable) { + written[index] = true; + } return new FaultHidingOutputStream(new FileOutputStream(entry.getDirtyFile(index))); } } diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java index 2c8e56250e..39b9861f5d 100644 --- a/luni/src/main/java/libcore/io/ForwardingOs.java +++ b/luni/src/main/java/libcore/io/ForwardingOs.java @@ -20,6 +20,7 @@ import java.io.FileDescriptor; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.net.SocketException; import java.nio.ByteBuffer; import libcore.util.MutableInt; import libcore.util.MutableLong; @@ -34,12 +35,12 @@ public class ForwardingOs implements Os { this.os = os; } - public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException { return os.accept(fd, peerAddress); } + public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); } public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); } - public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException { os.bind(fd, address, port); } + public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); } public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); } public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); } - public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException { os.connect(fd, address, port); } + public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.connect(fd, address, port); } public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException { return os.dup(oldFd); } public FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException { return os.dup2(oldFd, newFd); } public String[] environ() { return os.environ(); } @@ -95,13 +96,13 @@ public class ForwardingOs implements Os { public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException { return os.read(fd, buffer); } public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException { return os.read(fd, bytes, byteOffset, byteCount); } public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException { return os.readv(fd, buffers, offsets, byteCounts); } - public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException { return os.recvfrom(fd, buffer, flags, srcAddress); } - public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); } + public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, buffer, flags, srcAddress); } + public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); } public void remove(String path) throws ErrnoException { os.remove(path); } public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); } public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException { return os.sendfile(outFd, inFd, inOffset, byteCount); } - public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException { return os.sendto(fd, buffer, flags, inetAddress, port); } - public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); } + public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, buffer, flags, inetAddress, port); } + public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return os.sendto(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); } public void setegid(int egid) throws ErrnoException { os.setegid(egid); } public void seteuid(int euid) throws ErrnoException { os.seteuid(euid); } public void setgid(int gid) throws ErrnoException { os.setgid(gid); } diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java index d637b67421..5fdc7be4af 100644 --- a/luni/src/main/java/libcore/io/Os.java +++ b/luni/src/main/java/libcore/io/Os.java @@ -20,17 +20,18 @@ import java.io.FileDescriptor; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.net.SocketException; import java.nio.ByteBuffer; import libcore.util.MutableInt; import libcore.util.MutableLong; public interface Os { - public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException; + public FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException; public boolean access(String path, int mode) throws ErrnoException; - public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; public void chmod(String path, int mode) throws ErrnoException; public void close(FileDescriptor fd) throws ErrnoException; - public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; public FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException; public FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException; public String[] environ(); @@ -88,12 +89,12 @@ public interface Os { public int read(FileDescriptor fd, ByteBuffer buffer) throws ErrnoException; public int read(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount) throws ErrnoException; public int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException; - public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException; - public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException; + public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; + public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; public void remove(String path) throws ErrnoException; public void rename(String oldPath, String newPath) throws ErrnoException; - public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException; - public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException; + public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException; + public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException; public long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException; public void setegid(int egid) throws ErrnoException; public void seteuid(int euid) throws ErrnoException; diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Posix.java index 7bbf49f7fb..0fc9f38ebc 100644 --- a/luni/src/main/java/libcore/io/Posix.java +++ b/luni/src/main/java/libcore/io/Posix.java @@ -20,6 +20,7 @@ import java.io.FileDescriptor; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.NioUtils; import libcore.util.MutableInt; @@ -28,12 +29,12 @@ import libcore.util.MutableLong; public final class Posix implements Os { Posix() { } - public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException; + public native FileDescriptor accept(FileDescriptor fd, InetSocketAddress peerAddress) throws ErrnoException, SocketException; public native boolean access(String path, int mode) throws ErrnoException; - public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; public native void chmod(String path, int mode) throws ErrnoException; public native void close(FileDescriptor fd) throws ErrnoException; - public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException; + public native void connect(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException; public native FileDescriptor dup(FileDescriptor oldFd) throws ErrnoException; public native FileDescriptor dup2(FileDescriptor oldFd, int newFd) throws ErrnoException; public native String[] environ(); @@ -119,33 +120,33 @@ public final class Posix implements Os { } private native int readBytes(FileDescriptor fd, Object buffer, int offset, int byteCount) throws ErrnoException; public native int readv(FileDescriptor fd, Object[] buffers, int[] offsets, int[] byteCounts) throws ErrnoException; - public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException { + public int recvfrom(FileDescriptor fd, ByteBuffer buffer, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { if (buffer.isDirect()) { return recvfromBytes(fd, buffer, buffer.position(), buffer.remaining(), flags, srcAddress); } else { return recvfromBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), flags, srcAddress); } } - public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException { + public int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return recvfromBytes(fd, bytes, byteOffset, byteCount, flags, srcAddress); } - private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException; + private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException; public native void remove(String path) throws ErrnoException; public native void rename(String oldPath, String newPath) throws ErrnoException; public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, MutableLong inOffset, long byteCount) throws ErrnoException; - public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException { + public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { if (buffer.isDirect()) { return sendtoBytes(fd, buffer, buffer.position(), buffer.remaining(), flags, inetAddress, port); } else { return sendtoBytes(fd, NioUtils.unsafeArray(buffer), NioUtils.unsafeArrayOffset(buffer) + buffer.position(), buffer.remaining(), flags, inetAddress, port); } } - public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException { + public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { // This indirection isn't strictly necessary, but ensures that our public interface is type safe. return sendtoBytes(fd, bytes, byteOffset, byteCount, flags, inetAddress, port); } - private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException; + private native int sendtoBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException; public native void setegid(int egid) throws ErrnoException; public native void seteuid(int euid) throws ErrnoException; public native void setgid(int gid) throws ErrnoException; diff --git a/luni/src/main/java/libcore/net/MimeUtils.java b/luni/src/main/java/libcore/net/MimeUtils.java index f8038f0b65..6ea0baf737 100644 --- a/luni/src/main/java/libcore/net/MimeUtils.java +++ b/luni/src/main/java/libcore/net/MimeUtils.java @@ -350,6 +350,7 @@ public final class MimeUtils { add("video/x-ms-wvx", "wvx"); add("video/x-msvideo", "avi"); add("video/x-sgi-movie", "movie"); + add("video/x-webex", "wrf"); add("x-conference/x-cooltalk", "ice"); add("x-epoc/x-sisx-app", "sisx"); applyOverrides(); diff --git a/luni/src/main/java/libcore/net/http/HttpResponseCache.java b/luni/src/main/java/libcore/net/http/HttpResponseCache.java index 7b95e1cf05..2130fd1f11 100644 --- a/luni/src/main/java/libcore/net/http/HttpResponseCache.java +++ b/luni/src/main/java/libcore/net/http/HttpResponseCache.java @@ -282,6 +282,13 @@ public final class HttpResponseCache extends ResponseCache implements ExtendedRe super.close(); editor.commit(); } + + @Override + public void write(byte[] buffer, int offset, int length) throws IOException { + // Since we don't override "write(int oneByte)", we can write directly to "out" + // and avoid the inefficient implementation from the FilterOutputStream. + out.write(buffer, offset, length); + } }; } @@ -419,7 +426,7 @@ public final class HttpResponseCache extends ResponseCache implements ExtendedRe } public void writeTo(DiskLruCache.Editor editor) throws IOException { - OutputStream out = editor.newOutputStream(0); + OutputStream out = editor.newOutputStream(ENTRY_METADATA); Writer writer = new BufferedWriter(new OutputStreamWriter(out, Charsets.UTF_8)); writer.write(uri + '\n'); diff --git a/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java b/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java index a59df556f3..260a9ad45a 100644 --- a/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java +++ b/luni/src/main/java/libcore/net/http/HttpURLConnectionImpl.java @@ -36,6 +36,7 @@ import java.security.Permission; import java.util.List; import java.util.Map; import libcore.io.Base64; +import libcore.io.IoUtils; /** * This implementation uses HttpEngine to send requests and receive responses. @@ -87,6 +88,14 @@ class HttpURLConnectionImpl extends HttpURLConnection { @Override public final void disconnect() { // Calling disconnect() before a connection exists should have no effect. if (httpEngine != null) { + // We close the response body here instead of in + // HttpEngine.release because that is called when input + // has been completely read from the underlying socket. + // However the response body can be a GZIPInputStream that + // still has unread data. + if (httpEngine.hasResponse()) { + IoUtils.closeQuietly(httpEngine.getResponseBody()); + } httpEngine.release(false); } } diff --git a/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java b/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java deleted file mode 100644 index 35e6c62657..0000000000 --- a/luni/src/main/java/org/apache/harmony/luni/util/TwoKeyHashMap.java +++ /dev/null @@ -1,566 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.harmony.luni.util; - -import java.util.AbstractCollection; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Arrays; -import java.util.Collection; -import java.util.ConcurrentModificationException; -import java.util.Iterator; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Set; - -/** - * - * Reductive hash with two keys - * - */ -public class TwoKeyHashMap<E, K, V> extends AbstractMap<String, V> { - - static final float DEFAULT_LOAD_FACTOR = 0.75f; - static final int DEFAULT_INITIAL_SIZE = 16; - - private Set<Map.Entry<String, V>> entrySet; - private Collection<V> values; - private int size; - private int arrSize; - private int modCount; - - private Entry<E, K, V>[] arr; - - private float loadFactor; - int threshold = 0; - - /** - * Constructs an empty HashMap - */ - public TwoKeyHashMap() { - this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR); - } - - /** - * Constructs an empty HashMap - * - * @param initialCapacity - */ - public TwoKeyHashMap(int initialCapacity) { - this(initialCapacity, DEFAULT_LOAD_FACTOR); - } - - /** - * Constructs an empty HashMap - * - * @param initialCapacity - * @param initialLoadFactor - */ - @SuppressWarnings("unchecked") - public TwoKeyHashMap(int initialCapacity, float initialLoadFactor) { - if (initialCapacity < 0) { - throw new IllegalArgumentException("initialCapacity should be >= 0"); - } - if (initialLoadFactor <= 0) { - throw new IllegalArgumentException( - "initialLoadFactor should be > 0"); - } - loadFactor = initialLoadFactor; - if (initialCapacity == Integer.MAX_VALUE) { - initialCapacity--; - } - arrSize = initialCapacity > 0 ? initialCapacity : 1; - threshold = (int) (arrSize * loadFactor); - arr = new Entry[arrSize + 1]; - } - - /** - * Returns a collection view of the values - */ - public Collection<V> values() { - if (values == null) { - values = new ValuesCollectionImpl(); - } - return values; - } - - /** - * Returns a collection view of the mappings - */ - public Set<Map.Entry<String, V>> entrySet() { - if (entrySet == null) { - entrySet = new EntrySetImpl(); - } - return entrySet; - } - - /** - * Clears the map - */ - public void clear() { - modCount++; - size = 0; - Arrays.fill(arr, 0, arr.length, null); - } - - /** - * Removes the mapping for the keys - * - * @param key1 - * @param key2 - * @return - */ - public V remove(Object key1, Object key2) { - Entry<E, K, V> e = removeEntry(key1, key2); - return (e != null) ? e.value : null; - } - - /** - * Associates the specified value with the specified keys in this map - * - * @param key1 - * @param key2 - * @param value - * @return - */ - public V put(E key1, K key2, V value) { - if (key1 == null && key2 == null) { - int index = arrSize; - if (arr[index] == null) { - arr[index] = createEntry(0, null, null, value, null); - size++; - modCount++; - return null; - } else { - V oldValue = arr[index].value; - arr[index].value = value; - return oldValue; - } - } - - int hash = key1.hashCode() + key2.hashCode(); - int index = (hash & 0x7fffffff) % arrSize; - Entry<E, K, V> e = arr[index]; - - while (e != null) { - if (hash == e.hash && key1.equals(e.getKey1()) - && key2.equals(e.getKey2())) { - V oldValue = e.value; - e.value = value; - return oldValue; - } - e = e.next; - } - - arr[index] = createEntry(hash, key1, key2, value, arr[index]); - size++; - modCount++; - - if (size > threshold) { - rehash(); - } - return null; - } - - /** - * Rehash the map - * - */ - @SuppressWarnings("unchecked") - void rehash() { - int newArrSize = (arrSize + 1) * 2 + 1; - if (newArrSize < 0) { - newArrSize = Integer.MAX_VALUE - 1; - } - Entry<E, K, V>[] newArr = new Entry[newArrSize + 1]; - - for (int i = 0; i < arr.length - 1; i++) { - Entry<E, K, V> entry = arr[i]; - while (entry != null) { - Entry<E, K, V> next = entry.next; - - int newIndex = (entry.hash & 0x7fffffff) % newArrSize; - entry.next = newArr[newIndex]; - newArr[newIndex] = entry; - - entry = next; - } - } - newArr[newArrSize] = arr[arrSize]; // move null entry - arrSize = newArrSize; - - // The maximum array size is reached, increased loadFactor - // will keep array from further growing - if (arrSize == Integer.MAX_VALUE) { - loadFactor *= 10; - } - threshold = (int) (arrSize * loadFactor); - arr = newArr; - } - - /** - * Returns true if this map contains a mapping for {@code key1} and {@code key2}. - */ - public boolean containsKey(Object key1, Object key2) { - return findEntry(key1, key2) != null; - } - - /** - * Return the value by keys - * - * @param key1 - * @param key2 - * @return - */ - public V get(Object key1, Object key2) { - Entry<E, K, V> e = findEntry(key1, key2); - if (e != null) { - return e.value; - } - return null; - } - - /** - * Returns true if this map contains no key-value mappings - */ - public boolean isEmpty() { - return size == 0; - } - - /** - * Returns the number of mappings - */ - public int size() { - return size; - } - - /** - * Creates new entry - * - * @param hashCode - * @param key1 - * @param key2 - * @param value - * @param next - * @return - */ - Entry<E, K, V> createEntry(int hashCode, E key1, K key2, V value, - Entry<E, K, V> next) { - return new Entry<E, K, V>(hashCode, key1, key2, value, next); - } - - /** - * Creates entries iterator - * - * @return - */ - Iterator<Map.Entry<String, V>> createEntrySetIterator() { - return new EntryIteratorImpl(); - } - - /** - * Creates values iterator - * - * @return - */ - Iterator<V> createValueCollectionIterator() { - return new ValueIteratorImpl(); - } - - /** - * Entry implementation for the TwoKeyHashMap class - * - */ - public static class Entry<E, K, V> implements Map.Entry<String, V> { - int hash; - E key1; - K key2; - V value; - Entry<E, K, V> next; - - public Entry(int hash, E key1, K key2, V value, Entry<E, K, V> next) { - this.hash = hash; - this.key1 = key1; - this.key2 = key2; - this.value = value; - this.next = next; - } - - public String getKey() { - return key1.toString() + key2.toString(); - } - - public E getKey1() { - return key1; - } - - public K getKey2() { - return key2; - } - - public V getValue() { - return value; - } - - public V setValue(V value) { - V oldValue = this.value; - this.value = value; - return oldValue; - } - - public boolean equals(Object obj) { - if (!(obj instanceof Entry)) { - return false; - } - - Entry<?, ?, ?> e = (Entry<?, ?, ?>) obj; - Object getKey1 = e.getKey1(); - Object getKey2 = e.getKey2(); - Object getValue = e.getValue(); - if ((key1 == null && getKey1 != null) - || (key2 == null && getKey2 != null) - || (value == null && getValue != null) - || !key1.equals(e.getKey1()) || !key2.equals(e.getKey2()) - || !value.equals(getValue)) { - return false; - } - return true; - } - - public int hashCode() { - int hash1 = (key1 == null ? 0 : key1.hashCode()); - int hash2 = (key2 == null ? 0 : key2.hashCode()); - return (hash1 + hash2) ^ (value == null ? 0 : value.hashCode()); - } - - } - - class EntrySetImpl extends AbstractSet<Map.Entry<String, V>> { - public int size() { - return size; - } - - public void clear() { - TwoKeyHashMap.this.clear(); - } - - public boolean isEmpty() { - return size == 0; - } - - public boolean contains(Object obj) { - if (!(obj instanceof Entry)) { - return false; - } - - Entry<?, ?, ?> entry = (Entry<?, ?, ?>) obj; - Entry<E, K, V> entry2 = findEntry(entry.getKey1(), entry.getKey2()); - if (entry2 == null) { - return false; - } - Object value = entry.getValue(); - Object value2 = entry2.getValue(); - return value == null ? value2 == null : value.equals(value2); - } - - public boolean remove(Object obj) { - if (!(obj instanceof Entry)) { - return false; - } - return removeEntry(((Entry) obj).getKey1(), ((Entry) obj).getKey2()) != null; - } - - public Iterator<Map.Entry<String, V>> iterator() { - return createEntrySetIterator(); - } - } - - // Iterates Entries inside the Map - class EntryIteratorImpl implements Iterator<Map.Entry<String, V>> { - private int startModCount; - private boolean found; - private int curr = -1; - private int returned_index = -1; - private Entry<E, K, V> curr_entry; - private Entry<E, K, V> returned_entry; - - EntryIteratorImpl() { - startModCount = modCount; - } - - public boolean hasNext() { - if (found) { - return true; - } - if (curr_entry != null) { - curr_entry = curr_entry.next; - } - if (curr_entry == null) { - for (curr++; curr < arr.length && arr[curr] == null; curr++) { - } - - if (curr < arr.length) { - curr_entry = arr[curr]; - } - } - return found = (curr_entry != null); - } - - public Map.Entry<String, V> next() { - if (modCount != startModCount) { - throw new ConcurrentModificationException(); - } - if (!hasNext()) { - throw new NoSuchElementException(); - } - - found = false; - returned_index = curr; - returned_entry = curr_entry; - return (Map.Entry<String, V>) curr_entry; - } - - public void remove() { - if (returned_index == -1) { - throw new IllegalStateException(); - } - - if (modCount != startModCount) { - throw new ConcurrentModificationException(); - } - - Entry<E, K, V> p = null; - Entry<E, K, V> e = arr[returned_index]; - while (e != returned_entry) { - p = e; - e = e.next; - } - if (p != null) { - p.next = returned_entry.next; - } else { - arr[returned_index] = returned_entry.next; - } - size--; - modCount++; - startModCount++; - returned_index = -1; - } - } - - private final Entry<E, K, V> findEntry(Object key1, Object key2) { - if (key1 == null && key2 == null) { - return arr[arrSize]; - } - - int hash = key1.hashCode() + key2.hashCode(); - int index = (hash & 0x7fffffff) % arrSize; - Entry<E, K, V> e = arr[index]; - - while (e != null) { - if (hash == e.hash && key1.equals(e.getKey1()) - && key2.equals(e.getKey2())) { - return e; - } - e = e.next; - } - return null; - } - - // Removes entry - private final Entry<E, K, V> removeEntry(Object key1, Object key2) { - if (key1 == null && key2 == null) { - int index = arrSize; - if (arr[index] != null) { - Entry<E, K, V> ret = arr[index]; - arr[index] = null; - size--; - modCount++; - return ret; - } - return null; - } - - int hash = key1.hashCode() + key2.hashCode(); - int index = (hash & 0x7fffffff) % arrSize; - - Entry<E, K, V> e = arr[index]; - Entry<E, K, V> prev = e; - while (e != null) { - if (hash == e.hash && key1.equals(e.getKey1()) - && key2.equals(e.getKey2())) { - if (prev == e) { - arr[index] = e.next; - } else { - prev.next = e.next; - } - size--; - modCount++; - return e; - } - - prev = e; - e = e.next; - } - return null; - } - - /** - * An instance is returned by the values() call. - */ - class ValuesCollectionImpl extends AbstractCollection<V> { - public int size() { - return size; - } - - public void clear() { - TwoKeyHashMap.this.clear(); - } - - public boolean isEmpty() { - return size == 0; - } - - public Iterator<V> iterator() { - return createValueCollectionIterator(); - } - - public boolean contains(Object obj) { - return containsValue(obj); - } - } - - class ValueIteratorImpl implements Iterator<V> { - private EntryIteratorImpl itr; - - ValueIteratorImpl() { - this.itr = new EntryIteratorImpl(); - } - - public V next() { - return itr.next().getValue(); - } - - public void remove() { - itr.remove(); - } - - public boolean hasNext() { - return itr.hasNext(); - } - } -} diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java index 4b29363cd9..da8a1c3100 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ClientHandshakeImpl.java @@ -500,7 +500,7 @@ public class ClientHandshakeImpl extends HandshakeProtocol { // send certificate verify for all certificates except those containing // fixed DH parameters - if (clientCert != null && !clientKeyExchange.isEmpty()) { + if (clientCert != null && clientCert.certs.length > 0 && !clientKeyExchange.isEmpty()) { // Certificate verify String authType = clientKey.getAlgorithm(); DigitalSignature ds = new DigitalSignature(authType); diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java index 4c92952bb1..6334d41bae 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java @@ -914,12 +914,12 @@ public class OpenSSLSocketImpl } } - NativeCrypto.SSL_interrupt(sslNativePointer); - synchronized (this) { synchronized (writeLock) { synchronized (readLock) { + NativeCrypto.SSL_interrupt(sslNativePointer); + // Shut down the SSL connection, per se. try { if (handshakeStarted) { diff --git a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java index c5e1838c96..ff7fb3d53b 100644 --- a/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java +++ b/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/ServerHandshakeImpl.java @@ -659,7 +659,7 @@ public class ServerHandshakeImpl extends HandshakeProtocol { } else { if ((parameters.getNeedClientAuth() && clientCert == null) || clientKeyExchange == null - || (clientCert != null + || (clientCert != null && clientCert.certs.length > 0 && !clientKeyExchange.isEmpty() && certificateVerify == null)) { unexpectedMessage(); diff --git a/luni/src/main/native/JniException.cpp b/luni/src/main/native/JniException.cpp index 6626448104..c733db42ee 100644 --- a/luni/src/main/native/JniException.cpp +++ b/luni/src/main/native/JniException.cpp @@ -17,22 +17,27 @@ #include "JniException.h" #include "JNIHelp.h" -bool maybeThrowIcuException(JNIEnv* env, UErrorCode error) { +bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error) { if (U_SUCCESS(error)) { return false; } - const char* message = u_errorName(error); + const char* exceptionClass; switch (error) { case U_ILLEGAL_ARGUMENT_ERROR: - return jniThrowException(env, "java/lang/IllegalArgumentException", message); + exceptionClass = "java/lang/IllegalArgumentException"; + break; case U_INDEX_OUTOFBOUNDS_ERROR: case U_BUFFER_OVERFLOW_ERROR: - return jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", message); + exceptionClass = "java/lang/ArrayIndexOutOfBoundsException"; + break; case U_UNSUPPORTED_ERROR: - return jniThrowException(env, "java/lang/UnsupportedOperationException", message); + exceptionClass = "java/lang/UnsupportedOperationException"; + break; default: - return jniThrowRuntimeException(env, message); + exceptionClass = "java/lang/RuntimeException"; + break; } + return jniThrowExceptionFmt(env, exceptionClass, "%s failed: %s", function, u_errorName(error)); } void jniThrowExceptionWithErrno(JNIEnv* env, const char* exceptionClassName, int error) { diff --git a/luni/src/main/native/JniException.h b/luni/src/main/native/JniException.h index b3447d2da6..cece2aa00e 100644 --- a/luni/src/main/native/JniException.h +++ b/luni/src/main/native/JniException.h @@ -25,6 +25,6 @@ void jniThrowExceptionWithErrno(JNIEnv* env, const char* exceptionClassName, int void jniThrowOutOfMemoryError(JNIEnv* env, const char* message); void jniThrowSocketException(JNIEnv* env, int error); -bool maybeThrowIcuException(JNIEnv* env, UErrorCode error); +bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error); #endif // JNI_EXCEPTION_H_included diff --git a/luni/src/main/native/java_text_Bidi.cpp b/luni/src/main/native/java_text_Bidi.cpp index 93c02bbc63..01bca098d3 100644 --- a/luni/src/main/native/java_text_Bidi.cpp +++ b/luni/src/main/native/java_text_Bidi.cpp @@ -88,18 +88,18 @@ static void Bidi_ubidi_setPara(JNIEnv* env, jclass, jlong ptr, jcharArray text, } UErrorCode err = U_ZERO_ERROR; ubidi_setPara(data->uBiDi(), chars.get(), length, paraLevel, data->embeddingLevels(), &err); - maybeThrowIcuException(env, err); + maybeThrowIcuException(env, "ubidi_setPara", err); } static jlong Bidi_ubidi_setLine(JNIEnv* env, jclass, jlong ptr, jint start, jint limit) { UErrorCode status = U_ZERO_ERROR; UBiDi* sized = ubidi_openSized(limit - start, 0, &status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "ubidi_openSized", status)) { return 0; } UniquePtr<BiDiData> lineData(new BiDiData(sized)); ubidi_setLine(uBiDi(ptr), start, limit, lineData->uBiDi(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ubidi_setLine", status); return reinterpret_cast<uintptr_t>(lineData.release()); } @@ -118,7 +118,7 @@ static jbyte Bidi_ubidi_getParaLevel(JNIEnv*, jclass, jlong ptr) { static jbyteArray Bidi_ubidi_getLevels(JNIEnv* env, jclass, jlong ptr) { UErrorCode status = U_ZERO_ERROR; const UBiDiLevel* levels = ubidi_getLevels(uBiDi(ptr), &status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "ubidi_getLevels", status)) { return NULL; } int len = ubidi_getLength(uBiDi(ptr)); @@ -130,7 +130,7 @@ static jbyteArray Bidi_ubidi_getLevels(JNIEnv* env, jclass, jlong ptr) { static jint Bidi_ubidi_countRuns(JNIEnv* env, jclass, jlong ptr) { UErrorCode status = U_ZERO_ERROR; int count = ubidi_countRuns(uBiDi(ptr), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ubidi_countRuns", status); return count; } @@ -141,7 +141,7 @@ static jobjectArray Bidi_ubidi_getRuns(JNIEnv* env, jclass, jlong ptr) { UBiDi* ubidi = uBiDi(ptr); UErrorCode status = U_ZERO_ERROR; int runCount = ubidi_countRuns(ubidi, &status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "ubidi_countRuns", status)) { return NULL; } jmethodID bidiRunConstructor = env->GetMethodID(JniConstants::bidiRunClass, "<init>", "(III)V"); diff --git a/luni/src/main/native/java_util_regex_Matcher.cpp b/luni/src/main/native/java_util_regex_Matcher.cpp index 0f91bd5ebb..6116d2bbb3 100644 --- a/luni/src/main/native/java_util_regex_Matcher.cpp +++ b/luni/src/main/native/java_util_regex_Matcher.cpp @@ -71,7 +71,7 @@ public: if (mJavaInput) { mEnv->ReleaseStringChars(mJavaInput, mChars); } - maybeThrowIcuException(mEnv, mStatus); + maybeThrowIcuException(mEnv, "utext_close", mStatus); } RegexMatcher* operator->() { @@ -173,7 +173,7 @@ static jint Matcher_openImpl(JNIEnv* env, jclass, jint patternAddr) { RegexPattern* pattern = reinterpret_cast<RegexPattern*>(static_cast<uintptr_t>(patternAddr)); UErrorCode status = U_ZERO_ERROR; RegexMatcher* result = pattern->matcher(status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "RegexPattern::matcher", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(result)); } diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp index 5a07694d82..26e3e89875 100644 --- a/luni/src/main/native/libcore_icu_ICU.cpp +++ b/luni/src/main/native/libcore_icu_ICU.cpp @@ -543,9 +543,12 @@ static jobject ICU_getAvailableCurrencyCodes(JNIEnv* env, jclass) { UErrorCode status = U_ZERO_ERROR; UEnumeration* e(ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &status)); EnumerationCounter counter(uenum_count(e, &status)); + if (maybeThrowIcuException(env, "uenum_count", status)) { + return NULL; + } EnumerationGetter getter(e, &status); jobject result = toStringArray16(env, &counter, &getter); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "uenum_unext", status); uenum_close(e); return result; } diff --git a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp index d93c2294f7..58650814d0 100644 --- a/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp +++ b/luni/src/main/native/libcore_icu_NativeBreakIterator.cpp @@ -55,14 +55,14 @@ public: size_t charCount = env->GetStringLength(mString); UErrorCode status = U_ZERO_ERROR; ubrk_setText(mIt, mChars, charCount, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ubrk_setText", status); } BreakIteratorPeer* clone(JNIEnv* env) { UErrorCode status = U_ZERO_ERROR; jint bufferSize = U_BRK_SAFECLONE_BUFFERSIZE; UBreakIterator* it = ubrk_safeClone(mIt, NULL, &bufferSize, &status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "ubrk_safeClone", status)) { return NULL; } BreakIteratorPeer* result = new BreakIteratorPeer(it); @@ -120,7 +120,7 @@ static jint makeIterator(JNIEnv* env, jstring locale, UBreakIteratorType type) { return 0; } UBreakIterator* it = ubrk_open(type, localeChars.c_str(), NULL, 0, &status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "ubrk_open", status)) { return 0; } return (new BreakIteratorPeer(it))->toAddress(); diff --git a/luni/src/main/native/libcore_icu_NativeCollation.cpp b/luni/src/main/native/libcore_icu_NativeCollation.cpp index 3ed49e9b27..32b1cc4a75 100644 --- a/luni/src/main/native/libcore_icu_NativeCollation.cpp +++ b/luni/src/main/native/libcore_icu_NativeCollation.cpp @@ -50,7 +50,7 @@ static jint NativeCollation_compare(JNIEnv* env, jclass, jint address, jstring j static jint NativeCollation_getAttribute(JNIEnv* env, jclass, jint address, jint type) { UErrorCode status = U_ZERO_ERROR; jint result = ucol_getAttribute(toCollator(address), (UColAttribute) type, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_getAttribute", status); return result; } @@ -61,7 +61,7 @@ static jint NativeCollation_getCollationElementIterator(JNIEnv* env, jclass, jin } UErrorCode status = U_ZERO_ERROR; UCollationElements* result = ucol_openElements(toCollator(address), source.get(), source.size(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_openElements", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(result)); } @@ -106,7 +106,7 @@ static jbyteArray NativeCollation_getSortKey(JNIEnv* env, jclass, jint address, static jint NativeCollation_next(JNIEnv* env, jclass, jint address) { UErrorCode status = U_ZERO_ERROR; jint result = ucol_next(toCollationElements(address), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_next", status); return result; } @@ -117,7 +117,7 @@ static jint NativeCollation_openCollator(JNIEnv* env, jclass, jstring localeName } UErrorCode status = U_ZERO_ERROR; UCollator* c = ucol_open(localeChars.c_str(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_open", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } @@ -129,14 +129,14 @@ static jint NativeCollation_openCollatorFromRules(JNIEnv* env, jclass, jstring j UErrorCode status = U_ZERO_ERROR; UCollator* c = ucol_openRules(rules.get(), rules.size(), UColAttributeValue(mode), UCollationStrength(strength), NULL, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_openRules", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } static jint NativeCollation_previous(JNIEnv* env, jclass, jint address) { UErrorCode status = U_ZERO_ERROR; jint result = ucol_previous(toCollationElements(address), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_previous", status); return result; } @@ -148,20 +148,20 @@ static jint NativeCollation_safeClone(JNIEnv* env, jclass, jint address) { UErrorCode status = U_ZERO_ERROR; jint bufferSize = U_COL_SAFECLONE_BUFFERSIZE; UCollator* c = ucol_safeClone(toCollator(address), NULL, &bufferSize, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_safeClone", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(c)); } static void NativeCollation_setAttribute(JNIEnv* env, jclass, jint address, jint type, jint value) { UErrorCode status = U_ZERO_ERROR; ucol_setAttribute(toCollator(address), (UColAttribute)type, (UColAttributeValue)value, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_setAttribute", status); } static void NativeCollation_setOffset(JNIEnv* env, jclass, jint address, jint offset) { UErrorCode status = U_ZERO_ERROR; ucol_setOffset(toCollationElements(address), offset, &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_setOffset", status); } static void NativeCollation_setText(JNIEnv* env, jclass, jint address, jstring javaSource) { @@ -171,7 +171,7 @@ static void NativeCollation_setText(JNIEnv* env, jclass, jint address, jstring j } UErrorCode status = U_ZERO_ERROR; ucol_setText(toCollationElements(address), source.get(), source.size(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucol_setText", status); } static JNINativeMethod gMethods[] = { diff --git a/luni/src/main/native/libcore_icu_NativeConverter.cpp b/luni/src/main/native/libcore_icu_NativeConverter.cpp index 5b3761e798..6b08ee089f 100644 --- a/luni/src/main/native/libcore_icu_NativeConverter.cpp +++ b/luni/src/main/native/libcore_icu_NativeConverter.cpp @@ -74,7 +74,7 @@ static jlong NativeConverter_openConverter(JNIEnv* env, jclass, jstring converte } UErrorCode status = U_ZERO_ERROR; UConverter* cnv = ucnv_open(converterNameChars.c_str(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "ucnv_open", status); return reinterpret_cast<uintptr_t>(cnv); } @@ -82,24 +82,36 @@ static void NativeConverter_closeConverter(JNIEnv*, jclass, jlong address) { ucnv_close(toUConverter(address)); } +static bool shouldCodecThrow(jboolean flush, UErrorCode error) { + if (flush) { + return (error != U_BUFFER_OVERFLOW_ERROR && error != U_TRUNCATED_CHAR_FOUND); + } else { + return (error != U_BUFFER_OVERFLOW_ERROR && error != U_INVALID_CHAR_FOUND && error != U_ILLEGAL_CHAR_FOUND); + } +} + static jint NativeConverter_encode(JNIEnv* env, jclass, jlong address, jcharArray source, jint sourceEnd, jbyteArray target, jint targetEnd, jintArray data, jboolean flush) { UConverter* cnv = toUConverter(address); if (cnv == NULL) { + maybeThrowIcuException(env, "toUConverter", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedCharArrayRO uSource(env, source); if (uSource.get() == NULL) { + maybeThrowIcuException(env, "uSource", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedByteArrayRW uTarget(env, target); if (uTarget.get() == NULL) { + maybeThrowIcuException(env, "uTarget", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedIntArrayRW myData(env, data); if (myData.get() == NULL) { + maybeThrowIcuException(env, "myData", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } @@ -125,6 +137,11 @@ static jint NativeConverter_encode(JNIEnv* env, jclass, jlong address, myData[2] = invalidUCharCount; } } + + // Managed code handles some cases; throw all other errors. + if (shouldCodecThrow(flush, errorCode)) { + maybeThrowIcuException(env, "ucnv_fromUnicode", errorCode); + } return errorCode; } @@ -134,18 +151,22 @@ static jint NativeConverter_decode(JNIEnv* env, jclass, jlong address, UConverter* cnv = toUConverter(address); if (cnv == NULL) { + maybeThrowIcuException(env, "toUConverter", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedByteArrayRO uSource(env, source); if (uSource.get() == NULL) { + maybeThrowIcuException(env, "uSource", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedCharArrayRW uTarget(env, target); if (uTarget.get() == NULL) { + maybeThrowIcuException(env, "uTarget", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } ScopedIntArrayRW myData(env, data); if (myData.get() == NULL) { + maybeThrowIcuException(env, "myData", U_ILLEGAL_ARGUMENT_ERROR); return U_ILLEGAL_ARGUMENT_ERROR; } @@ -172,6 +193,10 @@ static jint NativeConverter_decode(JNIEnv* env, jclass, jlong address, } } + // Managed code handles some cases; throw all other errors. + if (shouldCodecThrow(flush, errorCode)) { + maybeThrowIcuException(env, "ucnv_toUnicode", errorCode); + } return errorCode; } @@ -387,11 +412,12 @@ static UConverterFromUCallback getFromUCallback(int32_t mode) { abort(); } -static jint NativeConverter_setCallbackEncode(JNIEnv* env, jclass, jlong address, +static void NativeConverter_setCallbackEncode(JNIEnv* env, jclass, jlong address, jint onMalformedInput, jint onUnmappableInput, jbyteArray javaReplacement) { UConverter* cnv = toUConverter(address); - if (!cnv) { - return U_ILLEGAL_ARGUMENT_ERROR; + if (cnv == NULL) { + maybeThrowIcuException(env, "toUConverter", U_ILLEGAL_ARGUMENT_ERROR); + return; } UConverterFromUCallback oldCallback = NULL; @@ -409,14 +435,15 @@ static jint NativeConverter_setCallbackEncode(JNIEnv* env, jclass, jlong address ScopedByteArrayRO replacementBytes(env, javaReplacement); if (replacementBytes.get() == NULL) { - return U_ILLEGAL_ARGUMENT_ERROR; + maybeThrowIcuException(env, "replacementBytes", U_ILLEGAL_ARGUMENT_ERROR); + return; } memcpy(callbackContext->replacementBytes, replacementBytes.get(), replacementBytes.size()); callbackContext->replacementByteCount = replacementBytes.size(); UErrorCode errorCode = U_ZERO_ERROR; ucnv_setFromUCallBack(cnv, CHARSET_ENCODER_CALLBACK, callbackContext, NULL, NULL, &errorCode); - return errorCode; + maybeThrowIcuException(env, "ucnv_setFromUCallBack", errorCode); } static void decoderIgnoreCallback(const void*, UConverterToUnicodeArgs*, const char*, int32_t, UConverterCallbackReason, UErrorCode* err) { @@ -469,11 +496,12 @@ static void CHARSET_DECODER_CALLBACK(const void* rawContext, UConverterToUnicode } } -static jint NativeConverter_setCallbackDecode(JNIEnv* env, jclass, jlong address, +static void NativeConverter_setCallbackDecode(JNIEnv* env, jclass, jlong address, jint onMalformedInput, jint onUnmappableInput, jstring javaReplacement) { UConverter* cnv = toUConverter(address); if (cnv == NULL) { - return U_ILLEGAL_ARGUMENT_ERROR; + maybeThrowIcuException(env, "toConverter", U_ILLEGAL_ARGUMENT_ERROR); + return; } UConverterToUCallback oldCallback; @@ -491,14 +519,15 @@ static jint NativeConverter_setCallbackDecode(JNIEnv* env, jclass, jlong address ScopedStringChars replacement(env, javaReplacement); if (replacement.get() == NULL) { - return U_ILLEGAL_ARGUMENT_ERROR; + maybeThrowIcuException(env, "replacement", U_ILLEGAL_ARGUMENT_ERROR); + return; } u_strncpy(callbackContext->replacementChars, replacement.get(), replacement.size()); callbackContext->replacementCharCount = replacement.size(); UErrorCode errorCode = U_ZERO_ERROR; ucnv_setToUCallBack(cnv, CHARSET_DECODER_CALLBACK, callbackContext, NULL, NULL, &errorCode); - return errorCode; + maybeThrowIcuException(env, "ucnv_setToUCallBack", errorCode); } static jfloat NativeConverter_getAveCharsPerByte(JNIEnv* env, jclass, jlong handle) { @@ -605,8 +634,8 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(NativeConverter, openConverter, "(Ljava/lang/String;)J"), NATIVE_METHOD(NativeConverter, resetByteToChar, "(J)V"), NATIVE_METHOD(NativeConverter, resetCharToByte, "(J)V"), - NATIVE_METHOD(NativeConverter, setCallbackDecode, "(JIILjava/lang/String;)I"), - NATIVE_METHOD(NativeConverter, setCallbackEncode, "(JII[B)I"), + NATIVE_METHOD(NativeConverter, setCallbackDecode, "(JIILjava/lang/String;)V"), + NATIVE_METHOD(NativeConverter, setCallbackEncode, "(JII[B)V"), }; void register_libcore_icu_NativeConverter(JNIEnv* env) { jniRegisterNativeMethods(env, "libcore/icu/NativeConverter", gMethods, NELEM(gMethods)); diff --git a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp index 1fe4055b63..dead1a8054 100644 --- a/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp +++ b/luni/src/main/native/libcore_icu_NativeDecimalFormat.cpp @@ -122,7 +122,7 @@ static jint NativeDecimalFormat_open(JNIEnv* env, jclass, jstring pattern0, if (fmt == NULL) { delete symbols; } - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "DecimalFormat::DecimalFormat", status); return static_cast<jint>(reinterpret_cast<uintptr_t>(fmt)); } @@ -144,7 +144,7 @@ static void NativeDecimalFormat_setSymbol(JNIEnv* env, jclass, jint addr, jint j UErrorCode status = U_ZERO_ERROR; UNumberFormatSymbol symbol = static_cast<UNumberFormatSymbol>(javaSymbol); unum_setSymbol(toUNumberFormat(addr), symbol, value.get(), value.size(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "unum_setSymbol", status); } static void NativeDecimalFormat_setAttribute(JNIEnv*, jclass, jint addr, jint javaAttr, jint value) { @@ -165,7 +165,7 @@ static void NativeDecimalFormat_setTextAttribute(JNIEnv* env, jclass, jint addr, UErrorCode status = U_ZERO_ERROR; UNumberFormatTextAttribute attr = static_cast<UNumberFormatTextAttribute>(javaAttr); unum_setTextAttribute(toUNumberFormat(addr), attr, value.get(), value.size(), &status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "unum_setTextAttribute", status); } static jstring NativeDecimalFormat_getTextAttribute(JNIEnv* env, jclass, jint addr, jint javaAttr) { @@ -184,7 +184,7 @@ static jstring NativeDecimalFormat_getTextAttribute(JNIEnv* env, jclass, jint ad chars.reset(new UChar[charCount]); charCount = unum_getTextAttribute(fmt, attr, chars.get(), charCount, &status); } - return maybeThrowIcuException(env, status) ? NULL : env->NewString(chars.get(), charCount); + return maybeThrowIcuException(env, "unum_getTextAttribute", status) ? NULL : env->NewString(chars.get(), charCount); } static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized, jstring pattern0) { @@ -195,12 +195,15 @@ static void NativeDecimalFormat_applyPatternImpl(JNIEnv* env, jclass, jint addr, ScopedJavaUnicodeString pattern(env, pattern0); DecimalFormat* fmt = toDecimalFormat(addr); UErrorCode status = U_ZERO_ERROR; + const char* function; if (localized) { + function = "DecimalFormat::applyLocalizedPattern"; fmt->applyLocalizedPattern(pattern.unicodeString(), status); } else { + function = "DecimalFormat::applyPattern"; fmt->applyPattern(pattern.unicodeString(), status); } - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, function, status); } static jstring NativeDecimalFormat_toPatternImpl(JNIEnv* env, jclass, jint addr, jboolean localized) { diff --git a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp index 58f460c9ff..693e944cf1 100644 --- a/luni/src/main/native/libcore_icu_NativeNormalizer.cpp +++ b/luni/src/main/native/libcore_icu_NativeNormalizer.cpp @@ -28,7 +28,7 @@ static jstring NativeNormalizer_normalizeImpl(JNIEnv* env, jclass, jstring s, ji UErrorCode status = U_ZERO_ERROR; UnicodeString dst; Normalizer::normalize(src.unicodeString(), mode, 0, dst, status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "Normalizer::normalize", status); return dst.isBogus() ? NULL : env->NewString(dst.getBuffer(), dst.length()); } @@ -37,7 +37,7 @@ static jboolean NativeNormalizer_isNormalizedImpl(JNIEnv* env, jclass, jstring s UNormalizationMode mode = static_cast<UNormalizationMode>(intMode); UErrorCode status = U_ZERO_ERROR; UBool result = Normalizer::isNormalized(src.unicodeString(), mode, status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "Normalizer::isNormalized", status); return result; } diff --git a/luni/src/main/native/libcore_icu_NativePluralRules.cpp b/luni/src/main/native/libcore_icu_NativePluralRules.cpp index a7164d0de2..df228ffcd0 100644 --- a/luni/src/main/native/libcore_icu_NativePluralRules.cpp +++ b/luni/src/main/native/libcore_icu_NativePluralRules.cpp @@ -34,7 +34,7 @@ static jint NativePluralRules_forLocaleImpl(JNIEnv* env, jclass, jstring localeN Locale locale = Locale::createFromName(ScopedUtfChars(env, localeName).c_str()); UErrorCode status = U_ZERO_ERROR; PluralRules* result = PluralRules::forLocale(locale, status); - maybeThrowIcuException(env, status); + maybeThrowIcuException(env, "PluralRules::forLocale", status); return reinterpret_cast<uintptr_t>(result); } diff --git a/luni/src/main/native/libcore_icu_TimeZones.cpp b/luni/src/main/native/libcore_icu_TimeZones.cpp index b543238bfc..15c18c5a03 100644 --- a/luni/src/main/native/libcore_icu_TimeZones.cpp +++ b/luni/src/main/native/libcore_icu_TimeZones.cpp @@ -43,14 +43,14 @@ static jobjectArray TimeZones_forCountryCode(JNIEnv* env, jclass, jstring countr } UErrorCode status = U_ZERO_ERROR; int32_t idCount = ids->count(status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "StringEnumeration::count", status)) { return NULL; } jobjectArray result = env->NewObjectArray(idCount, JniConstants::stringClass, NULL); for (int32_t i = 0; i < idCount; ++i) { const UnicodeString* id = ids->snext(status); - if (maybeThrowIcuException(env, status)) { + if (maybeThrowIcuException(env, "StringEnumeration::snext", status)) { return NULL; } ScopedLocalRef<jstring> idString(env, env->NewString(id->getBuffer(), id->length())); diff --git a/luni/src/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp index 4f1115f3e8..bffb4a5d0a 100644 --- a/luni/src/main/native/libcore_io_Memory.cpp +++ b/luni/src/main/native/libcore_io_Memory.cpp @@ -31,49 +31,114 @@ #if defined(__arm__) // 32-bit ARM has load/store alignment restrictions for longs. #define LONG_ALIGNMENT_MASK 0x3 +#define INT_ALIGNMENT_MASK 0x0 +#define SHORT_ALIGNMENT_MASK 0x0 +#elif defined(__mips__) +// MIPS has load/store alignment restrictions for longs, ints and shorts. +#define LONG_ALIGNMENT_MASK 0x7 +#define INT_ALIGNMENT_MASK 0x3 +#define SHORT_ALIGNMENT_MASK 0x1 #elif defined(__i386__) // x86 can load anything at any alignment. #define LONG_ALIGNMENT_MASK 0x0 +#define INT_ALIGNMENT_MASK 0x0 +#define SHORT_ALIGNMENT_MASK 0x0 #else #error unknown load/store alignment restrictions for this architecture #endif +// Use packed structures for access to unaligned data on targets with alignment restrictions. +// The compiler will generate appropriate code to access these structures without +// generating alignment exceptions. +template <typename T> static inline T get_unaligned(const T* address) { + struct unaligned { T v; } __attribute__ ((packed)); + const unaligned* p = reinterpret_cast<const unaligned*>(address); + return p->v; +} + +template <typename T> static inline void put_unaligned(T* address, T v) { + struct unaligned { T v; } __attribute__ ((packed)); + unaligned* p = reinterpret_cast<unaligned*>(address); + p->v = v; +} + template <typename T> static T cast(jint address) { return reinterpret_cast<T>(static_cast<uintptr_t>(address)); } +// Byte-swap 2 jshort values packed in a jint. +static inline jint bswap_2x16(jint v) { + // v is initially ABCD + v = bswap_32(v); // v=DCBA +#if defined(__mips__) && defined(__mips_isa_rev) && (__mips_isa_rev >= 2) + __asm__ volatile ("wsbh %0, %0" : "+r" (v)); // v=BADC +#else + v = (v << 16) | ((v >> 16) & 0xffff); // v=BADC +#endif + return v; +} + static inline void swapShorts(jshort* dstShorts, const jshort* srcShorts, size_t count) { // Do 32-bit swaps as long as possible... jint* dst = reinterpret_cast<jint*>(dstShorts); const jint* src = reinterpret_cast<const jint*>(srcShorts); - for (size_t i = 0; i < count / 2; ++i) { - jint v = *src++; // v=ABCD - v = bswap_32(v); // v=DCBA - jint v2 = (v << 16) | ((v >> 16) & 0xffff); // v=BADC - *dst++ = v2; - } - // ...with one last 16-bit swap if necessary. - if ((count % 2) != 0) { - jshort v = *reinterpret_cast<const jshort*>(src); - *reinterpret_cast<jshort*>(dst) = bswap_16(v); + + if ((reinterpret_cast<uintptr_t>(dst) & INT_ALIGNMENT_MASK) == 0 && + (reinterpret_cast<uintptr_t>(src) & INT_ALIGNMENT_MASK) == 0) { + for (size_t i = 0; i < count / 2; ++i) { + jint v = *src++; + *dst++ = bswap_2x16(v); + } + // ...with one last 16-bit swap if necessary. + if ((count % 2) != 0) { + jshort v = *reinterpret_cast<const jshort*>(src); + *reinterpret_cast<jshort*>(dst) = bswap_16(v); + } + } else { + for (size_t i = 0; i < count / 2; ++i) { + jint v = get_unaligned<jint>(src++); + put_unaligned<jint>(dst++, bswap_2x16(v)); + } + if ((count % 2) != 0) { + jshort v = get_unaligned<jshort>(reinterpret_cast<const jshort*>(src)); + put_unaligned<jshort>(reinterpret_cast<jshort*>(dst), bswap_16(v)); + } } } static inline void swapInts(jint* dstInts, const jint* srcInts, size_t count) { - for (size_t i = 0; i < count; ++i) { - jint v = *srcInts++; - *dstInts++ = bswap_32(v); + if ((reinterpret_cast<uintptr_t>(dstInts) & INT_ALIGNMENT_MASK) == 0 && + (reinterpret_cast<uintptr_t>(srcInts) & INT_ALIGNMENT_MASK) == 0) { + for (size_t i = 0; i < count; ++i) { + jint v = *srcInts++; + *dstInts++ = bswap_32(v); + } + } else { + for (size_t i = 0; i < count; ++i) { + jint v = get_unaligned<int>(srcInts++); + put_unaligned<jint>(dstInts++, bswap_32(v)); + } } } static inline void swapLongs(jlong* dstLongs, const jlong* srcLongs, size_t count) { jint* dst = reinterpret_cast<jint*>(dstLongs); const jint* src = reinterpret_cast<const jint*>(srcLongs); - for (size_t i = 0; i < count; ++i) { - jint v1 = *src++; - jint v2 = *src++; - *dst++ = bswap_32(v2); - *dst++ = bswap_32(v1); + if ((reinterpret_cast<uintptr_t>(dstLongs) & INT_ALIGNMENT_MASK) == 0 && + (reinterpret_cast<uintptr_t>(srcLongs) & INT_ALIGNMENT_MASK) == 0) { + for (size_t i = 0; i < count; ++i) { + jint v1 = *src++; + jint v2 = *src++; + *dst++ = bswap_32(v2); + *dst++ = bswap_32(v1); + } + } else { + for (size_t i = 0; i < count; ++i) { + jint v1 = get_unaligned<jint>(src++); + jint v2 = get_unaligned<jint>(src++); + put_unaligned<jint>(dst++, bswap_32(v2)); + put_unaligned<jint>(dst++, bswap_32(v1)); + } } } @@ -226,20 +291,11 @@ static void Memory_pokeInt(JNIEnv*, jclass, jint dstAddress, jint value, jboolea static jlong Memory_peekLong(JNIEnv*, jclass, jint srcAddress, jboolean swap) { jlong result; + const jlong* src = cast<const jlong*>(srcAddress); if ((srcAddress & LONG_ALIGNMENT_MASK) == 0) { - result = *cast<const jlong*>(srcAddress); + result = *src; } else { - // Handle unaligned memory access one byte at a time - const jbyte* src = cast<const jbyte*>(srcAddress); - jbyte* dst = reinterpret_cast<jbyte*>(&result); - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; + result = get_unaligned<jlong>(src); } if (swap) { result = bswap_64(result); @@ -248,23 +304,14 @@ static jlong Memory_peekLong(JNIEnv*, jclass, jint srcAddress, jboolean swap) { } static void Memory_pokeLong(JNIEnv*, jclass, jint dstAddress, jlong value, jboolean swap) { + jlong* dst = cast<jlong*>(dstAddress); if (swap) { value = bswap_64(value); } if ((dstAddress & LONG_ALIGNMENT_MASK) == 0) { - *cast<jlong*>(dstAddress) = value; + *dst = value; } else { - // Handle unaligned memory access one byte at a time - const jbyte* src = reinterpret_cast<const jbyte*>(&value); - jbyte* dst = cast<jbyte*>(dstAddress); - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; + put_unaligned<jlong>(dst, value); } } diff --git a/luni/src/main/native/libcore_io_OsConstants.cpp b/luni/src/main/native/libcore_io_OsConstants.cpp index 622ce6d95a..a1cfcf07cc 100644 --- a/luni/src/main/native/libcore_io_OsConstants.cpp +++ b/luni/src/main/native/libcore_io_OsConstants.cpp @@ -275,7 +275,9 @@ static void OsConstants_initConstants(JNIEnv* env, jclass c) { initConstant(env, c, "SIGRTMAX", SIGRTMAX); initConstant(env, c, "SIGRTMIN", SIGRTMIN); initConstant(env, c, "SIGSEGV", SIGSEGV); +#if defined(SIGSTKFLT) initConstant(env, c, "SIGSTKFLT", SIGSTKFLT); +#endif initConstant(env, c, "SIGSTOP", SIGSTOP); initConstant(env, c, "SIGSYS", SIGSYS); initConstant(env, c, "SIGTERM", SIGTERM); diff --git a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp index 687c57e09e..7dabc5d7c9 100644 --- a/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp +++ b/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp @@ -3933,7 +3933,7 @@ static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobjec } /** - * Interrupt any pending IO before closing the socket. + * Interrupt any pending I/O before closing the socket. */ static void NativeCrypto_SSL_interrupt( JNIEnv* env, jclass, jint ssl_address) { diff --git a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java index 85e360e03f..b374f56c3c 100644 --- a/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java +++ b/luni/src/test/java/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java @@ -16,15 +16,24 @@ package com.android.org.bouncycastle.jce.provider; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.FileNotFoundException; +import java.io.InputStream; import java.io.IOException; import java.math.BigInteger; +import java.security.cert.CertificateFactory; +import java.security.cert.Certificate; +import java.security.MessageDigest; +import java.security.PrivateKey; +import java.security.PublicKey; import java.util.HashSet; import java.util.Set; import junit.framework.TestCase; import com.android.org.bouncycastle.jce.provider.CertBlacklist; +import com.android.org.bouncycastle.crypto.Digest; +import com.android.org.bouncycastle.util.encoders.Base64; import com.android.org.bouncycastle.util.encoders.Hex; public class CertBlacklistTest extends TestCase { @@ -34,6 +43,25 @@ public class CertBlacklistTest extends TestCase { private Set<String> DEFAULT_PUBKEYS; private Set<String> DEFAULT_SERIALS; + public static final String TEST_CERT = "" + + "MIIDsjCCAxugAwIBAgIJAPLf2gS0zYGUMA0GCSqGSIb3DQEBBQUAMIGYMQswCQYDVQQGEwJVUzET" + + "MBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEPMA0GA1UEChMGR29v" + + "Z2xlMRAwDgYDVQQLEwd0ZXN0aW5nMRYwFAYDVQQDEw1HZXJlbXkgQ29uZHJhMSEwHwYJKoZIhvcN" + + "AQkBFhJnY29uZHJhQGdvb2dsZS5jb20wHhcNMTIwNzE0MTc1MjIxWhcNMTIwODEzMTc1MjIxWjCB" + + "mDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50YWluIFZp" + + "ZXcxDzANBgNVBAoTBkdvb2dsZTEQMA4GA1UECxMHdGVzdGluZzEWMBQGA1UEAxMNR2VyZW15IENv" + + "bmRyYTEhMB8GCSqGSIb3DQEJARYSZ2NvbmRyYUBnb29nbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUA" + + "A4GNADCBiQKBgQCjGGHATBYlmas+0sEECkno8LZ1KPglb/mfe6VpCT3GhSr+7br7NG/ZwGZnEhLq" + + "E7YIH4fxltHmQC3Tz+jM1YN+kMaQgRRjo/LBCJdOKaMwUbkVynAH6OYsKevjrOPk8lfM5SFQzJMG" + + "sA9+Tfopr5xg0BwZ1vA/+E3mE7Tr3M2UvwIDAQABo4IBADCB/TAdBgNVHQ4EFgQUhzkS9E6G+x8W" + + "L4EsmRjDxu28tHUwgc0GA1UdIwSBxTCBwoAUhzkS9E6G+x8WL4EsmRjDxu28tHWhgZ6kgZswgZgx" + + "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3" + + "MQ8wDQYDVQQKEwZHb29nbGUxEDAOBgNVBAsTB3Rlc3RpbmcxFjAUBgNVBAMTDUdlcmVteSBDb25k" + + "cmExITAfBgkqhkiG9w0BCQEWEmdjb25kcmFAZ29vZ2xlLmNvbYIJAPLf2gS0zYGUMAwGA1UdEwQF" + + "MAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAYiugFDmbDOQ2U/+mqNt7o8ftlEo9SJrns6O8uTtK6AvR" + + "orDrR1AXTXkuxwLSbmVfedMGOZy7Awh7iZa8hw5x9XmUudfNxvmrKVEwGQY2DZ9PXbrnta/dwbhK" + + "mWfoepESVbo7CKIhJp8gRW0h1Z55ETXD57aGJRvQS4pxkP8ANhM="; + public CertBlacklistTest() throws IOException { tmpFile = File.createTempFile("test", ""); DEFAULT_PUBKEYS = getDefaultPubkeys(); @@ -64,7 +92,7 @@ public class CertBlacklistTest extends TestCase { // convert the results to a hashset of strings Set<String> results = new HashSet<String>(); for (byte[] value: arr) { - results.add(new String(Hex.encode(value))); + results.add(new String(value)); } return results; } @@ -82,6 +110,13 @@ public class CertBlacklistTest extends TestCase { return results; } + private String getHash(PublicKey publicKey) throws Exception { + byte[] encoded = publicKey.getEncoded(); + MessageDigest digest = MessageDigest.getInstance("SHA1"); + byte[] hexlifiedHash = Hex.encode(digest.digest(encoded)); + return new String(hexlifiedHash); + } + private Set<String> getDefaultPubkeys() throws IOException { return getPubkeyBlacklist(""); } @@ -116,7 +151,14 @@ public class CertBlacklistTest extends TestCase { blacklistToFile(result.toString()); } - public void testPubkeyBlacklistLegit() throws IOException { + private PublicKey createPublicKey(String cert) throws Exception { + byte[] derCert = Base64.decode(cert.getBytes()); + InputStream istream = new ByteArrayInputStream(derCert); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + return cf.generateCertificate(istream).getPublicKey(); + } + + public void testPubkeyBlacklistLegit() throws Exception { // build the blacklist HashSet<String> bl = new HashSet<String>(); bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc"); @@ -128,6 +170,34 @@ public class CertBlacklistTest extends TestCase { assertEquals(bl, getCurrentPubkeyBlacklist()); } + public void testLegitPubkeyIsntBlacklisted() throws Exception { + // build the public key + PublicKey pk = createPublicKey(TEST_CERT); + // write that to the test blacklist + writeBlacklist(new HashSet<String>()); + // set our blacklist path + CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), + CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH); + // check to make sure it isn't blacklisted + assertEquals(bl.isPublicKeyBlackListed(pk), false); + } + + public void testPubkeyIsBlacklisted() throws Exception { + // build the public key + PublicKey pk = createPublicKey(TEST_CERT); + // get its hash + String hash = getHash(pk); + // write that to the test blacklist + HashSet<String> testBlackList = new HashSet<String>(); + testBlackList.add(hash); + writeBlacklist(testBlackList); + // set our blacklist path + CertBlacklist bl = new CertBlacklist(tmpFile.getCanonicalPath(), + CertBlacklist.DEFAULT_SERIAL_BLACKLIST_PATH); + // check to make sure it isn't blacklited + assertTrue(bl.isPublicKeyBlackListed(pk)); + } + public void testSerialBlacklistLegit() throws IOException { // build the blacklist HashSet<String> bl = new HashSet<String>(); diff --git a/luni/src/test/java/libcore/io/DiskLruCacheTest.java b/luni/src/test/java/libcore/io/DiskLruCacheTest.java index 03a6932069..2796b65854 100644 --- a/luni/src/test/java/libcore/io/DiskLruCacheTest.java +++ b/luni/src/test/java/libcore/io/DiskLruCacheTest.java @@ -349,6 +349,28 @@ public final class DiskLruCacheTest extends TestCase { creator2.commit(); } + public void testCreateNewEntryWithMissingFileAborts() throws Exception { + DiskLruCache.Editor creator = cache.edit("k1"); + creator.set(0, "A"); + creator.set(1, "A"); + assertTrue(getDirtyFile("k1", 0).exists()); + assertTrue(getDirtyFile("k1", 1).exists()); + assertTrue(getDirtyFile("k1", 0).delete()); + assertFalse(getDirtyFile("k1", 0).exists()); + creator.commit(); // silently abort if file does not exist due to I/O issue + + assertFalse(getCleanFile("k1", 0).exists()); + assertFalse(getCleanFile("k1", 1).exists()); + assertFalse(getDirtyFile("k1", 0).exists()); + assertFalse(getDirtyFile("k1", 1).exists()); + assertNull(cache.get("k1")); + + DiskLruCache.Editor creator2 = cache.edit("k1"); + creator2.set(0, "B"); + creator2.set(1, "C"); + creator2.commit(); + } + public void testRevertWithTooFewValues() throws Exception { DiskLruCache.Editor creator = cache.edit("k1"); creator.set(1, "A"); @@ -805,4 +827,4 @@ public final class DiskLruCacheTest extends TestCase { assertTrue(getCleanFile(key, 1).exists()); snapshot.close(); } -}
\ No newline at end of file +} diff --git a/luni/src/test/java/libcore/io/MemoryTest.java b/luni/src/test/java/libcore/io/MemoryTest.java index a533f15c9f..9a596fb2e6 100644 --- a/luni/src/test/java/libcore/io/MemoryTest.java +++ b/luni/src/test/java/libcore/io/MemoryTest.java @@ -18,6 +18,7 @@ package libcore.io; import dalvik.system.VMRuntime; +import java.util.Arrays; import junit.framework.TestCase; public class MemoryTest extends TestCase { @@ -28,65 +29,116 @@ public class MemoryTest extends TestCase { swappedValues[i] = Integer.reverseBytes(values[i]); } - int scale = 4; + int scale = SizeOf.INT; VMRuntime runtime = VMRuntime.getRuntime(); - byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length); - int ptr = (int) runtime.addressOf(array); + byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); + int base_ptr = (int) runtime.addressOf(array); - // Regular copy. - Memory.pokeIntArray(ptr, values, 0, values.length, false); - assertIntsEqual(values, ptr, false); - assertIntsEqual(swappedValues, ptr, true); + for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { + int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. + Arrays.fill(array, (byte) 0); - // Swapped copy. - Memory.pokeIntArray(ptr, values, 0, values.length, true); - assertIntsEqual(values, ptr, true); - assertIntsEqual(swappedValues, ptr, false); + // Regular copy. + Memory.pokeIntArray(ptr, values, 0, values.length, false); + assertIntsEqual(values, ptr, false); + assertIntsEqual(swappedValues, ptr, true); - // Swapped copies of slices (to ensure we test non-zero offsets). - for (int i = 0; i < values.length; ++i) { - Memory.pokeIntArray(ptr + i * scale, values, i, 1, true); + // Swapped copy. + Memory.pokeIntArray(ptr, values, 0, values.length, true); + assertIntsEqual(values, ptr, true); + assertIntsEqual(swappedValues, ptr, false); + + // Swapped copies of slices (to ensure we test non-zero offsets). + for (int i = 0; i < values.length; ++i) { + Memory.pokeIntArray(ptr + i * scale, values, i, 1, true); + } + assertIntsEqual(values, ptr, true); + assertIntsEqual(swappedValues, ptr, false); } - assertIntsEqual(values, ptr, true); - assertIntsEqual(swappedValues, ptr, false); } private void assertIntsEqual(int[] expectedValues, int ptr, boolean swap) { for (int i = 0; i < expectedValues.length; ++i) { - assertEquals(expectedValues[i], Memory.peekInt(ptr + 4 * i, swap)); + assertEquals(expectedValues[i], Memory.peekInt(ptr + SizeOf.INT * i, swap)); } } + public void testSetLongArray() { + long[] values = { 0x1020304050607080L, 0xffeeddccbbaa9988L }; + long[] swappedValues = new long[values.length]; + for (int i = 0; i < values.length; ++i) { + swappedValues[i] = Long.reverseBytes(values[i]); + } + + int scale = SizeOf.LONG; + VMRuntime runtime = VMRuntime.getRuntime(); + byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); + int base_ptr = (int) runtime.addressOf(array); + + for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { + int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. + Arrays.fill(array, (byte) 0); + + // Regular copy. + Memory.pokeLongArray(ptr, values, 0, values.length, false); + assertLongsEqual(values, ptr, false); + assertLongsEqual(swappedValues, ptr, true); + + // Swapped copy. + Memory.pokeLongArray(ptr, values, 0, values.length, true); + assertLongsEqual(values, ptr, true); + assertLongsEqual(swappedValues, ptr, false); + + // Swapped copies of slices (to ensure we test non-zero offsets). + for (int i = 0; i < values.length; ++i) { + Memory.pokeLongArray(ptr + i * scale, values, i, 1, true); + } + assertLongsEqual(values, ptr, true); + assertLongsEqual(swappedValues, ptr, false); + } + } + + private void assertLongsEqual(long[] expectedValues, int ptr, boolean swap) { + for (int i = 0; i < expectedValues.length; ++i) { + assertEquals(expectedValues[i], Memory.peekLong(ptr + SizeOf.LONG * i, swap)); + } + } + public void testSetShortArray() { short[] values = { 0x0001, 0x0020, 0x0300, 0x4000 }; short[] swappedValues = { 0x0100, 0x2000, 0x0003, 0x0040 }; - int scale = 2; + int scale = SizeOf.SHORT; VMRuntime runtime = VMRuntime.getRuntime(); - byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length); - int ptr = (int) runtime.addressOf(array); + byte[] array = (byte[]) runtime.newNonMovableArray(byte.class, scale * values.length + 1); + int base_ptr = (int) runtime.addressOf(array); - // Regular copy. Memset first so we start from a known state. - Memory.pokeShortArray(ptr, values, 0, values.length, false); - assertShortsEqual(values, ptr, false); - assertShortsEqual(swappedValues, ptr, true); + for (int ptr_offset = 0; ptr_offset < 2; ++ptr_offset) { + int ptr = base_ptr + ptr_offset; // To test aligned and unaligned accesses. + Arrays.fill(array, (byte) 0); - // Swapped copy. - Memory.pokeShortArray(ptr, values, 0, values.length, true); - assertShortsEqual(values, ptr, true); - assertShortsEqual(swappedValues, ptr, false); + // Regular copy. + Memory.pokeShortArray(ptr, values, 0, values.length, false); + assertShortsEqual(values, ptr, false); + assertShortsEqual(swappedValues, ptr, true); - // Swapped copies of slices (to ensure we test non-zero offsets). - for (int i = 0; i < values.length; ++i) { - Memory.pokeShortArray(ptr + i * scale, values, i, 1, true); + // Swapped copy. + Memory.pokeShortArray(ptr, values, 0, values.length, true); + assertShortsEqual(values, ptr, true); + assertShortsEqual(swappedValues, ptr, false); + + // Swapped copies of slices (to ensure we test non-zero offsets). + for (int i = 0; i < values.length; ++i) { + Memory.pokeShortArray(ptr + i * scale, values, i, 1, true); + } + assertShortsEqual(values, ptr, true); + assertShortsEqual(swappedValues, ptr, false); } - assertShortsEqual(values, ptr, true); - assertShortsEqual(swappedValues, ptr, false); } private void assertShortsEqual(short[] expectedValues, int ptr, boolean swap) { for (int i = 0; i < expectedValues.length; ++i) { - assertEquals(expectedValues[i], Memory.peekShort(ptr + 2 * i, swap)); + assertEquals(expectedValues[i], Memory.peekShort(ptr + SizeOf.SHORT * i, swap)); } } } diff --git a/luni/src/test/java/libcore/java/io/FileTest.java b/luni/src/test/java/libcore/java/io/FileTest.java index 3cf621e972..b2391ac0c9 100644 --- a/luni/src/test/java/libcore/java/io/FileTest.java +++ b/luni/src/test/java/libcore/java/io/FileTest.java @@ -225,4 +225,45 @@ public class FileTest extends junit.framework.TestCase { assertTrue(new File("/").getTotalSpace() >= 0); assertTrue(new File("/").getUsableSpace() >= 0); } + + public void test_mkdirs() throws Exception { + // Set up a directory to test in. + File base = createTemporaryDirectory(); + + // mkdirs returns true only if it _creates_ a directory. + // So we get false for a directory that already exists... + assertTrue(base.exists()); + assertFalse(base.mkdirs()); + // But true if we had to create something. + File a = new File(base, "a"); + assertFalse(a.exists()); + assertTrue(a.mkdirs()); + assertTrue(a.exists()); + + // Test the recursive case where we need to create multiple parents. + File b = new File(a, "b"); + File c = new File(b, "c"); + File d = new File(c, "d"); + assertTrue(a.exists()); + assertFalse(b.exists()); + assertFalse(c.exists()); + assertFalse(d.exists()); + assertTrue(d.mkdirs()); + assertTrue(a.exists()); + assertTrue(b.exists()); + assertTrue(c.exists()); + assertTrue(d.exists()); + + // Test the case where the 'directory' exists as a file. + File existsAsFile = new File(base, "existsAsFile"); + existsAsFile.createNewFile(); + assertTrue(existsAsFile.exists()); + assertFalse(existsAsFile.mkdirs()); + + // Test the case where the parent exists as a file. + File badParent = new File(existsAsFile, "sub"); + assertTrue(existsAsFile.exists()); + assertFalse(badParent.exists()); + assertFalse(badParent.mkdirs()); + } } diff --git a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java index e973b8fe02..e1f51bd89a 100644..100755 --- a/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java +++ b/luni/src/test/java/libcore/java/io/InterruptedStreamTest.java @@ -28,6 +28,7 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.channels.ClosedByInterruptException; +import java.nio.channels.ClosedChannelException; import java.nio.channels.Pipe; import java.nio.channels.ReadableByteChannel; import java.nio.channels.ServerSocketChannel; @@ -93,7 +94,7 @@ public final class InterruptedStreamTest extends TestCase { public void testInterruptWritableSocketChannel() throws Exception { sockets = newSocketChannelPair(); - testInterruptReadableChannel(sockets[0].getChannel()); + testInterruptWritableChannel(sockets[0].getChannel()); } /** @@ -166,6 +167,7 @@ public final class InterruptedStreamTest extends TestCase { channel.write(ByteBuffer.allocate(BUFFER_SIZE)); } } catch (ClosedByInterruptException expected) { + } catch (ClosedChannelException expected) { } } @@ -173,6 +175,10 @@ public final class InterruptedStreamTest extends TestCase { final Thread toInterrupt = Thread.currentThread(); new Thread(new Runnable () { @Override public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException ex) { + } toInterrupt.interrupt(); } }).start(); diff --git a/luni/src/test/java/libcore/java/io/SerializationTest.java b/luni/src/test/java/libcore/java/io/SerializationTest.java index 434dd56d3d..d452c110bd 100644 --- a/luni/src/test/java/libcore/java/io/SerializationTest.java +++ b/luni/src/test/java/libcore/java/io/SerializationTest.java @@ -18,6 +18,8 @@ package libcore.java.io; import java.io.IOException; import java.io.InvalidClassException; +import java.io.ObjectStreamClass; +import java.io.ObjectStreamField; import java.io.Serializable; import junit.framework.TestCase; import libcore.util.SerializationTester; @@ -26,6 +28,13 @@ public final class SerializationTest extends TestCase { // http://b/4471249 public void testSerializeFieldMadeTransient() throws Exception { + // Does ObjectStreamClass have the right idea? + ObjectStreamClass osc = ObjectStreamClass.lookup(FieldMadeTransient.class); + ObjectStreamField[] fields = osc.getFields(); + assertEquals(1, fields.length); + assertEquals("nonTransientInt", fields[0].getName()); + assertEquals(int.class, fields[0].getType()); + // this was created by serializing a FieldMadeTransient with a non-0 transientInt String s = "aced0005737200346c6962636f72652e6a6176612e696f2e53657269616c697a6174696f6e54657" + "374244669656c644d6164655472616e7369656e74000000000000000002000149000c7472616e736" @@ -37,6 +46,7 @@ public final class SerializationTest extends TestCase { static class FieldMadeTransient implements Serializable { private static final long serialVersionUID = 0L; private transient int transientInt; + private int nonTransientInt; } public void testSerialVersionUidChange() throws Exception { diff --git a/luni/src/test/java/libcore/java/lang/StringTest.java b/luni/src/test/java/libcore/java/lang/StringTest.java index 42a7aada76..99dba49f2d 100644 --- a/luni/src/test/java/libcore/java/lang/StringTest.java +++ b/luni/src/test/java/libcore/java/lang/StringTest.java @@ -91,10 +91,24 @@ public class StringTest extends TestCase { } } - public void testStringFromCharset() { - Charset cs = Charset.forName("UTF-8"); - byte[] bytes = new byte[] {(byte) 'h', (byte) 'i'}; - assertEquals("hi", new String(bytes, cs)); + public void testString_BII() throws Exception { + byte[] bytes = "xa\u0666bx".getBytes("UTF-8"); + assertEquals("a\u0666b", new String(bytes, 1, bytes.length - 2)); + } + + public void testString_BIIString() throws Exception { + byte[] bytes = "xa\u0666bx".getBytes("UTF-8"); + assertEquals("a\u0666b", new String(bytes, 1, bytes.length - 2, "UTF-8")); + } + + public void testString_BIICharset() throws Exception { + byte[] bytes = "xa\u0666bx".getBytes("UTF-8"); + assertEquals("a\u0666b", new String(bytes, 1, bytes.length - 2, Charset.forName("UTF-8"))); + } + + public void testString_BCharset() throws Exception { + byte[] bytes = "a\u0666b".getBytes("UTF-8"); + assertEquals("a\u0666b", new String(bytes, Charset.forName("UTF-8"))); } public void testStringFromCharset_MaliciousCharset() { diff --git a/luni/src/test/java/libcore/java/net/OldDatagramPacketTest.java b/luni/src/test/java/libcore/java/net/OldDatagramPacketTest.java index a77a44d86a..8ca40672da 100644 --- a/luni/src/test/java/libcore/java/net/OldDatagramPacketTest.java +++ b/luni/src/test/java/libcore/java/net/OldDatagramPacketTest.java @@ -21,71 +21,40 @@ import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; -import tests.support.Support_PortManager; public class OldDatagramPacketTest extends junit.framework.TestCase { - DatagramPacket dp; - - volatile boolean started = false; - - public void test_getPort() throws IOException { - dp = new DatagramPacket("Hello".getBytes(), 5, InetAddress.getLocalHost(), 1000); + public void test_getPort() throws Exception { + DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5, InetAddress.getLocalHost(), 1000); assertEquals("Incorrect port returned", 1000, dp.getPort()); - InetAddress localhost = InetAddress.getByName("localhost"); - - int[] ports = Support_PortManager.getNextPortsForUDP(2); - final int port = ports[0]; - final Object lock = new Object(); - + final DatagramSocket ss = new DatagramSocket(); Thread thread = new Thread(new Runnable() { public void run() { - DatagramSocket socket = null; try { - socket = new DatagramSocket(port); - synchronized (lock) { - started = true; - lock.notifyAll(); - } - socket.setSoTimeout(3000); - DatagramPacket packet = new DatagramPacket(new byte[256], - 256); - socket.receive(packet); - socket.send(packet); - socket.close(); + DatagramPacket packet = new DatagramPacket(new byte[256], 256); + ss.setSoTimeout(3000); + ss.receive(packet); + ss.send(packet); } catch (IOException e) { System.out.println("thread exception: " + e); - if (socket != null) - socket.close(); } } }); thread.start(); - DatagramSocket socket = null; + DatagramSocket cs = new DatagramSocket(); try { - socket = new DatagramSocket(ports[1]); - socket.setSoTimeout(3000); - DatagramPacket packet = new DatagramPacket(new byte[] { 1, 2, 3, 4, - 5, 6 }, 6, localhost, port); - synchronized (lock) { - try { - if (!started) - lock.wait(); - } catch (InterruptedException e) { - fail(e.toString()); - } - } - socket.send(packet); - socket.receive(packet); - socket.close(); - assertTrue("datagram received wrong port: " + packet.getPort(), - packet.getPort() == port); + byte[] bytes = new byte[] { 1, 2, 3, 4, 5, 6 }; + DatagramPacket packet = new DatagramPacket(bytes, 6, InetAddress.getByName("localhost"), ss.getLocalPort()); + cs.send(packet); + cs.setSoTimeout(3000); + cs.receive(packet); + cs.close(); + assertEquals(packet.getPort(), ss.getLocalPort()); } finally { - if (socket != null) { - socket.close(); - } + cs.close(); + ss.close(); } } @@ -104,7 +73,7 @@ public class OldDatagramPacketTest extends junit.framework.TestCase { } public void test_setData$BII() { - dp = new DatagramPacket("Hello".getBytes(), 5); + DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5); try { dp.setData(null, 2, 3); fail("NullPointerException was not thrown."); @@ -113,7 +82,7 @@ public class OldDatagramPacketTest extends junit.framework.TestCase { } public void test_setData$B() { - dp = new DatagramPacket("Hello".getBytes(), 5); + DatagramPacket dp = new DatagramPacket("Hello".getBytes(), 5); try { dp.setData(null); fail("NullPointerException was not thrown."); diff --git a/luni/src/test/java/libcore/java/net/OldServerSocketTest.java b/luni/src/test/java/libcore/java/net/OldServerSocketTest.java index cf35489109..6518897ae3 100644 --- a/luni/src/test/java/libcore/java/net/OldServerSocketTest.java +++ b/luni/src/test/java/libcore/java/net/OldServerSocketTest.java @@ -33,7 +33,6 @@ import java.nio.channels.IllegalBlockingModeException; import java.nio.channels.ServerSocketChannel; import java.security.Permission; import java.util.Properties; -import tests.support.Support_PortManager; public class OldServerSocketTest extends OldSocketTestCase { @@ -86,10 +85,9 @@ public class OldServerSocketTest extends OldSocketTestCase { } public void test_ConstructorII() throws IOException { - int freePortNumber = Support_PortManager.getNextPort(); - s = new ServerSocket(freePortNumber, 1); + s = new ServerSocket(0, 1); s.setSoTimeout(2000); - startClient(freePortNumber); + startClient(s.getLocalPort()); sconn = s.accept(); sconn.close(); s.close(); @@ -133,10 +131,9 @@ public class OldServerSocketTest extends OldSocketTestCase { } public void test_ConstructorI() throws Exception { - int portNumber = Support_PortManager.getNextPort(); - s = new ServerSocket(portNumber); + s = new ServerSocket(0); try { - new ServerSocket(portNumber); + new ServerSocket(s.getLocalPort()); fail("IOException was not thrown."); } catch(IOException ioe) { //expected @@ -162,11 +159,9 @@ public class OldServerSocketTest extends OldSocketTestCase { } public void test_ConstructorIILjava_net_InetAddress() throws IOException { - int freePortNumber = Support_PortManager.getNextPort(); - - ServerSocket ss = new ServerSocket(freePortNumber, 10, InetAddress.getLocalHost()); + ServerSocket ss = new ServerSocket(0, 10, InetAddress.getLocalHost()); try { - new ServerSocket(freePortNumber, 10, InetAddress.getLocalHost()); + new ServerSocket(ss.getLocalPort(), 10, InetAddress.getLocalHost()); fail("IOException was not thrown."); } catch(IOException expected) { } @@ -217,9 +212,7 @@ public class OldServerSocketTest extends OldSocketTestCase { } public void test_accept() throws IOException { - int portNumber = Support_PortManager.getNextPort(); - - ServerSocket newSocket = new ServerSocket(portNumber); + ServerSocket newSocket = new ServerSocket(0); newSocket.setSoTimeout(500); try { Socket accepted = newSocket.accept(); diff --git a/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java b/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java index 2646f986d5..3a5608c7fa 100644 --- a/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java +++ b/luni/src/test/java/libcore/java/net/OldURLClassLoaderTest.java @@ -35,7 +35,6 @@ import java.util.List; import java.util.jar.Manifest; import org.apache.harmony.security.tests.support.TestCertUtils; import tests.support.Support_Configuration; -import tests.support.Support_PortManager; import tests.support.Support_TestWebData; import tests.support.Support_TestWebServer; import tests.support.resource.Support_Resources; @@ -210,13 +209,12 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase { @SideEffect("Support_TestWebServer requires isolation.") public void test_findResourceLjava_lang_String() throws Exception { - int port = Support_PortManager.getNextPort(); File tmp = File.createTempFile("test", ".txt"); Support_TestWebServer server = new Support_TestWebServer(); try { - server.initServer(port, tmp.getAbsolutePath(), "text/html"); + int port = server.initServer(tmp.getAbsolutePath(), "text/html"); URL[] urls = { new URL("http://localhost:" + port + "/") }; ucl = new URLClassLoader(urls); @@ -244,9 +242,8 @@ public class OldURLClassLoaderTest extends junit.framework.TestCase { tempFile2.deleteOnExit(); Support_TestWebServer server = new Support_TestWebServer(); - int port = Support_PortManager.getNextPort(); try { - server.initServer(port, false); + int port = server.initServer(); String tempPath1 = tempFile1.getParentFile().getAbsolutePath() + "/"; InputStream is = getClass().getResourceAsStream( diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java index 347242a139..a1747fab2a 100644 --- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java +++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java @@ -24,7 +24,9 @@ import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END; import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_START; import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_INPUT_AT_END; import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_OUTPUT_AT_END; +import dalvik.system.CloseGuard; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -76,6 +78,7 @@ import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import junit.framework.TestCase; +import libcore.java.lang.ref.FinalizationTester; import libcore.java.security.TestKeyStore; import libcore.javax.net.ssl.TestSSLContext; import libcore.net.http.HttpResponseCache; @@ -818,6 +821,50 @@ public final class URLConnectionTest extends TestCase { assertEquals(200, connection.getResponseCode()); } + public void testDisconnectAfterOnlyResponseCodeCausesNoCloseGuardWarning() throws IOException { + CloseGuardGuard guard = new CloseGuardGuard(); + try { + server.enqueue(new MockResponse() + .setBody(gzip("ABCABCABC".getBytes("UTF-8"))) + .addHeader("Content-Encoding: gzip")); + server.play(); + + HttpURLConnection connection = (HttpURLConnection) server.getUrl("/").openConnection(); + assertEquals(200, connection.getResponseCode()); + connection.disconnect(); + connection = null; + assertFalse(guard.wasCloseGuardCalled()); + } finally { + guard.close(); + } + } + + public static class CloseGuardGuard implements Closeable, CloseGuard.Reporter { + private final CloseGuard.Reporter oldReporter = CloseGuard.getReporter(); + + private AtomicBoolean closeGuardCalled = new AtomicBoolean(); + + public CloseGuardGuard() { + CloseGuard.setReporter(this); + } + + @Override public void report(String message, Throwable allocationSite) { + oldReporter.report(message, allocationSite); + closeGuardCalled.set(true); + } + + public boolean wasCloseGuardCalled() { + // FinalizationTester.induceFinalization(); + close(); + return closeGuardCalled.get(); + } + + @Override public void close() { + CloseGuard.setReporter(oldReporter); + } + + } + public void testDefaultRequestProperty() throws Exception { URLConnection.setDefaultRequestProperty("X-testSetDefaultRequestProperty", "A"); assertNull(URLConnection.getDefaultRequestProperty("X-setDefaultRequestProperty")); diff --git a/luni/src/test/java/libcore/java/nio/BufferTest.java b/luni/src/test/java/libcore/java/nio/BufferTest.java index 06a8e942ca..2a895fc9d6 100644 --- a/luni/src/test/java/libcore/java/nio/BufferTest.java +++ b/luni/src/test/java/libcore/java/nio/BufferTest.java @@ -675,4 +675,80 @@ public class BufferTest extends TestCase { } assertFalse(bb.hasArray()); } + + public void testBug6085292() { + ByteBuffer b = ByteBuffer.allocateDirect(1); + + try { + b.asCharBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asCharBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + + try { + b.asDoubleBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asDoubleBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + + try { + b.asFloatBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asFloatBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + + try { + b.asIntBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asIntBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + + try { + b.asLongBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asLongBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + + try { + b.asShortBuffer().get(); + fail(); + } catch (BufferUnderflowException expected) { + } + try { + b.asShortBuffer().get(0); + fail(); + } catch (IndexOutOfBoundsException expected) { + assertTrue(expected.getMessage().contains("limit=0")); + } + } } diff --git a/luni/src/test/java/libcore/java/nio/channels/OldServerSocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/OldServerSocketChannelTest.java index fb635128ac..51f288a2e3 100644 --- a/luni/src/test/java/libcore/java/nio/channels/OldServerSocketChannelTest.java +++ b/luni/src/test/java/libcore/java/nio/channels/OldServerSocketChannelTest.java @@ -25,26 +25,17 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.channels.spi.SelectorProvider; import junit.framework.TestCase; -import tests.support.Support_PortManager; -/* - * test for ServerSocketChannel - */ public class OldServerSocketChannelTest extends TestCase { private static final int TIME_UNIT = 200; - private InetSocketAddress localAddr1; - private ServerSocketChannel serverChannel; private SocketChannel clientChannel; protected void setUp() throws Exception { super.setUp(); - this.localAddr1 = new InetSocketAddress( - "127.0.0.1", Support_PortManager - .getNextPort()); this.serverChannel = ServerSocketChannel.open(); this.clientChannel = SocketChannel.open(); } @@ -87,7 +78,7 @@ public class OldServerSocketChannelTest extends TestCase { public void test_accept_Block_NoConnect_interrupt() throws IOException { assertTrue(this.serverChannel.isBlocking()); ServerSocket gotSocket = this.serverChannel.socket(); - gotSocket.bind(localAddr1); + gotSocket.bind(null); class MyThread extends Thread { public String errMsg = null; diff --git a/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java b/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java index 3987194f54..6560a7bbbf 100644 --- a/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java +++ b/luni/src/test/java/libcore/java/nio/channels/OldSocketChannelTest.java @@ -35,11 +35,7 @@ import java.nio.channels.UnresolvedAddressException; import java.nio.channels.UnsupportedAddressTypeException; import java.nio.channels.spi.SelectorProvider; import junit.framework.TestCase; -import tests.support.Support_PortManager; -/** - * Tests for SocketChannel and its default implementation. - */ public class OldSocketChannelTest extends TestCase { private static final int CAPACITY_NORMAL = 200; @@ -58,11 +54,10 @@ public class OldSocketChannelTest extends TestCase { protected void setUp() throws Exception { super.setUp(); - this.localAddr1 = new InetSocketAddress("127.0.0.1", - Support_PortManager.getNextPort()); this.channel1 = SocketChannel.open(); this.channel2 = SocketChannel.open(); - this.server1 = new ServerSocket(localAddr1.getPort()); + this.server1 = new ServerSocket(0); + this.localAddr1 = (InetSocketAddress) server1.getLocalSocketAddress(); } protected void tearDown() throws Exception { diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java index 695908b966..78608d0055 100644 --- a/luni/src/test/java/libcore/java/security/ProviderTest.java +++ b/luni/src/test/java/libcore/java/security/ProviderTest.java @@ -17,14 +17,20 @@ package libcore.java.security; import java.security.Provider; +import java.security.SecureRandom; +import java.security.SecureRandomSpi; +import java.security.Security; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.SecureRandomSpi; import java.security.Security; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Map.Entry; +import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -195,4 +201,48 @@ public class ProviderTest extends TestCase { } } } + + /** + * http://code.google.com/p/android/issues/detail?id=21449 + */ + public void testSecureRandomImplementationOrder() { + Provider srp = new SRProvider(); + try { + int position = Security.insertProviderAt(srp, 1); // first is one, not zero + assertEquals(1, position); + SecureRandom sr = new SecureRandom(); + if (!sr.getAlgorithm().equals("SecureRandom1")) { + throw new IllegalStateException("Expected SecureRandom1"); + } + } finally { + Security.removeProvider(srp.getName()); + } + } + + public static class SRProvider extends Provider { + + SRProvider() { + super("SRProvider", 1.42, "SecureRandom Provider"); + put("SecureRandom.SecureRandom1", SecureRandom1.class.getName()); + put("SecureRandom.SecureRandom2", SecureRandom2.class.getName()); + put("SecureRandom.SecureRandom3", SecureRandom3.class.getName()); + } + } + + public static abstract class AbstractSecureRandom extends SecureRandomSpi { + protected void engineSetSeed(byte[] seed) { + throw new UnsupportedOperationException(); + } + protected void engineNextBytes(byte[] bytes) { + throw new UnsupportedOperationException(); + } + protected byte[] engineGenerateSeed(int numBytes) { + throw new UnsupportedOperationException(); + } + } + + public static class SecureRandom1 extends AbstractSecureRandom {} + public static class SecureRandom2 extends AbstractSecureRandom {} + public static class SecureRandom3 extends AbstractSecureRandom {} + } diff --git a/luni/src/test/java/libcore/java/util/OldScannerTest.java b/luni/src/test/java/libcore/java/util/OldScannerTest.java index b51cfbc2cd..9bac1f4c94 100644 --- a/luni/src/test/java/libcore/java/util/OldScannerTest.java +++ b/luni/src/test/java/libcore/java/util/OldScannerTest.java @@ -28,7 +28,6 @@ import java.util.Scanner; import java.util.regex.MatchResult; import java.util.regex.Pattern; import junit.framework.TestCase; -import tests.support.Support_PortManager; public final class OldScannerTest extends TestCase { @@ -492,15 +491,12 @@ public final class OldScannerTest extends TestCase { assertEquals(102400, matchResult.end()); } - public void test_Constructor_LReadableByteChannel() - throws IOException { - InetSocketAddress localAddr = new InetSocketAddress("127.0.0.1", - Support_PortManager.getNextPort()); + public void test_Constructor_LReadableByteChannel() throws IOException { ServerSocketChannel ssc = ServerSocketChannel.open(); - ssc.socket().bind(localAddr); + ssc.socket().bind(null); SocketChannel sc = SocketChannel.open(); - sc.connect(localAddr); + sc.connect(ssc.socket().getLocalSocketAddress()); sc.configureBlocking(false); assertFalse(sc.isBlocking()); diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java index d94b01754e..484668b588 100644 --- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java +++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java @@ -144,8 +144,8 @@ public class TimeZoneTest extends junit.framework.TestCase { // http://code.google.com/p/android/issues/detail?id=11918 public void testHasSameRules() throws Exception { - TimeZone denver = TimeZone.getTimeZone ("America/Denver") ; - TimeZone phoenix = TimeZone.getTimeZone ("America/Phoenix") ; + TimeZone denver = TimeZone.getTimeZone("America/Denver"); + TimeZone phoenix = TimeZone.getTimeZone("America/Phoenix"); assertFalse(denver.hasSameRules(phoenix)); } @@ -157,4 +157,33 @@ public class TimeZoneTest extends junit.framework.TestCase { } catch (NullPointerException expected) { } } + + // http://b.corp.google.com/issue?id=6556561 + public void testCustomZoneIds() throws Exception { + // These are all okay (and equivalent). + assertEquals("GMT+05:00", TimeZone.getTimeZone("GMT+05:00").getID()); + assertEquals("GMT+05:00", TimeZone.getTimeZone("GMT+5:00").getID()); + assertEquals("GMT+05:00", TimeZone.getTimeZone("GMT+0500").getID()); + assertEquals("GMT+05:00", TimeZone.getTimeZone("GMT+500").getID()); + assertEquals("GMT+05:00", TimeZone.getTimeZone("GMT+5").getID()); + // These aren't. + assertEquals("GMT", TimeZone.getTimeZone("GMT+5.5").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:5").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:0").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:005").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:000").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+005:00").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+05:99").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+28:00").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+05:00.00").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+05:00:00").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+junk").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5junk").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:junk").getID()); + assertEquals("GMT", TimeZone.getTimeZone("GMT+5:00junk").getID()); + assertEquals("GMT", TimeZone.getTimeZone("junkGMT+5:00").getID()); + assertEquals("GMT", TimeZone.getTimeZone("junk").getID()); + assertEquals("GMT", TimeZone.getTimeZone("gmt+5:00").getID()); + } } diff --git a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java index 450b8d918e..07d99e93c4 100644 --- a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java +++ b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java @@ -247,19 +247,36 @@ public class OldMatcherTest extends TestCase { } } - // Starting index out of region + String string3 = "Brave new world"; Pattern pat3 = Pattern.compile("new"); - Matcher mat3 = pat3.matcher("Brave new world"); + Matcher mat3 = pat3.matcher(string3); + + // find(int) throws for out of range indexes. + try { + mat3.find(-1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } + assertFalse(mat3.find(string3.length())); + try { + mat3.find(string3.length() + 1); + fail(); + } catch (IndexOutOfBoundsException expected) { + } - assertTrue(mat3.find(-1)); assertTrue(mat3.find(6)); assertFalse(mat3.find(7)); mat3.region(7, 10); + assertFalse(mat3.find()); // No "new" in the region. - assertFalse(mat3.find(3)); - assertFalse(mat3.find(6)); - assertFalse(mat3.find(7)); + assertTrue(mat3.find(3)); // find(int) ignores the region. + assertTrue(mat3.find(6)); // find(int) ignores the region. + assertFalse(mat3.find(7)); // No "new" >= 7. + + mat3.region(1, 4); + assertFalse(mat3.find()); // No "new" in the region. + assertTrue(mat3.find(5)); // find(int) ignores the region. } public void testSEOLsymbols() { @@ -579,4 +596,14 @@ public class OldMatcherTest extends TestCase { assertTrue(pattern.matcher("14pt").matches()); } + public void testUnicodeCharacterClasses() throws Exception { + // http://code.google.com/p/android/issues/detail?id=21176 + // We use the Unicode TR-18 definitions: http://www.unicode.org/reports/tr18/#Compatibility_Properties + assertTrue("\u0666".matches("\\d")); // ARABIC-INDIC DIGIT SIX + assertFalse("\u0666".matches("\\D")); // ARABIC-INDIC DIGIT SIX + assertTrue("\u1680".matches("\\s")); // OGHAM SPACE MARK + assertFalse("\u1680".matches("\\S")); // OGHAM SPACE MARK + assertTrue("\u00ea".matches("\\w")); // LATIN SMALL LETTER E WITH CIRCUMFLEX + assertFalse("\u00ea".matches("\\W")); // LATIN SMALL LETTER E WITH CIRCUMFLEX + } } diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java index e3ae16fb86..65d86909d4 100644 --- a/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java +++ b/luni/src/test/java/libcore/javax/net/ssl/SSLEngineTest.java @@ -347,6 +347,51 @@ public class SSLEngineTest extends TestCase { c.close(); } + /** + * http://code.google.com/p/android/issues/detail?id=31903 + * This test case directly tests the fix for the issue. + */ + public void test_SSLEngine_clientAuthWantedNoClientCert() throws Exception { + TestSSLContext clientAuthContext + = TestSSLContext.create(TestKeyStore.getClient(), + TestKeyStore.getServer()); + TestSSLEnginePair p = TestSSLEnginePair.create(clientAuthContext, + new TestSSLEnginePair.Hooks() { + @Override + void beforeBeginHandshake(SSLEngine client, SSLEngine server) { + server.setWantClientAuth(true); + } + }); + assertConnected(p); + clientAuthContext.close(); + } + + /** + * http://code.google.com/p/android/issues/detail?id=31903 + * This test case verifies that if the server requires a client cert + * (setNeedClientAuth) but the client does not provide one SSL connection + * establishment will fail + */ + public void test_SSLEngine_clientAuthNeededNoClientCert() throws Exception { + boolean handshakeExceptionCaught = false; + TestSSLContext clientAuthContext + = TestSSLContext.create(TestKeyStore.getClient(), + TestKeyStore.getServer()); + try { + TestSSLEnginePair.create(clientAuthContext, + new TestSSLEnginePair.Hooks() { + @Override + void beforeBeginHandshake(SSLEngine client, SSLEngine server) { + server.setNeedClientAuth(true); + } + }); + fail(); + } catch (SSLHandshakeException expected) { + } finally { + clientAuthContext.close(); + } + } + public void test_SSLEngine_getEnableSessionCreation() throws Exception { TestSSLContext c = TestSSLContext.create(); SSLEngine e = c.clientContext.createSSLEngine(); diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java index 90cdeb9d13..8b9cb11614 100644 --- a/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java +++ b/luni/src/test/java/libcore/javax/net/ssl/SSLSocketTest.java @@ -1054,9 +1054,10 @@ public class SSLSocketTest extends TestCase { assertEquals(0, wrapping.getSoTimeout()); // setting wrapper sets underlying and ... - wrapping.setSoTimeout(10); - assertEquals(10, wrapping.getSoTimeout()); - assertEquals(10, underlying.getSoTimeout()); + int expectedTimeoutMillis = 1000; // Using a small value such as 10 was affected by rounding + wrapping.setSoTimeout(expectedTimeoutMillis); + assertEquals(expectedTimeoutMillis, wrapping.getSoTimeout()); + assertEquals(expectedTimeoutMillis, underlying.getSoTimeout()); // ... getting wrapper inspects underlying underlying.setSoTimeout(0); diff --git a/luni/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java b/luni/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java index 33ce8fb44a..8395c00d1a 100644 --- a/luni/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java +++ b/luni/src/test/java/org/apache/harmony/annotation/tests/java/lang/annotation/AnnotationTest.java @@ -126,6 +126,17 @@ public class AnnotationTest extends TestCase { m2.getDeclaredAnnotations()[0].hashCode()); } + + public static void test35304() throws Exception { + Class c = AnnotationTest.class; + Class[] parameterTypes = new Class[] { String.class, String.class }; + Annotation[][] annotations = c.getDeclaredMethod("test35304_method", parameterTypes).getParameterAnnotations(); + assertEquals(2, annotations.length); // Two parameters. + assertEquals(0, annotations[0].length); // No annotations on the first. + assertEquals(1, annotations[1].length); // One annotation on the second. + } + + private static String test35304_method(String s1, @Deprecated String s2) { return null; } } class AnnotatedClass2 { diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java index 88fcdd7fa2..7442210808 100644 --- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java +++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/CipherTest.java @@ -423,9 +423,10 @@ public class CipherTest extends junit.framework.TestCase { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] b1 = new byte[30]; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); c.update(b, 0, 10, b1, 5); try { c.doFinal(); @@ -441,13 +442,13 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len = c.doFinal(b, 0, 16, b1, 0); assertEquals(16, len); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); + assertTrue(Arrays.equals(c.getIV(), IV)); c.update(b1, 0, 24, b, 0); try { @@ -508,9 +509,10 @@ public class CipherTest extends junit.framework.TestCase { public void testDoFinalbyteArrayintintbyteArrayint() throws Exception { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] b1 = new byte[30]; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); try { c.doFinal(b, 0, 10, b1, 5); fail(); @@ -525,11 +527,10 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len = c.doFinal(b, 0, 16, b1, 0); assertEquals(16, len); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); try { @@ -620,9 +621,10 @@ public class CipherTest extends junit.framework.TestCase { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; ByteBuffer bInput = ByteBuffer.allocate(64); ByteBuffer bOutput = ByteBuffer.allocate(64); + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); bInput.put(b, 0, 10); try { c.doFinal(bInput, bOutput); @@ -638,14 +640,12 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); bInput = ByteBuffer.allocate(16); bInput.put(b, 0, 16); int len = c.doFinal(bInput, bOutput); assertEquals(0, len); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); - c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); bInput = ByteBuffer.allocate(64); @@ -947,9 +947,10 @@ public class CipherTest extends junit.framework.TestCase { public void test_doFinal$BI() throws Exception { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] b1 = new byte[30]; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); c.update(b, 0, 10); try { c.doFinal(b1, 5); @@ -965,13 +966,11 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); c.update(b, 3, 8); int len = c.doFinal(b1, 0); assertEquals(0, len); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); - c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); c.update(b1, 0, 24); @@ -998,9 +997,10 @@ public class CipherTest extends junit.framework.TestCase { byte[] bI2 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; byte[] bI3 = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] bI4 = {1,2,3}; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); try { c.doFinal(bI1); fail(); @@ -1015,14 +1015,13 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len1 = c.doFinal(bI2).length; assertEquals(16, len1); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len2 = c.doFinal(bI3, 0, 16, b1, 0); assertEquals(16, len2); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); try { @@ -1035,9 +1034,10 @@ public class CipherTest extends junit.framework.TestCase { public void test_doFinal$BII() throws Exception { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] b1 = new byte[30]; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); try { c.doFinal(b, 0, 10); fail(); @@ -1052,14 +1052,13 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len1 = c.doFinal(b, 0, 16).length; assertEquals(16, len1); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len2 = c.doFinal(b, 0, 16, b1, 0); assertEquals(16, len2); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); try { @@ -1072,9 +1071,10 @@ public class CipherTest extends junit.framework.TestCase { public void test_doFinal$BII$B() throws Exception { byte[] b = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; byte[] b1 = new byte[30]; + AlgorithmParameterSpec ap = new IvParameterSpec(IV); Cipher c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); try { c.doFinal(b, 0, 10, b1); fail(); @@ -1089,11 +1089,10 @@ public class CipherTest extends junit.framework.TestCase { } c = Cipher.getInstance("DES/CBC/NoPadding"); - c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES); + c.init(Cipher.ENCRYPT_MODE, CIPHER_KEY_DES, ap); int len = c.doFinal(b, 0, 16, b1); assertEquals(16, len); - AlgorithmParameterSpec ap = new IvParameterSpec(IV); c = Cipher.getInstance("DES/CBC/PKCS5Padding"); c.init(Cipher.DECRYPT_MODE, CIPHER_KEY_DES, ap); try { diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java index b3b2931990..3ea57bfb09 100644 --- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java +++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java @@ -33,6 +33,7 @@ import java.io.Serializable; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchProviderException; +import java.util.ArrayList; import java.util.Arrays; import javax.crypto.Cipher; @@ -43,6 +44,8 @@ import javax.crypto.SealedObject; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import libcore.util.SerializationTester; + /** */ public class SealedObjectTest extends TestCase { @@ -291,4 +294,23 @@ public class SealedObjectTest extends TestCase { } } + // http://code.google.com/p/android/issues/detail?id=4834 + public void testDeserialization() throws Exception { + // (Boilerplate so we can create SealedObject instances.) + KeyGenerator kg = KeyGenerator.getInstance("DES"); + Key key = kg.generateKey(); + Cipher cipher = Cipher.getInstance("DES"); + cipher.init(Cipher.ENCRYPT_MODE, key); + + // Incorrect use of readUnshared meant you couldn't have two SealedObjects + // with the same algorithm or parameters algorithm... + ArrayList<SealedObject> sealedObjects = new ArrayList<SealedObject>(); + for (int i = 0; i < 10; ++i) { + sealedObjects.add(new SealedObject("hello", cipher)); + } + String serializedForm = SerializationTester.serializeHex(sealedObjects); + + // ...so this would throw "java.io.InvalidObjectException: Unshared read of back reference". + SerializationTester.deserializeHex(serializedForm); + } } 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 3ca11f7e46..07e3de5c8c 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 @@ -19,7 +19,6 @@ package org.apache.harmony.luni.tests.java.net; import dalvik.annotation.BrokenTest; import junit.framework.TestCase; import tests.support.Support_Configuration; -import tests.support.Support_PortManager; import tests.support.Support_TestWebData; import tests.support.Support_TestWebServer; import tests.support.resource.Support_Resources; @@ -220,9 +219,8 @@ public class URLConnectionTest extends TestCase { public void setUp() throws Exception { super.setUp(); - port = Support_PortManager.getNextPort(); server = new Support_TestWebServer(); - server.initServer(port, false); + port = server.initServer(); url = new URL("http://localhost:" + port + "/test1"); uc = url.openConnection(); url2 = new URL("http://localhost:" + port + "/test2"); diff --git a/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java b/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java index 053200f212..34d7aedfa2 100644 --- a/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java +++ b/luni/src/test/java/tests/api/javax/net/ServerSocketFactoryTest.java @@ -30,158 +30,77 @@ import javax.net.ServerSocketFactory; import junit.framework.TestCase; -import tests.support.Support_PortManager; - - -/** - * Tests for <code>ServerSocketFactory</code> class constructors and methods. - */ public class ServerSocketFactoryTest extends TestCase { - /** - * javax.net.SocketFactory#SocketFactory() - */ public void test_Constructor() { - try { - ServerSocketFactory sf = new MyServerSocketFactory(); - } catch (Exception e) { - fail("Unexpected exception " + e.toString()); - } + ServerSocketFactory sf = new MyServerSocketFactory(); } - /** - * javax.net.ServerSocketFactory#createServerSocket() - */ - public final void test_createServerSocket_01() { + public final void test_createServerSocket() throws Exception { ServerSocketFactory sf = ServerSocketFactory.getDefault(); - try { - ServerSocket ss = sf.createServerSocket(); - assertNotNull(ss); - } catch (SocketException e) { - } catch (Exception e) { - fail(e.toString()); - } + ServerSocket ss = sf.createServerSocket(); + assertNotNull(ss); + ss.close(); } - /** - * javax.net.ServerSocketFactory#createServerSocket(int port) - */ - public final void test_createServerSocket_02() { + public final void test_createServerSocket_I() throws Exception { ServerSocketFactory sf = ServerSocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - - try { - ServerSocket ss = sf.createServerSocket(portNumber); - assertNotNull(ss); - } catch (Exception ex) { - fail("Unexpected exception: " + ex); - } + ServerSocket ss = sf.createServerSocket(0); + assertNotNull(ss); try { - sf.createServerSocket(portNumber); + sf.createServerSocket(ss.getLocalPort()); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IOException"); + } catch (IOException expected) { } + ss.close(); + try { sf.createServerSocket(-1); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } - /** - * javax.net.ServerSocketFactory#createServerSocket(int port, int backlog) - */ - public final void test_createServerSocket_03() { + public final void test_createServerSocket_II() throws Exception { ServerSocketFactory sf = ServerSocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - - try { - ServerSocket ss = sf.createServerSocket(portNumber, 0); - assertNotNull(ss); - } catch (Exception ex) { - fail("Unexpected exception: " + ex); - } + ServerSocket ss = sf.createServerSocket(0, 0); + assertNotNull(ss); try { - sf.createServerSocket(portNumber, 0); + sf.createServerSocket(ss.getLocalPort(), 0); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IOException"); + } catch (IOException expected) { } + ss.close(); + try { sf.createServerSocket(65536, 0); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } - /** - * javax.net.ServerSocketFactory#createServerSocket(int port, int backlog, InetAddress ifAddress) - */ - public final void test_createServerSocket_04() { + public final void test_createServerSocket_IIInetAddress() throws Exception { ServerSocketFactory sf = ServerSocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - try { - ServerSocket ss = sf.createServerSocket(portNumber, 0, InetAddress.getLocalHost()); - assertNotNull(ss); - } catch (Exception ex) { - fail("Unexpected exception: " + ex); - } + ServerSocket ss = sf.createServerSocket(0, 0, InetAddress.getLocalHost()); + assertNotNull(ss); try { - sf.createServerSocket(portNumber, 0, InetAddress.getLocalHost()); + sf.createServerSocket(ss.getLocalPort(), 0, InetAddress.getLocalHost()); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IOException"); + } catch (IOException expected) { } + ss.close(); + try { sf.createServerSocket(Integer.MAX_VALUE, 0, InetAddress.getLocalHost()); fail("IllegalArgumentException wasn't thrown"); - } catch (IllegalArgumentException ioe) { - //expected - } catch (Exception ex) { - fail(ex + " was thrown instead of IllegalArgumentException"); - } - } - - /** - * javax.net.ServerSocketFactory#getDefault() - */ - public final void test_getDefault() { - ServerSocketFactory sf = ServerSocketFactory.getDefault(); - ServerSocket s; - try { - s = sf.createServerSocket(0); - s.close(); - } catch (IOException e) { - } - try { - s = sf.createServerSocket(0, 50); - s.close(); - } catch (IOException e) { - } - try { - s = sf.createServerSocket(0, 50, InetAddress.getLocalHost()); - s.close(); - } catch (IOException e) { + } catch (IllegalArgumentException expected) { } } } diff --git a/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java b/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java index 2250602f3e..e939a9bed5 100644 --- a/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java +++ b/luni/src/test/java/tests/api/javax/net/SocketFactoryTest.java @@ -33,200 +33,135 @@ import javax.net.SocketFactory; import junit.framework.TestCase; -import tests.support.Support_PortManager; - - -/** - * Tests for <code>SocketFactory</code> class methods. - */ public class SocketFactoryTest extends TestCase { - /** - * javax.net.SocketFactory#SocketFactory() - */ - public void test_Constructor() { - try { - MySocketFactory sf = new MySocketFactory(); - } catch (Exception e) { - fail("Unexpected exception " + e.toString()); - } + public void test_Constructor() throws Exception { + new MySocketFactory(); } - /** - * javax.net.SocketFactory#createSocket() - */ - public final void test_createSocket_01() { + public final void test_createSocket() throws Exception { SocketFactory sf = SocketFactory.getDefault(); - try { - Socket s = sf.createSocket(); - assertNotNull(s); - assertEquals(-1, s.getLocalPort()); - assertEquals(0, s.getPort()); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } + Socket s = sf.createSocket(); + assertNotNull(s); + assertEquals(-1, s.getLocalPort()); + assertEquals(0, s.getPort()); MySocketFactory msf = new MySocketFactory(); try { msf.createSocket(); fail("No expected SocketException"); - } catch (SocketException e) { - } catch (IOException e) { - fail(e.toString()); + } catch (SocketException expected) { } } - /** - * javax.net.SocketFactory#createSocket(String host, int port) - */ - public final void test_createSocket_02() { + public final void test_createSocket_StringI() throws Exception { SocketFactory sf = SocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - int sport = startServer("Cons String,I"); + int sport = new ServerSocket(0).getLocalPort(); int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE}; - try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport); - assertNotNull(s); - assertTrue("Failed to create socket", s.getPort() == sport); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } + Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport); + assertNotNull(s); + assertTrue("Failed to create socket", s.getPort() == sport); try { - Socket s = sf.createSocket("bla-bla", sport); + sf.createSocket("bla-bla", sport); fail("UnknownHostException wasn't thrown"); - } catch (UnknownHostException uhe) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of UnknownHostException"); + } catch (UnknownHostException expected) { } for (int i = 0; i < invalidPorts.length; i++) { try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i]); + sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i]); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } } try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), portNumber); + sf.createSocket(InetAddress.getLocalHost().getHostName(), s.getLocalPort()); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected + } catch (IOException expected) { } SocketFactory f = SocketFactory.getDefault(); try { - Socket s = f.createSocket("localhost", 8082); + f.createSocket(InetAddress.getLocalHost().getHostName(), 8082); fail("IOException wasn't thrown ..."); - } catch (IOException e) { + } catch (IOException expected) { } } - /** - * javax.net.SocketFactory#createSocket(InetAddress host, int port) - */ - public final void test_createSocket_03() { + public final void test_createSocket_InetAddressI() throws Exception { SocketFactory sf = SocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - int sport = startServer("Cons InetAddress,I"); + int sport = new ServerSocket(0).getLocalPort(); int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE}; - try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), sport); - assertNotNull(s); - assertTrue("Failed to create socket", s.getPort() == sport); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } + Socket s = sf.createSocket(InetAddress.getLocalHost(), sport); + assertNotNull(s); + assertTrue("Failed to create socket", s.getPort() == sport); for (int i = 0; i < invalidPorts.length; i++) { try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i]); + sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i]); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } } try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), portNumber); + sf.createSocket(InetAddress.getLocalHost(), s.getLocalPort()); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected + } catch (IOException expected) { } SocketFactory f = SocketFactory.getDefault(); try { - Socket s = f.createSocket(InetAddress.getLocalHost(), 8081); + f.createSocket(InetAddress.getLocalHost(), 8081); fail("IOException wasn't thrown ..."); - } catch (IOException e) { + } catch (IOException expected) { } } - /** - * javax.net.SocketFactory#createSocket(InetAddress address, int port, - * InetAddress localAddress, int localPort) - */ - public final void test_createSocket_04() { + public final void test_createSocket_InetAddressIInetAddressI() throws Exception { SocketFactory sf = SocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - int sport = startServer("Cons InetAddress,I,InetAddress,I"); + int sport = new ServerSocket(0).getLocalPort(); int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE}; - try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), sport, - InetAddress.getLocalHost(), portNumber); - assertNotNull(s); - assertTrue("1: Failed to create socket", s.getPort() == sport); - assertTrue("2: Failed to create socket", s.getLocalPort() == portNumber); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } + Socket s = sf.createSocket(InetAddress.getLocalHost(), sport, + InetAddress.getLocalHost(), 0); + assertNotNull(s); + assertTrue("1: Failed to create socket", s.getPort() == sport); + int portNumber = s.getLocalPort(); for (int i = 0; i < invalidPorts.length; i++) { try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i], - InetAddress.getLocalHost(), portNumber); + sf.createSocket(InetAddress.getLocalHost(), invalidPorts[i], + InetAddress.getLocalHost(), portNumber); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), sport, - InetAddress.getLocalHost(), invalidPorts[i]); + sf.createSocket(InetAddress.getLocalHost(), sport, + InetAddress.getLocalHost(), invalidPorts[i]); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } } try { - Socket s = sf.createSocket(InetAddress.getLocalHost(), sport, - InetAddress.getLocalHost(), portNumber); + sf.createSocket(InetAddress.getLocalHost(), sport, + InetAddress.getLocalHost(), portNumber); fail("IOException wasn't thrown"); - } catch (IOException ioe) { - //expected + } catch (IOException expected) { } SocketFactory f = SocketFactory.getDefault(); try { - Socket s = f.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082); + f.createSocket(InetAddress.getLocalHost(), 8081, InetAddress.getLocalHost(), 8082); fail("IOException wasn't thrown ..."); - } catch (IOException e) { + } catch (IOException expected) { } } @@ -234,59 +169,41 @@ public class SocketFactoryTest extends TestCase { * javax.net.SocketFactory#createSocket(String host, int port, * InetAddress localHost, int localPort) */ - public final void test_createSocket_05() { + public final void test_createSocket_05() throws Exception { SocketFactory sf = SocketFactory.getDefault(); - int portNumber = Support_PortManager.getNextPort(); - int sport = startServer("Cons String,I,InetAddress,I"); + int sport = new ServerSocket(0).getLocalPort(); int[] invalidPorts = {Integer.MIN_VALUE, -1, 65536, Integer.MAX_VALUE}; - try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport, - InetAddress.getLocalHost(), portNumber); - assertNotNull(s); - assertTrue("1: Failed to create socket", s.getPort() == sport); - assertTrue("2: Failed to create socket", s.getLocalPort() == portNumber); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } + Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport, + InetAddress.getLocalHost(), 0); + assertNotNull(s); + assertTrue("1: Failed to create socket", s.getPort() == sport); - portNumber = Support_PortManager.getNextPort(); try { - Socket s = sf.createSocket("bla-bla", sport, InetAddress.getLocalHost(), portNumber); + sf.createSocket("bla-bla", sport, InetAddress.getLocalHost(), 0); fail("UnknownHostException wasn't thrown"); - } catch (UnknownHostException uhe) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of UnknownHostException"); + } catch (UnknownHostException expected) { } for (int i = 0; i < invalidPorts.length; i++) { - portNumber = Support_PortManager.getNextPort(); try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i], - InetAddress.getLocalHost(), portNumber); + sf.createSocket(InetAddress.getLocalHost().getHostName(), invalidPorts[i], + InetAddress.getLocalHost(), 0); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } try { - Socket s = sf.createSocket(InetAddress.getLocalHost().getHostName(), sport, - InetAddress.getLocalHost(), invalidPorts[i]); + sf.createSocket(InetAddress.getLocalHost().getHostName(), sport, + InetAddress.getLocalHost(), invalidPorts[i]); fail("IllegalArgumentException wasn't thrown for " + invalidPorts[i]); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException for " + invalidPorts[i]); + } catch (IllegalArgumentException expected) { } } - SocketFactory f = SocketFactory.getDefault(); try { - Socket s = f.createSocket("localhost", 8081, InetAddress.getLocalHost(), 8082); + sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082); fail("IOException wasn't thrown ..."); - } catch (IOException e) { + } catch (IOException expected) { } } @@ -297,12 +214,12 @@ public class SocketFactoryTest extends TestCase { SocketFactory sf = SocketFactory.getDefault(); Socket s; try { - s = sf.createSocket("localhost", 8082); + s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8082); s.close(); } catch (IOException e) { } try { - s = sf.createSocket("localhost", 8081, InetAddress.getLocalHost(), 8082); + s = sf.createSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082); s.close(); } catch (IOException e) { } @@ -317,17 +234,6 @@ public class SocketFactoryTest extends TestCase { } catch (IOException e) { } } - - protected int startServer(String name) { - int portNumber = Support_PortManager.getNextPort(); - ServerSocket ss = null; - try { - ss = new ServerSocket(portNumber); - } catch (IOException e) { - fail(name + ": " + e); - } - return ss.getLocalPort(); - } } class MySocketFactory extends SocketFactory { diff --git a/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java b/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java index 8a02f9c157..c075ceace4 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/HandshakeCompletedEventTest.java @@ -42,7 +42,6 @@ import javax.security.cert.X509Certificate; import junit.framework.TestCase; import libcore.io.Base64; import org.apache.harmony.xnet.tests.support.mySSLSession; -import tests.support.Support_PortManager; /** * Tests for <code>HandshakeCompletedEvent</code> class constructors and methods. @@ -50,7 +49,7 @@ import tests.support.Support_PortManager; */ public class HandshakeCompletedEventTest extends TestCase { - String certificate = "-----BEGIN CERTIFICATE-----\n" + private String certificate = "-----BEGIN CERTIFICATE-----\n" + "MIICZTCCAdICBQL3AAC2MA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMSAw\n" + "HgYDVQQKExdSU0EgRGF0YSBTZWN1cml0eSwgSW5jLjEuMCwGA1UECxMlU2VjdXJl\n" + "IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05NzAyMjAwMDAwMDBa\n" @@ -200,11 +199,10 @@ public class HandshakeCompletedEventTest extends TestCase { // TrustManager - SSLSocket socket; - SSLSocket serverSocket; - MyHandshakeListener listener; - int port = Support_PortManager.getNextPort(); - String host = "localhost"; + private SSLSocket socket; + private SSLServerSocket serverSocket; + private MyHandshakeListener listener; + private String host = "localhost"; private String PASSWORD = "android"; @@ -398,35 +396,34 @@ public class HandshakeCompletedEventTest extends TestCase { private boolean provideKeys; - public TestServer(boolean provideKeys, int clientAuth, String keys) { + public TestServer(boolean provideKeys, int clientAuth, String keys) throws Exception { this.keys = keys; this.clientAuth = clientAuth; this.provideKeys = provideKeys; trustManager = new TestTrustManager(); - } - public void run() { - try { - KeyManager[] keyManagers = provideKeys ? getKeyManagers(keys) : null; - TrustManager[] trustManagers = new TrustManager[] { trustManager }; + KeyManager[] keyManagers = provideKeys ? getKeyManagers(keys) : null; + TrustManager[] trustManagers = new TrustManager[] { trustManager }; - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagers, trustManagers, null); + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, trustManagers, null); - SSLServerSocket serverSocket = (SSLServerSocket) - sslContext.getServerSocketFactory().createServerSocket(); + serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(); - if (clientAuth == CLIENT_AUTH_WANTED) { - serverSocket.setWantClientAuth(true); - } else if (clientAuth == CLIENT_AUTH_NEEDED) { - serverSocket.setNeedClientAuth(true); - } else { - serverSocket.setWantClientAuth(false); - } + if (clientAuth == CLIENT_AUTH_WANTED) { + serverSocket.setWantClientAuth(true); + } else if (clientAuth == CLIENT_AUTH_NEEDED) { + serverSocket.setNeedClientAuth(true); + } else { + serverSocket.setWantClientAuth(false); + } - serverSocket.bind(new InetSocketAddress(port)); + serverSocket.bind(new InetSocketAddress(0)); + } + public void run() { + try { SSLSocket clientSocket = (SSLSocket)serverSocket.accept(); InputStream istream = clientSocket.getInputStream(); @@ -497,7 +494,7 @@ public class HandshakeCompletedEventTest extends TestCase { SSLSocket socket = (SSLSocket)sslContext.getSocketFactory().createSocket(); - socket.connect(new InetSocketAddress(port)); + socket.connect(serverSocket.getLocalSocketAddress()); socket.addHandshakeCompletedListener(listener); socket.startHandshake(); diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java index cc96782062..5086f65ec2 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/SSLServerSocketTest.java @@ -20,8 +20,6 @@ import junit.framework.TestCase; import libcore.io.Base64; -import tests.support.Support_PortManager; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; @@ -120,127 +118,78 @@ public class SSLServerSocketTest extends TestCase { /** * javax.net.ssl.SSLServerSocket#SSLServerSocket() */ - public void testConstructor_01() { - try { - SSLServerSocket ssl = new mySSLServerSocket(); - } catch (Exception ex) { - fail("Unexpected exception was thrown " + ex); - } + public void testConstructor() throws Exception { + SSLServerSocket ssl = new mySSLServerSocket(); } /** * javax.net.ssl.SSLServerSocket#SSLServerSocket(int port) */ - public void testConstructor_02() { - SSLServerSocket ssl; - int portNumber = Support_PortManager.getNextPort(); + public void testConstructor_I() throws Exception { int[] port_invalid = {-1, 65536, Integer.MIN_VALUE, Integer.MAX_VALUE}; - try { - ssl = new mySSLServerSocket(portNumber); - assertEquals(portNumber, ssl.getLocalPort()); - } catch (Exception ex) { - fail("Unexpected exception was thrown " + ex); - } + SSLServerSocket ssl = new mySSLServerSocket(0); for (int i = 0; i < port_invalid.length; i++) { try { - ssl = new mySSLServerSocket(port_invalid[i]); + new mySSLServerSocket(port_invalid[i]); fail("IllegalArgumentException should be thrown"); - } catch (IllegalArgumentException iae) { - //expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } try { - ssl = new mySSLServerSocket(portNumber); - new mySSLServerSocket(portNumber); + new mySSLServerSocket(ssl.getLocalPort()); fail("IOException Expected when opening an already opened port"); - } catch (IOException ioe) { - // expected - } catch (Exception ex) { - fail("Unexpected exception was thrown " + ex); + } catch (IOException expected) { } } /** * javax.net.ssl.SSLServerSocket#SSLServerSocket(int port, int backlog) */ - public void testConstructor_03() { - mySSLServerSocket ssl; - int portNumber = Support_PortManager.getNextPort(); + public void testConstructor_II() throws Exception { + mySSLServerSocket ssl = new mySSLServerSocket(0, 1); int[] port_invalid = {-1, Integer.MIN_VALUE, Integer.MAX_VALUE}; - try { - ssl = new mySSLServerSocket(portNumber, 1); - assertEquals(portNumber, ssl.getLocalPort()); - } catch (Exception ex) { - fail("Unexpected exception was thrown"); - } - for (int i = 0; i < port_invalid.length; i++) { try { - ssl = new mySSLServerSocket(port_invalid[i], 1); + new mySSLServerSocket(port_invalid[i], 1); fail("IllegalArgumentException should be thrown"); - } catch (IllegalArgumentException iae) { - // expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } - portNumber = Support_PortManager.getNextPort(); try { - ssl = new mySSLServerSocket(portNumber, 1); - new mySSLServerSocket(portNumber, 1); + new mySSLServerSocket(ssl.getLocalPort(), 1); fail("IOException should be thrown"); - } catch (IOException ioe) { + } catch (IOException expected) { } } /** * javax.net.ssl.SSLServerSocket#SSLServerSocket(int port, int backlog, InetAddress address) */ - public void testConstructor_04() { - mySSLServerSocket ssl; - InetAddress ia = null; - int portNumber = Support_PortManager.getNextPort(); - int[] port_invalid = {-1, 65536, Integer.MIN_VALUE, Integer.MAX_VALUE}; + public void testConstructor_IIInetAddress() throws Exception { + // A null InetAddress is okay. + new mySSLServerSocket(0, 0, null); - try { - ssl = new mySSLServerSocket(portNumber, 0, ia); - assertEquals(portNumber, ssl.getLocalPort()); - } catch (Exception ex) { - fail("Unexpected exception was thrown"); - } + int[] port_invalid = {-1, 65536, Integer.MIN_VALUE, Integer.MAX_VALUE}; - portNumber = Support_PortManager.getNextPort(); - try { - ssl = new mySSLServerSocket(portNumber, 0, InetAddress.getLocalHost()); - assertEquals(portNumber, ssl.getLocalPort()); - } catch (Exception ex) { - fail("Unexpected exception was thrown"); - } + mySSLServerSocket ssl = new mySSLServerSocket(0, 0, InetAddress.getLocalHost()); for (int i = 0; i < port_invalid.length; i++) { try { - ssl = new mySSLServerSocket(port_invalid[i], 1, InetAddress.getLocalHost()); + new mySSLServerSocket(port_invalid[i], 1, InetAddress.getLocalHost()); fail("IllegalArgumentException should be thrown"); - } catch (IllegalArgumentException iae) { - // expected - } catch (Exception e) { - fail(e + " was thrown instead of IllegalArgumentException"); + } catch (IllegalArgumentException expected) { } } - portNumber = Support_PortManager.getNextPort(); try { - ssl = new mySSLServerSocket(portNumber, 0, InetAddress.getLocalHost()); - new mySSLServerSocket(portNumber, 0, InetAddress.getLocalHost()); - fail("IOException should be thrown for"); - } catch (IOException ioe) { + new mySSLServerSocket(ssl.getLocalPort(), 0, InetAddress.getLocalHost()); + fail("IOException should be thrown for"); + } catch (IOException expected) { } } diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java index ec23cae9d1..508442233a 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/SSLSessionTest.java @@ -39,12 +39,7 @@ import junit.framework.TestCase; import libcore.io.Base64; import tests.api.javax.net.ssl.HandshakeCompletedEventTest.MyHandshakeListener; import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager; -import tests.support.Support_PortManager; -/** - * Tests for SSLSession class - * - */ public class SSLSessionTest extends TestCase { // set to true if on Android, false if on RI @@ -57,7 +52,7 @@ public class SSLSessionTest extends TestCase { public void test_getPeerHost() throws Exception { SSLSession s = clientSession; assertEquals(InetAddress.getLocalHost().getHostName(), s.getPeerHost()); - assertEquals(port, s.getPeerPort()); + assertEquals(serverSocket.getLocalPort(), s.getPeerPort()); } /** @@ -258,12 +253,10 @@ public class SSLSessionTest extends TestCase { TestClient client; @Override - protected void setUp() { - port = Support_PortManager.getNextPort(); + protected void setUp() throws Exception { String serverKeys = (useBKS ? SERVER_KEYS_BKS : SERVER_KEYS_JKS); String clientKeys = (useBKS ? CLIENT_KEYS_BKS : CLIENT_KEYS_JKS); - server = new TestServer(true, - TestServer.CLIENT_AUTH_WANTED, serverKeys); + server = new TestServer(true, TestServer.CLIENT_AUTH_WANTED, serverKeys); client = new TestClient(true, clientKeys); serverThread = new Thread(server); @@ -453,8 +446,7 @@ public class SSLSessionTest extends TestCase { + "NMGpCX6qmjbkJQLVK/Yfo1ePaUexPSOX0G9m8+DoV3iyNw6at01NRw=="; - int port; - SSLSocket serverSocket; + SSLServerSocket serverSocket; MyHandshakeListener listener; String host = "localhost"; boolean notFinished = true; @@ -489,36 +481,35 @@ public class SSLSessionTest extends TestCase { private KeyStore store; - public TestServer(boolean provideKeys, int clientAuth, String keys) { + public TestServer(boolean provideKeys, int clientAuth, String keys) throws Exception { this.keys = keys; this.clientAuth = clientAuth; this.provideKeys = provideKeys; trustManager = new TestTrustManager(); - } - public void run() { - try { - store = provideKeys ? getKeyStore(keys) : null; - KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; - TrustManager[] trustManagers = new TrustManager[] { trustManager }; + store = provideKeys ? getKeyStore(keys) : null; + KeyManager[] keyManagers = store != null ? getKeyManagers(store) : null; + TrustManager[] trustManagers = new TrustManager[] { trustManager }; - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagers, trustManagers, null); + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, trustManagers, null); - SSLServerSocket serverSocket = (SSLServerSocket)sslContext - .getServerSocketFactory().createServerSocket(); + serverSocket = (SSLServerSocket)sslContext.getServerSocketFactory().createServerSocket(); - if (clientAuth == CLIENT_AUTH_WANTED) { - serverSocket.setWantClientAuth(true); - } else if (clientAuth == CLIENT_AUTH_NEEDED) { - serverSocket.setNeedClientAuth(true); - } else { - serverSocket.setWantClientAuth(false); - } + if (clientAuth == CLIENT_AUTH_WANTED) { + serverSocket.setWantClientAuth(true); + } else if (clientAuth == CLIENT_AUTH_NEEDED) { + serverSocket.setNeedClientAuth(true); + } else { + serverSocket.setWantClientAuth(false); + } - serverSocket.bind(new InetSocketAddress(port)); + serverSocket.bind(null); + } + public void run() { + try { SSLSocket clientSocket = (SSLSocket)serverSocket.accept(); InputStream istream = clientSocket.getInputStream(); @@ -589,7 +580,7 @@ public class SSLSessionTest extends TestCase { SSLSocket socket = (SSLSocket)clientSslContext.getSocketFactory().createSocket(); - socket.connect(new InetSocketAddress(port)); + socket.connect(serverSocket.getLocalSocketAddress()); OutputStream ostream = socket.getOutputStream(); ostream.write(testData.getBytes()); ostream.flush(); diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java index 02abcc29ae..0d911162a6 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketFactoryTest.java @@ -25,16 +25,13 @@ import javax.net.ssl.SSLSocketFactory; import junit.framework.TestCase; -import tests.support.Support_PortManager; - public class SSLSocketFactoryTest extends TestCase { private ServerSocket ss; protected int startServer(String name) { - int portNumber = Support_PortManager.getNextPort(); try { - ss = new ServerSocket(portNumber); + ss = new ServerSocket(0); } catch (IOException e) { fail(name + ": " + e); } diff --git a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java index ab60f72335..b4cbde201b 100644 --- a/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java +++ b/luni/src/test/java/tests/api/javax/net/ssl/SSLSocketTest.java @@ -38,7 +38,6 @@ import javax.security.cert.X509Certificate; import junit.framework.TestCase; import libcore.io.Base64; import tests.api.javax.net.ssl.HandshakeCompletedEventTest.TestTrustManager; -import tests.support.Support_PortManager; import libcore.java.security.StandardNames; public class SSLSocketTest extends TestCase { @@ -51,7 +50,7 @@ public class SSLSocketTest extends TestCase { /** * javax.net.ssl.SSLSocket#SSLSocket() */ - public void testConstructor_01() throws Exception { + public void testConstructor() throws Exception { SSLSocket ssl = getSSLSocket(); assertNotNull(ssl); ssl.close(); @@ -60,7 +59,7 @@ public class SSLSocketTest extends TestCase { /** * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port) */ - public void testConstructor_02() throws UnknownHostException, IOException { + public void testConstructor_InetAddressI() throws Exception { int sport = startServer("Cons InetAddress,I"); int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; @@ -88,15 +87,13 @@ public class SSLSocketTest extends TestCase { * javax.net.ssl.SSLSocket#SSLSocket(InetAddress address, int port, * InetAddress clientAddress, int clientPort) */ - public void testConstructor_03() throws UnknownHostException, IOException { + public void testConstructor_InetAddressIInetAddressI() throws Exception { int sport = startServer("Cons InetAddress,I,InetAddress,I"); - int portNumber = Support_PortManager.getNextPort(); SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost(), sport, - InetAddress.getLocalHost(), portNumber); + InetAddress.getLocalHost(), 0); assertNotNull(ssl); assertEquals(sport, ssl.getPort()); - assertEquals(portNumber, ssl.getLocalPort()); ssl.close(); try { @@ -137,7 +134,7 @@ public class SSLSocketTest extends TestCase { /** * javax.net.ssl.SSLSocket#SSLSocket(String host, int port) */ - public void testConstructor_04() throws UnknownHostException, IOException { + public void testConstructor_StringI() throws Exception { int sport = startServer("Cons String,I"); int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; @@ -171,28 +168,25 @@ public class SSLSocketTest extends TestCase { * javax.net.ssl.SSLSocket#SSLSocket(String host, int port, InetAddress clientAddress, * int clientPort) */ - public void testConstructor_05() throws UnknownHostException, IOException { + public void testConstructor_StringIInetAddressI() throws Exception { int sport = startServer("Cons String,I,InetAddress,I"); - int portNumber = Support_PortManager.getNextPort(); int[] invalidPort = {-1, Integer.MIN_VALUE, 65536, Integer.MAX_VALUE}; SSLSocket ssl = getSSLSocket(InetAddress.getLocalHost().getHostName(), sport, - InetAddress.getLocalHost(), portNumber); + InetAddress.getLocalHost(), 0); assertNotNull(ssl); assertEquals(sport, ssl.getPort()); - assertEquals(portNumber, ssl.getLocalPort()); try { - getSSLSocket("localhost", 8081, InetAddress.getLocalHost(), 8082); + getSSLSocket(InetAddress.getLocalHost().getHostName(), 8081, InetAddress.getLocalHost(), 8082); fail(); } catch (IOException expected) { } for (int i = 0; i < invalidPort.length; i++) { - portNumber = Support_PortManager.getNextPort(); try { getSSLSocket(InetAddress.getLocalHost().getHostName(), invalidPort[i], - InetAddress.getLocalHost(), portNumber); + InetAddress.getLocalHost(), 0); fail(); } catch (IllegalArgumentException expected) { } @@ -204,9 +198,8 @@ public class SSLSocketTest extends TestCase { } } - portNumber = Support_PortManager.getNextPort(); try { - getSSLSocket("bla-bla", sport, InetAddress.getLocalHost(), portNumber); + getSSLSocket("bla-bla", sport, InetAddress.getLocalHost(), 0); fail(); } catch (UnknownHostException expected) { } @@ -422,12 +415,10 @@ public class SSLSocketTest extends TestCase { ssl.close(); } - boolean useBKS = !StandardNames.IS_RI; + private boolean useBKS = !StandardNames.IS_RI; private String PASSWORD = "android"; - private int port = Support_PortManager.getNextPort(); - private boolean serverReady = false; /** @@ -551,7 +542,7 @@ public class SSLSocketTest extends TestCase { SSLServerSocket serverSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(); try { - serverSocket.bind(new InetSocketAddress(port)); + serverSocket.bind(new InetSocketAddress(0)); sport = serverSocket.getLocalPort(); serverReady = true; diff --git a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java index 286d4ab46c..bdc580d61f 100644 --- a/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java +++ b/luni/src/test/java/tests/api/org/apache/harmony/kernel/dalvik/ThreadsTest.java @@ -187,11 +187,10 @@ public class ThreadsTest extends TestCase { if (! completed) { try { wait(maxWaitMillis); - } catch (InterruptedException ex) { - // Ignore it. + } catch (InterruptedException ignored) { } if (! completed) { - Assert.fail("parker hanging"); + Assert.fail("parker hung for more than " + maxWaitMillis + " ms"); } } diff --git a/support/src/test/java/tests/support/Support_TestWebServer.java b/support/src/test/java/tests/support/Support_TestWebServer.java index 4d6b0d14f9..5f3cd85ad7 100644 --- a/support/src/test/java/tests/support/Support_TestWebServer.java +++ b/support/src/test/java/tests/support/Support_TestWebServer.java @@ -94,51 +94,21 @@ public class Support_TestWebServer implements Support_HttpConstants { } /** - * Initialize a new server with default port and timeout. - * @param log Set true if you want trace output - */ - public int initServer(boolean log) throws Exception { - return initServer(0, DEFAULT_TIMEOUT, log); - } - - /** - * Initialize a new server with default timeout. - * @param port Sets the server to listen on this port, or 0 to let the OS choose. - * Hard-coding ports is evil, so always pass 0. - * @param log Set true if you want trace output - */ - public int initServer(int port, boolean log) throws Exception { - return initServer(port, DEFAULT_TIMEOUT, log); - } - - /** - * Initialize a new server with default timeout and disabled log. - * @param port Sets the server to listen on this port, or 0 to let the OS choose. - * Hard-coding ports is evil, so always pass 0. * @param servePath the path to the dynamic web test data * @param contentType the type of the dynamic web test data */ - public int initServer(int port, String servePath, String contentType) - throws Exception { + public int initServer(String servePath, String contentType) throws Exception { Support_TestWebData.initDynamicTestWebData(servePath, contentType); - return initServer(port, DEFAULT_TIMEOUT, false); + return initServer(); } - /** - * Initialize a new server with default port and timeout. - * @param port Sets the server to listen on this port, or 0 to let the OS choose. - * Hard-coding ports is evil, so always pass 0. - * @param timeout Indicates the period of time to wait until a socket is - * closed - * @param log Set true if you want trace output - */ - public int initServer(int port, int timeout, boolean log) throws Exception { - mTimeout = timeout; - mLog = log; + public int initServer() throws Exception { + mTimeout = DEFAULT_TIMEOUT; + mLog = false; keepAlive = true; if (acceptT == null) { acceptT = new AcceptThread(); - mPort = acceptT.init(port); + mPort = acceptT.init(); acceptT.start(); } return mPort; @@ -253,8 +223,8 @@ public class Support_TestWebServer implements Support_HttpConstants { * @param port the port to use, or 0 to let the OS choose. * Hard-coding ports is evil, so always pass 0! */ - public int init(int port) throws IOException { - ss = new ServerSocket(port); + public int init() throws IOException { + ss = new ServerSocket(0); ss.setSoTimeout(5000); ss.setReuseAddress(true); return ss.getLocalPort(); |
