Merge "Check for leniency of calendar in getDisplayNames"
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 3a24856..1df80da 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -246,6 +246,7 @@
public static final int FD_CLOEXEC = placeholder();
public static final int FIONREAD = placeholder();
public static final int F_DUPFD = placeholder();
+ /** @hide */ public static final int F_DUPFD_CLOEXEC = placeholder();
public static final int F_GETFD = placeholder();
public static final int F_GETFL = placeholder();
public static final int F_GETLK = placeholder();
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index fb912a7..4e85908 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -218,6 +218,7 @@
initConstant(env, c, "FD_CLOEXEC", FD_CLOEXEC);
initConstant(env, c, "FIONREAD", FIONREAD);
initConstant(env, c, "F_DUPFD", F_DUPFD);
+ initConstant(env, c, "F_DUPFD_CLOEXEC", F_DUPFD_CLOEXEC);
initConstant(env, c, "F_GETFD", F_GETFD);
initConstant(env, c, "F_GETFL", F_GETFL);
initConstant(env, c, "F_GETLK", F_GETLK);
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 1e87223..57facc5 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -28,6 +28,7 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImpl;
+import java.net.UnknownHostException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.concurrent.Callable;
@@ -447,4 +448,62 @@
executor.shutdown();
}
}
+
+ // b/26354315
+ public void testDoNotCallCloseFromSocketCtor() {
+ // Original openJdk7 Socket implementation may call Socket#close() inside a constructor.
+ // In this case, classes that extend Socket wont be fully constructed when they
+ // receive #close() call. This test makes sure this won't happen
+
+ // Extend Socket
+ class SocketThatFailOnClose extends Socket {
+ public SocketThatFailOnClose(String host, int port)
+ throws UnknownHostException, IOException {
+ super(host, port);
+ }
+ public SocketThatFailOnClose(InetAddress address, int port) throws IOException {
+ super(address, port);
+ }
+ public SocketThatFailOnClose(String host, int port, InetAddress localAddr,
+ int localPort) throws IOException {
+ super(host, port, localAddr, localPort);
+ }
+ public SocketThatFailOnClose(InetAddress address, int port, InetAddress localAddr,
+ int localPort) throws IOException {
+ super(address, port, localAddr, localPort);
+ }
+ public SocketThatFailOnClose(String host, int port, boolean stream) throws IOException {
+ super(host, port, stream);
+ }
+ public SocketThatFailOnClose(InetAddress host, int port, boolean stream)
+ throws IOException {
+ super(host, port, stream);
+ }
+
+ @Override
+ public void close() {
+ fail("Do not call close from the Socket constructor");
+ }
+ }
+
+ // Test all Socket ctors
+ try {
+ new SocketThatFailOnClose("localhost", 1);
+ } catch(IOException expected) {}
+ try {
+ new SocketThatFailOnClose(InetAddress.getLocalHost(), 1);
+ } catch(IOException expected) {}
+ try {
+ new SocketThatFailOnClose("localhost", 1, null, 0);
+ } catch(IOException expected) {}
+ try {
+ new SocketThatFailOnClose(InetAddress.getLocalHost(), 1, null, 0);
+ } catch(IOException expected) {}
+ try {
+ new SocketThatFailOnClose("localhost", 1, true);
+ } catch(IOException expected) {}
+ try {
+ new SocketThatFailOnClose(InetAddress.getLocalHost(), 1, true);
+ } catch(IOException expected) {}
+ }
}
diff --git a/ojluni/src/main/java/java/io/FileDescriptor.java b/ojluni/src/main/java/java/io/FileDescriptor.java
index f858e27..8da266b 100755
--- a/ojluni/src/main/java/java/io/FileDescriptor.java
+++ b/ojluni/src/main/java/java/io/FileDescriptor.java
@@ -25,6 +25,10 @@
package java.io;
+import android.system.ErrnoException;
+import android.system.Os;
+import static android.system.OsConstants.F_DUPFD_CLOEXEC;
+
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -74,7 +78,7 @@
*
* @see java.lang.System#in
*/
- public static final FileDescriptor in = new FileDescriptor(0);
+ public static final FileDescriptor in = dupFd(0);
/**
* A handle to the standard output stream. Usually, this file
@@ -82,7 +86,7 @@
* known as <code>System.out</code>.
* @see java.lang.System#out
*/
- public static final FileDescriptor out = new FileDescriptor(1);
+ public static final FileDescriptor out = dupFd(1);
/**
* A handle to the standard error stream. Usually, this file
@@ -91,7 +95,7 @@
*
* @see java.lang.System#err
*/
- public static final FileDescriptor err = new FileDescriptor(2);
+ public static final FileDescriptor err = dupFd(2);
/**
* Tests if this file descriptor object is valid.
@@ -169,6 +173,15 @@
return isSocket(descriptor);
}
+ // Android-added.
+ private static FileDescriptor dupFd(int fd) {
+ try {
+ return new FileDescriptor(Os.fcntlInt(new FileDescriptor(fd), F_DUPFD_CLOEXEC, 0));
+ } catch (ErrnoException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
private static native boolean isSocket(int descriptor);
// package private methods used by FIS, FOS and RAF
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index 72f7469..2aa057f 100755
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -426,7 +426,12 @@
if (address != null)
connect(address);
} catch (IOException e) {
- close();
+ // Do not call #close, classes that extend this class may do not expect a call
+ // to #close coming from the superclass constructor.
+ if (impl != null) {
+ impl.close();
+ }
+ closed = true;
throw e;
}
}
diff --git a/ojluni/src/main/java/java/net/URI.java b/ojluni/src/main/java/java/net/URI.java
index 8c2b9b4..82b8cb6 100755
--- a/ojluni/src/main/java/java/net/URI.java
+++ b/ojluni/src/main/java/java/net/URI.java
@@ -2612,6 +2612,10 @@
private static final long L_DASH = lowMask("-");
private static final long H_DASH = highMask("-");
+ // UNDERSCORE, for use in domainlabel and toplabel
+ private static final long L_UNDERSCORE = lowMask("_");
+ private static final long H_UNDERSCORE = highMask("_");
+
// Dot, for use in hostnames
private static final long L_DOT = lowMask(".");
private static final long H_DOT = highMask(".");
@@ -3371,8 +3375,8 @@
}
// hostname = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
- // domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
- // toplabel = alpha | alpha *( alphanum | "-" ) alphanum
+ // domainlabel = alphanum | alphanum *( alphanum | "-" | "_" ) alphanum
+ // toplabel = alpha | alpha *( alphanum | "-" | "_" ) alphanum
//
private int parseHostname(int start, int n)
throws URISyntaxException
@@ -3382,14 +3386,21 @@
int l = -1; // Start of last parsed label
do {
- // domainlabel = alphanum [ *( alphanum | "-" ) alphanum ]
+ // domainlabel = alphanum [ *( alphanum | "-" | "_" ) alphanum ]
+ //
+ // The RFCs don't permit underscores in hostnames, but URI has to because a certain
+ // large website doesn't seem to care about standards and specs.
+ // http://code.google.com/p/android/issues/detail?id=37577
+ // http://b/17579865
+ // http://b/18016625
+ // http://b/18023709
q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
if (q <= p)
break;
l = p;
if (q > p) {
p = q;
- q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
+ q = scan(p, n, L_ALPHANUM | L_DASH | L_UNDERSCORE, H_ALPHANUM | H_DASH | H_UNDERSCORE);
if (q > p) {
if (charAt(q - 1) == '-')
fail("Illegal character in hostname", q - 1);
diff --git a/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java b/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
index 37c1d5b..8fcfae6 100755
--- a/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileDispatcherImpl.java
@@ -32,7 +32,6 @@
static {
Util.load();
- init();
}
FileDispatcherImpl(boolean append) {
@@ -148,6 +147,4 @@
static native void closeIntFD(int fd) throws IOException;
- static native void init();
-
}
diff --git a/ojluni/src/main/native/FileDispatcherImpl.c b/ojluni/src/main/native/FileDispatcherImpl.c
index 2533b3a..80413f4 100755
--- a/ojluni/src/main/native/FileDispatcherImpl.c
+++ b/ojluni/src/main/native/FileDispatcherImpl.c
@@ -56,22 +56,6 @@
#define fdatasync fsync
#endif
-static int preCloseFD = -1; /* File descriptor to which we dup other fd's
- before closing them for real */
-
-
-JNIEXPORT void JNICALL
-FileDispatcherImpl_init(JNIEnv *env, jclass cl)
-{
- int sp[2];
- if (socketpair(PF_UNIX, SOCK_STREAM, 0, sp) < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "socketpair failed");
- return;
- }
- preCloseFD = sp[0];
- close(sp[1]);
-}
-
JNIEXPORT jint JNICALL
FileDispatcherImpl_read0(JNIEnv *env, jclass clazz,
jobject fdo, jlong address, jint len)
@@ -256,11 +240,15 @@
FileDispatcherImpl_preClose0(JNIEnv *env, jclass clazz, jobject fdo)
{
jint fd = fdval(env, fdo);
- if (preCloseFD >= 0) {
- if (dup2(preCloseFD, fd) < 0) {
- JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
- }
+ int preCloseFD = open("/dev/null", O_RDWR | O_CLOEXEC);
+ if (preCloseFD < 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "open(\"/dev/null\") failed");
+ return;
}
+ if (dup2(preCloseFD, fd) < 0) {
+ JNU_ThrowIOExceptionWithLastError(env, "dup2 failed");
+ }
+ close(preCloseFD);
}
JNIEXPORT void JNICALL
@@ -284,7 +272,6 @@
NATIVE_METHOD(FileDispatcherImpl, readv0, "(Ljava/io/FileDescriptor;JI)J"),
NATIVE_METHOD(FileDispatcherImpl, pread0, "(Ljava/io/FileDescriptor;JIJ)I"),
NATIVE_METHOD(FileDispatcherImpl, read0, "(Ljava/io/FileDescriptor;JI)I"),
- NATIVE_METHOD(FileDispatcherImpl, init, "()V"),
};
void register_sun_nio_ch_FileDispatcherImpl(JNIEnv* env) {