Merge changes I0f3ea18f,I7204e8ab
* changes:
Update sun.net to OpenJDK8u121-b13.
Add missing / improve existing change markers in sun.net.
diff --git a/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
index 2f5400c..6588e2d 100644
--- a/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
@@ -42,6 +42,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+import java.util.Objects;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
@@ -55,10 +56,10 @@
public class FtpURLConnectionTest extends TestCase {
private static final String FILE_PATH = "test/file/for/FtpURLConnectionTest.txt";
- private static final String USER = "user";
- private static final String PASSWORD = "password";
private static final String SERVER_HOSTNAME = "localhost";
- private static final String USER_HOME_DIR = "/home/user";
+ private static final String VALID_USER = "user";
+ private static final String VALID_PASSWORD = "password";
+ private static final String VALID_USER_HOME_DIR = "/home/user";
private FakeFtpServer fakeFtpServer;
private UnixFakeFileSystem fileSystem;
@@ -68,10 +69,11 @@
super.setUp();
fakeFtpServer = new FakeFtpServer();
fakeFtpServer.setServerControlPort(0 /* allocate port number automatically */);
- fakeFtpServer.addUserAccount(new UserAccount(USER, PASSWORD, USER_HOME_DIR));
+ fakeFtpServer.addUserAccount(new UserAccount(VALID_USER, VALID_PASSWORD,
+ VALID_USER_HOME_DIR));
fileSystem = new UnixFakeFileSystem();
fakeFtpServer.setFileSystem(fileSystem);
- fileSystem.add(new DirectoryEntry(USER_HOME_DIR));
+ fileSystem.add(new DirectoryEntry(VALID_USER_HOME_DIR));
fakeFtpServer.start();
}
@@ -83,17 +85,45 @@
public void testInputUrl() throws Exception {
byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
- URL fileUrl = addFileEntry(FILE_PATH, fileContents);
+ addFileEntry(FILE_PATH, fileContents);
+ URL fileUrl = getFileUrlWithCredentials(VALID_USER, VALID_PASSWORD, FILE_PATH);
URLConnection connection = fileUrl.openConnection();
assertContents(fileContents, connection.getInputStream());
}
+ public void testInputUrl_invalidUserOrPassword() throws Exception {
+ checkInputUrl_invalidUserOrPassword("wrong_user", VALID_PASSWORD);
+ checkInputUrl_invalidUserOrPassword(VALID_USER, "wrong password");
+ }
+
+ public void testInputUrl_missingPassword() throws Exception {
+ URL noPasswordUrl = getFileUrlWithCredentials(VALID_USER, null, FILE_PATH);
+ URLConnection noPasswordConnection = noPasswordUrl.openConnection();
+ try {
+ noPasswordConnection.getInputStream();
+ fail();
+ } catch (IOException expected) {
+ }
+ }
+
+ private void checkInputUrl_invalidUserOrPassword(String user, String password)
+ throws IOException {
+ URL fileUrl = getFileUrlWithCredentials(user, password, FILE_PATH);
+ URLConnection connection = fileUrl.openConnection();
+ try {
+ connection.getInputStream();
+ fail();
+ } catch (sun.net.ftp.FtpLoginException expected) {
+ assertEquals("Invalid username/password", expected.getMessage());
+ }
+ }
+
public void testOutputUrl() throws Exception {
byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
addFileEntry("test/output-url/existing file.txt", fileContents);
byte[] newFileContents = "contents of brand new file".getBytes(UTF_8);
String filePath = "test/output-url/file that is newly created.txt";
- URL fileUrl = new URL(getFileUrlString(filePath));
+ URL fileUrl = getFileUrlWithCredentials(VALID_USER, VALID_PASSWORD, filePath);
URLConnection connection = fileUrl.openConnection();
connection.setDoInput(false);
connection.setDoOutput(true);
@@ -218,7 +248,7 @@
}
private InputStream openFileSystemContents(String fileName) throws IOException {
- String fullFileName = USER_HOME_DIR + "/" + fileName;
+ String fullFileName = VALID_USER_HOME_DIR + "/" + fileName;
FileEntry entry = (FileEntry) fileSystem.getEntry(fullFileName);
assertNotNull("File must exist with name " + fullFileName, entry);
return entry.createInputStream();
@@ -243,18 +273,13 @@
}
}
- private String getFileUrlString(String filePath) {
+ private URL getFileUrlWithCredentials(String user, String password, String filePath) {
+ Objects.requireNonNull(user);
+ Objects.requireNonNull(filePath);
int serverPort = fakeFtpServer.getServerControlPort();
- String urlString = String.format(Locale.US, "ftp://%s:%s@%s:%s/%s",
- USER, PASSWORD, SERVER_HOSTNAME, serverPort, filePath);
- return urlString;
- }
-
- private URL addFileEntry(String filePath, byte[] fileContents) {
- FileEntry fileEntry = new FileEntry(USER_HOME_DIR + "/" + filePath);
- fileEntry.setContents(fileContents);
- fileSystem.add(fileEntry);
- String urlString = getFileUrlString(filePath);
+ String credentials = user + (password == null ? "" : (":" + password));
+ String urlString = String.format(Locale.US, "ftp://%s@%s:%s/%s",
+ credentials, SERVER_HOSTNAME, serverPort, filePath);
try {
return new URL(urlString);
} catch (MalformedURLException e) {
@@ -263,6 +288,13 @@
}
}
+ private URL addFileEntry(String filePath, byte[] fileContents) {
+ FileEntry fileEntry = new FileEntry(VALID_USER_HOME_DIR + "/" + filePath);
+ fileEntry.setContents(fileContents);
+ fileSystem.add(fileEntry);
+ return getFileUrlWithCredentials(VALID_USER, VALID_PASSWORD, filePath);
+ }
+
/**
* A {@link ProxySelector} that selects the same (given) Proxy for all URIs.
*/
diff --git a/luni/src/test/java/libcore/sun/net/util/IPAddressUtilTest.java b/luni/src/test/java/libcore/sun/net/util/IPAddressUtilTest.java
new file mode 100644
index 0000000..9294309
--- /dev/null
+++ b/luni/src/test/java/libcore/sun/net/util/IPAddressUtilTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.sun.net.util;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+import static sun.net.util.IPAddressUtil.textToNumericFormatV4;
+
+public class IPAddressUtilTest extends TestCase {
+
+ public void test_textToNumericFormatV4_valid() {
+ assertBytesEquals(0, 0, 0, 0, textToNumericFormatV4("0.0.0.0"));
+ assertBytesEquals(1, 2, 3, 4, textToNumericFormatV4("1.2.3.4"));
+ assertBytesEquals(255, 255, 255, 255, textToNumericFormatV4("255.255.255.255"));
+ assertBytesEquals(123, 23, 255, 37, textToNumericFormatV4("123.23.255.37"));
+ assertBytesEquals(192, 168, 0, 42, textToNumericFormatV4("192.168.0.42"));
+ }
+
+ public void test_textToNumericFormatV4_invalid() {
+ // Wrong number of components
+ assertNull(textToNumericFormatV4("1"));
+ assertNull(textToNumericFormatV4("1.2"));
+ assertNull(textToNumericFormatV4("1.2.3"));
+ assertNull(textToNumericFormatV4("1.2.3.4.5"));
+
+ // Extra dots in various places
+ assertNull(textToNumericFormatV4("1..3.4"));
+ assertNull(textToNumericFormatV4("1..2.3.4"));
+ assertNull(textToNumericFormatV4(".1.2.3"));
+ assertNull(textToNumericFormatV4(".1.2.3.4"));
+ assertNull(textToNumericFormatV4("1.2.3.4."));
+
+ // Out of bounds values
+ assertNull(textToNumericFormatV4("256.2.3.4"));
+ assertNull(textToNumericFormatV4("1.256.3.4"));
+ assertNull(textToNumericFormatV4("1.2.256.4"));
+ assertNull(textToNumericFormatV4("1.2.3.256"));
+ assertNull(textToNumericFormatV4("1.-2.3.4"));
+ }
+
+ private static void assertBytesEquals(int a, int b, int c, int d, byte[] actual) {
+ byte[] expected = new byte[] { (byte) a, (byte) b, (byte) c, (byte) d };
+ assertTrue("Expected " + Arrays.toString(expected) + ", got " + Arrays.toString(actual),
+ Arrays.equals(expected, actual));
+ }
+
+}
diff --git a/ojluni/src/main/java/sun/net/ExtendedOptionsImpl.java b/ojluni/src/main/java/sun/net/ExtendedOptionsImpl.java
index 94005e0..0b58a99 100644
--- a/ojluni/src/main/java/sun/net/ExtendedOptionsImpl.java
+++ b/ojluni/src/main/java/sun/net/ExtendedOptionsImpl.java
@@ -43,6 +43,17 @@
*/
public class ExtendedOptionsImpl {
+ // Android-removed: System.loadLibrary("net") is not available on Android.
+ /*
+ static {
+ AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
+ System.loadLibrary("net");
+ return null;
+ });
+ init();
+ }
+ */
+
private ExtendedOptionsImpl() {}
public static void checkSetOptionPermission(SocketOption<?> option) {
@@ -71,6 +82,9 @@
}
}
+ // Android-removed: Native initialization logic that doesn't exist on Android.
+ // private static native void init();
+
/*
* Extension native implementations
*
diff --git a/ojluni/src/main/java/sun/net/NetHooks.java b/ojluni/src/main/java/sun/net/NetHooks.java
index 05100d9..153096e 100644
--- a/ojluni/src/main/java/sun/net/NetHooks.java
+++ b/ojluni/src/main/java/sun/net/NetHooks.java
@@ -38,43 +38,45 @@
public final class NetHooks {
- // Android-removed: No SDP support.
- // /**
- // * A provider with hooks to allow sockets be converted prior to binding or
- // * connecting a TCP socket.
- // *
- // * <p> Concrete implementations of this class should define a zero-argument
- // * constructor and implement the abstract methods specified below.
- // */
- // public static abstract class Provider {
- // /**
- // * Initializes a new instance of this class.
- // */
- // protected Provider() {}
- //
- // /**
- // * Invoked prior to binding a TCP socket.
- // */
- // public abstract void implBeforeTcpBind(FileDescriptor fdObj,
- // InetAddress address,
- // int port)
- // throws IOException;
- //
- // /**
- // * Invoked prior to connecting an unbound TCP socket.
- // */
- // public abstract void implBeforeTcpConnect(FileDescriptor fdObj,
- // InetAddress address,
- // int port)
- // throws IOException;
- // }
+ // Android-removed: Android doesn't support Session Description Protocol (SDP).
+ /*
+ /**
+ * A provider with hooks to allow sockets be converted prior to binding or
+ * connecting a TCP socket.
+ *
+ * <p> Concrete implementations of this class should define a zero-argument
+ * constructor and implement the abstract methods specified below.
+ *
+ public static abstract class Provider {
+ /**
+ * Initializes a new instance of this class.
+ *
+ protected Provider() {}
+
+ /**
+ * Invoked prior to binding a TCP socket.
+ *
+ public abstract void implBeforeTcpBind(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException;
+
+ /**
+ * Invoked prior to connecting an unbound TCP socket.
+ *
+ public abstract void implBeforeTcpConnect(FileDescriptor fdObj,
+ InetAddress address,
+ int port)
+ throws IOException;
+ }
+ */
/**
* For now, we load the SDP provider on Solaris. In the future this may
* be changed to use the ServiceLoader facility to allow the deployment of
* other providers.
*/
- // Android-removed: No SDP support
+ // Android-removed: Android doesn't support Session Description Protocol (SDP).
// private static final Provider provider = new sun.net.sdp.SdpProvider();
/**
@@ -85,7 +87,7 @@
int port)
throws IOException
{
- // Android-removed: No SDP support
+ // Android-removed: Android doesn't support Session Description Protocol (SDP).
// provider.implBeforeTcpBind(fdObj, address, port);
}
diff --git a/ojluni/src/main/java/sun/net/NetworkClient.java b/ojluni/src/main/java/sun/net/NetworkClient.java
index 1b311bc..0f76bf6 100644
--- a/ojluni/src/main/java/sun/net/NetworkClient.java
+++ b/ojluni/src/main/java/sun/net/NetworkClient.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -139,7 +139,7 @@
serverSocket.getOutputStream()),
true, encoding);
} catch (UnsupportedEncodingException e) {
- throw new InternalError(encoding +"encoding not found");
+ throw new InternalError(encoding +"encoding not found", e);
}
serverInput = new BufferedInputStream(serverSocket.getInputStream());
}
@@ -244,7 +244,7 @@
* Sets the read timeout.
*
* Note: Public URLConnection (and protocol specific implementations)
- * protect against negative timeout values being set. This implemenation,
+ * protect against negative timeout values being set. This implementation,
* and protocol specific implementations, use -1 to represent the default
* read timeout.
*
diff --git a/ojluni/src/main/java/sun/net/TelnetOutputStream.java b/ojluni/src/main/java/sun/net/TelnetOutputStream.java
index 432e975..74f6c9c 100644
--- a/ojluni/src/main/java/sun/net/TelnetOutputStream.java
+++ b/ojluni/src/main/java/sun/net/TelnetOutputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1994, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -81,7 +81,7 @@
}
/**
- * set the stickyCRLF flag. Tells wether the terminal considers CRLF as a single
+ * set the stickyCRLF flag. Tells whether the terminal considers CRLF as a single
* char.
*
* @param on the <code>boolean</code> to set the flag to.
diff --git a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
index 6ba9b9a..fac57e2 100644
--- a/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
+++ b/ojluni/src/main/java/sun/net/spi/DefaultProxySelector.java
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,13 +33,14 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
-import java.util.StringTokenizer;
import java.io.IOException;
-import sun.misc.RegexpPool;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.StringJoiner;
+import java.util.regex.Pattern;
import sun.net.NetProperties;
import sun.net.SocksProxy;
+import static java.util.regex.Pattern.quote;
/**
* Supports proxy settings using system properties This proxy selector
@@ -87,9 +88,31 @@
private static boolean hasSystemProxies = false;
+ // Android-removed: Nonfunctional init logic: "net" library does not exist on Android.
+ /*
+ static {
+ final String key = "java.net.useSystemProxies";
+ Boolean b = AccessController.doPrivileged(
+ new PrivilegedAction<Boolean>() {
+ public Boolean run() {
+ return NetProperties.getBoolean(key);
+ }});
+ if (b != null && b.booleanValue()) {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("net");
+ return null;
+ }
+ });
+ hasSystemProxies = init();
+ }
+ }
+ */
+
/**
* How to deal with "non proxy hosts":
- * since we do have to generate a RegexpPool we don't want to do that if
+ * since we do have to generate a pattern we don't want to do that if
* it's not necessary. Therefore we do cache the result, on a per-protocol
* basis, and change it only when the "source", i.e. the system property,
* did change.
@@ -101,17 +124,19 @@
static final String defStringVal = "localhost|127.*|[::1]|0.0.0.0|[::0]";
String hostsSource;
- RegexpPool hostsPool;
+ Pattern pattern;
final String property;
final String defaultVal;
static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
+ static NonProxyInfo socksNonProxyInfo = new NonProxyInfo("socksNonProxyHosts", null, null, defStringVal);
+ // Android-changed: Different NonProxyInfo flags for https hosts vs. http.
static NonProxyInfo httpsNonProxyInfo = new NonProxyInfo("https.nonProxyHosts", null, null, defStringVal);
- NonProxyInfo(String p, String s, RegexpPool pool, String d) {
+ NonProxyInfo(String p, String s, Pattern pattern, String d) {
property = p;
hostsSource = s;
- hostsPool = pool;
+ this.pattern = pattern;
defaultVal = d;
}
}
@@ -166,11 +191,13 @@
} else if ("https".equalsIgnoreCase(protocol)) {
// HTTPS uses the same property as HTTP, for backward
// compatibility
- //
- // Android-changed: Allow a different set of flags for https hosts.
+ // Android-changed: Different NonProxyInfo flags for https hosts vs. http.
+ // pinfo = NonProxyInfo.httpNonProxyInfo;
pinfo = NonProxyInfo.httpsNonProxyInfo;
} else if ("ftp".equalsIgnoreCase(protocol)) {
pinfo = NonProxyInfo.ftpNonProxyInfo;
+ } else if ("socket".equalsIgnoreCase(protocol)) {
+ pinfo = NonProxyInfo.socksNonProxyInfo;
}
/**
@@ -214,7 +241,20 @@
* settings (Gnome & Windows) if we were
* instructed to.
*/
- // Android-changed, hasSystemProxies is always false
+ // Android-removed: Dead code, hasSystemProxies is always false.
+ /*
+ if (hasSystemProxies) {
+ String sproto;
+ if (proto.equalsIgnoreCase("socket"))
+ sproto = "socks";
+ else
+ sproto = proto;
+ Proxy sproxy = getSystemProxy(sproto, urlhost);
+ if (sproxy != null) {
+ return sproxy;
+ }
+ }
+ */
return Proxy.NO_PROXY;
}
// If a Proxy Host is defined for that protocol
@@ -227,7 +267,7 @@
nphosts = nprop.defaultVal;
} else {
nprop.hostsSource = null;
- nprop.hostsPool = null;
+ nprop.pattern = null;
}
} else if (nphosts.length() != 0) {
// add the required default patterns
@@ -238,20 +278,11 @@
}
if (nphosts != null) {
if (!nphosts.equals(nprop.hostsSource)) {
- RegexpPool pool = new RegexpPool();
- StringTokenizer st = new StringTokenizer(nphosts, "|", false);
- try {
- while (st.hasMoreTokens()) {
- pool.add(st.nextToken().toLowerCase(), Boolean.TRUE);
- }
- } catch (sun.misc.REException ex) {
- }
- nprop.hostsPool = pool;
+ nprop.pattern = toPattern(nphosts);
nprop.hostsSource = nphosts;
}
}
- if (nprop.hostsPool != null &&
- nprop.hostsPool.match(urlhost) != null) {
+ if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
return Proxy.NO_PROXY;
}
}
@@ -324,4 +355,55 @@
return -1;
}
}
+
+ // Android-removed: Native logic not available/used on Android.
+ /*
+ private native static boolean init();
+ private synchronized native Proxy getSystemProxy(String protocol, String host);
+ */
+
+ /**
+ * @return {@code true} if given this pattern for non-proxy hosts and this
+ * urlhost the proxy should NOT be used to access this urlhost
+ */
+ static boolean shouldNotUseProxyFor(Pattern pattern, String urlhost) {
+ if (pattern == null || urlhost.isEmpty())
+ return false;
+ boolean matches = pattern.matcher(urlhost).matches();
+ return matches;
+ }
+
+ /**
+ * @param mask non-null mask
+ * @return {@link java.util.regex.Pattern} corresponding to this mask
+ * or {@code null} in case mask should not match anything
+ */
+ static Pattern toPattern(String mask) {
+ boolean disjunctionEmpty = true;
+ StringJoiner joiner = new StringJoiner("|");
+ for (String disjunct : mask.split("\\|")) {
+ if (disjunct.isEmpty())
+ continue;
+ disjunctionEmpty = false;
+ String regex = disjunctToRegex(disjunct.toLowerCase());
+ joiner.add(regex);
+ }
+ return disjunctionEmpty ? null : Pattern.compile(joiner.toString());
+ }
+
+ /**
+ * @param disjunct non-null mask disjunct
+ * @return java regex string corresponding to this mask
+ */
+ static String disjunctToRegex(String disjunct) {
+ String regex;
+ if (disjunct.startsWith("*")) {
+ regex = ".*" + quote(disjunct.substring(1));
+ } else if (disjunct.endsWith("*")) {
+ regex = quote(disjunct.substring(0, disjunct.length() - 1)) + ".*";
+ } else {
+ regex = quote(disjunct);
+ }
+ return regex;
+ }
}
diff --git a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
index 7ca0f12..4a58e5f 100644
--- a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
+++ b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,89 +37,84 @@
* @param src a String representing an IPv4 address in standard format
* @return a byte array representing the IPv4 numeric address
*/
+ @SuppressWarnings("fallthrough")
public static byte[] textToNumericFormatV4(String src)
{
- if (src.length() == 0) {
+ byte[] res = new byte[INADDR4SZ];
+
+ long tmpValue = 0;
+ int currByte = 0;
+ boolean newOctet = true;
+
+ int len = src.length();
+ if (len == 0 || len > 15) {
return null;
}
-
- byte[] res = new byte[INADDR4SZ];
- String[] s = src.split("\\.", -1);
- long val;
- try {
- switch(s.length) {
- // BEGIN Android-removed
- /*
- case 1:
- // When only one part is given, the value is stored directly in
- // the network address without any byte rearrangement.
-
- val = Long.parseLong(s[0]);
- if (val < 0 || val > 0xffffffffL)
+ /*
+ * When only one part is given, the value is stored directly in
+ * the network address without any byte rearrangement.
+ *
+ * When a two part address is supplied, the last part is
+ * interpreted as a 24-bit quantity and placed in the right
+ * most three bytes of the network address. This makes the
+ * two part address format convenient for specifying Class A
+ * network addresses as net.host.
+ *
+ * When a three part address is specified, the last part is
+ * interpreted as a 16-bit quantity and placed in the right
+ * most two bytes of the network address. This makes the
+ * three part address format convenient for specifying
+ * Class B net- work addresses as 128.net.host.
+ *
+ * When four parts are specified, each is interpreted as a
+ * byte of data and assigned, from left to right, to the
+ * four bytes of an IPv4 address.
+ *
+ * We determine and parse the leading parts, if any, as single
+ * byte values in one pass directly into the resulting byte[],
+ * then the remainder is treated as a 8-to-32-bit entity and
+ * translated into the remaining bytes in the array.
+ */
+ for (int i = 0; i < len; i++) {
+ char c = src.charAt(i);
+ if (c == '.') {
+ if (newOctet || tmpValue < 0 || tmpValue > 0xff || currByte == 3) {
return null;
- res[0] = (byte) ((val >> 24) & 0xff);
- res[1] = (byte) (((val & 0xffffff) >> 16) & 0xff);
- res[2] = (byte) (((val & 0xffff) >> 8) & 0xff);
- res[3] = (byte) (val & 0xff);
- break;
- case 2:
- // When a two part address is supplied, the last part is
- // interpreted as a 24-bit quantity and placed in the right
- // most three bytes of the network address. This makes the
- // two part address format convenient for specifying Class A
- // network addresses as net.host.
-
- val = Integer.parseInt(s[0]);
- if (val < 0 || val > 0xff)
- return null;
- res[0] = (byte) (val & 0xff);
- val = Integer.parseInt(s[1]);
- if (val < 0 || val > 0xffffff)
- return null;
- res[1] = (byte) ((val >> 16) & 0xff);
- res[2] = (byte) (((val & 0xffff) >> 8) &0xff);
- res[3] = (byte) (val & 0xff);
- break;
- case 3:
- //
- // When a three part address is specified, the last part is
- // interpreted as a 16-bit quantity and placed in the right
- // most two bytes of the network address. This makes the
- // three part address format convenient for specifying
- // Class B net- work addresses as 128.net.host.
- for (int i = 0; i < 2; i++) {
- val = Integer.parseInt(s[i]);
- if (val < 0 || val > 0xff)
- return null;
- res[i] = (byte) (val & 0xff);
}
- val = Integer.parseInt(s[2]);
- if (val < 0 || val > 0xffff)
+ res[currByte++] = (byte) (tmpValue & 0xff);
+ tmpValue = 0;
+ newOctet = true;
+ } else {
+ int digit = Character.digit(c, 10);
+ if (digit < 0) {
return null;
- res[2] = (byte) ((val >> 8) & 0xff);
- res[3] = (byte) (val & 0xff);
- break;
- */
- // END Android-removed
- case 4:
- /*
- * When four parts are specified, each is interpreted as a
- * byte of data and assigned, from left to right, to the
- * four bytes of an IPv4 address.
- */
- for (int i = 0; i < 4; i++) {
- val = Integer.parseInt(s[i]);
- if (val < 0 || val > 0xff)
- return null;
- res[i] = (byte) (val & 0xff);
}
- break;
- default:
- return null;
+ tmpValue *= 10;
+ tmpValue += digit;
+ newOctet = false;
}
- } catch(NumberFormatException e) {
+ }
+ if (newOctet || tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) {
return null;
}
+ switch (currByte) {
+ // BEGIN Android-changed: Require all four parts to be given for an IPv4 address.
+ /*
+ case 0:
+ res[0] = (byte) ((tmpValue >> 24) & 0xff);
+ case 1:
+ res[1] = (byte) ((tmpValue >> 16) & 0xff);
+ case 2:
+ res[2] = (byte) ((tmpValue >> 8) & 0xff);
+ */
+ case 0:
+ case 1:
+ case 2:
+ return null;
+ // END Android-changed: Require all four parts to be given for an IPv4 address.
+ case 3:
+ res[3] = (byte) ((tmpValue >> 0) & 0xff);
+ }
return res;
}
diff --git a/ojluni/src/main/java/sun/net/util/URLUtil.java b/ojluni/src/main/java/sun/net/util/URLUtil.java
index 08c1e43..c25defb 100644
--- a/ojluni/src/main/java/sun/net/util/URLUtil.java
+++ b/ojluni/src/main/java/sun/net/util/URLUtil.java
@@ -76,5 +76,29 @@
return strForm.toString();
}
+
+ // Android-removed: Android doesn't support SecurityManager, so Permissions logic is dead code.
+ /*
+ public static Permission getConnectPermission(URL url) throws IOException {
+ String urlStringLowerCase = url.toString().toLowerCase();
+ if (urlStringLowerCase.startsWith("http:") || urlStringLowerCase.startsWith("https:")) {
+ return getURLConnectPermission(url);
+ } else if (urlStringLowerCase.startsWith("jar:http:") || urlStringLowerCase.startsWith("jar:https:")) {
+ String urlString = url.toString();
+ int bangPos = urlString.indexOf("!/");
+ urlString = urlString.substring(4, bangPos > -1 ? bangPos : urlString.length());
+ URL u = new URL(urlString);
+ return getURLConnectPermission(u);
+ // If protocol is HTTP or HTTPS than use URLPermission object
+ } else {
+ return url.openConnection().getPermission();
+ }
+ }
+
+ private static Permission getURLConnectPermission(URL url) {
+ String urlString = url.getProtocol() + "://" + url.getAuthority() + url.getPath();
+ return new URLPermission(urlString);
+ }
+ */
}
diff --git a/ojluni/src/main/java/sun/net/www/MessageHeader.java b/ojluni/src/main/java/sun/net/www/MessageHeader.java
index 0237a85..34b6307 100644
--- a/ojluni/src/main/java/sun/net/www/MessageHeader.java
+++ b/ojluni/src/main/java/sun/net/www/MessageHeader.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,13 +31,7 @@
import java.io.*;
import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
+import java.util.*;
/** An RFC 844 or MIME message header. Includes methods
for parsing headers from incoming streams, fetching
@@ -61,6 +55,17 @@
}
/**
+ * Returns list of header names in a comma separated list
+ */
+ public synchronized String getHeaderNamesInList() {
+ StringJoiner joiner = new StringJoiner(",");
+ for (int i=0; i<nkeys; i++) {
+ joiner.add(keys[i]);
+ }
+ return joiner.toString();
+ }
+
+ /**
* Reset a message header (all key/values removed)
*/
public synchronized void reset() {
@@ -148,7 +153,7 @@
for (int i=0; i<nkeys; i++) {
if (k.equalsIgnoreCase(keys[i])
&& values[i] != null && values[i].length() > 5
- && values[i].regionMatches(true, 0, "NTLM ", 0, 5)) {
+ && values[i].substring(0, 5).equalsIgnoreCase("NTLM ")) {
found = true;
break;
}
@@ -236,7 +241,8 @@
return filterAndAddHeaders(excludeList, null);
}
- public synchronized Map<String, List<String>> filterAndAddHeaders(String[] excludeList, Map<String, List<String>> include) {
+ public synchronized Map<String, List<String>> filterAndAddHeaders(
+ String[] excludeList, Map<String, List<String>> include) {
boolean skipIt = false;
Map<String, List<String>> m = new HashMap<String, List<String>>();
for (int i = nkeys; --i >= 0;) {
@@ -265,15 +271,13 @@
}
if (include != null) {
- Iterator entries = include.entrySet().iterator();
- while (entries.hasNext()) {
- Map.Entry entry = (Map.Entry)entries.next();
- List l = (List)m.get(entry.getKey());
+ for (Map.Entry<String,List<String>> entry: include.entrySet()) {
+ List<String> l = m.get(entry.getKey());
if (l == null) {
- l = new ArrayList();
- m.put((String)entry.getKey(), l);
+ l = new ArrayList<String>();
+ m.put(entry.getKey(), l);
}
- l.add(entry.getValue());
+ l.addAll(entry.getValue());
}
}
@@ -437,6 +441,7 @@
}
/** Parse and merge a MIME header from an input stream. */
+ @SuppressWarnings("fallthrough")
public void mergeHeader(InputStream is) throws java.io.IOException {
if (is == null)
return;
@@ -458,6 +463,7 @@
break;
case '\t':
c = ' ';
+ /*fall through*/
case ' ':
inKey = false;
break;
diff --git a/ojluni/src/main/java/sun/net/www/MeteredStream.java b/ojluni/src/main/java/sun/net/www/MeteredStream.java
index 17c8b83..26fe85d 100644
--- a/ojluni/src/main/java/sun/net/www/MeteredStream.java
+++ b/ojluni/src/main/java/sun/net/www/MeteredStream.java
@@ -142,15 +142,17 @@
return 0;
}
-// Android-changed: Remove support for Android-removed class ChunkedInputSTream
-// if (in instanceof ChunkedInputStream) {
-// n = in.skip(n);
-// }
-// else {
+ // Android-removed: Removed support for Android-removed class ChunkedInputStream.
+ /*
+ if (in instanceof ChunkedInputStream) {
+ n = in.skip(n);
+ }
+ else {
+ */
// just skip min(n, num_bytes_left)
long min = (n > expected - count) ? expected - count: n;
n = in.skip(min);
-// }
+ // }
justRead(n);
return n;
}
diff --git a/ojluni/src/main/java/sun/net/www/URLConnection.java b/ojluni/src/main/java/sun/net/www/URLConnection.java
index 2760acc..c495928 100644
--- a/ojluni/src/main/java/sun/net/www/URLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/URLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,7 @@
package sun.net.www;
import java.net.URL;
-import java.net.ContentHandler;
import java.util.*;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.BufferedInputStream;
-import java.net.UnknownServiceException;
/**
* A class to represent an active connection to an object
@@ -99,7 +94,7 @@
public Map<String,List<String>> getRequestProperties() {
if (connected)
throw new IllegalStateException("Already connected");
- return Collections.EMPTY_MAP;
+ return Collections.emptyMap();
}
public String getHeaderField(String name) {
diff --git a/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
index 24f2f3b..e9f3d78 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
@@ -81,10 +81,12 @@
*/
public class FtpURLConnection extends URLConnection {
-// Android-changed: Removed support for proxying FTP over HTTP since it
-// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
-// // In case we have to use proxies, we use HttpURLConnection
-// HttpURLConnection http = null;
+ // Android-changed: Removed support for proxying FTP over HTTP.
+ // It relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ /*
+ // In case we have to use proxies, we use HttpURLConnection
+ HttpURLConnection http = null;
+ */
private Proxy instProxy;
InputStream is = null;
@@ -163,6 +165,8 @@
*
* @param url The <code>URL</code> to retrieve or store.
*/
+ // Android-changed: Ctors can throw IOException for NetworkSecurityPolicy enforcement.
+ // public FtpURLConnection(URL url) {
public FtpURLConnection(URL url) throws IOException {
this(url, null);
}
@@ -170,19 +174,22 @@
/**
* Same as FtpURLconnection(URL) with a per connection proxy specified
*/
+ // Android-changed: Ctors can throw IOException for NetworkSecurityPolicy enforcement.
+ // FtpURLConnection(URL url, Proxy p) {
FtpURLConnection(URL url, Proxy p) throws IOException {
super(url);
instProxy = p;
host = url.getHost();
port = url.getPort();
String userInfo = url.getUserInfo();
-
+ // BEGIN Android-added: Enforce NetworkSecurityPolicy.isClearTextTrafficPermitted().
if (!NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted()) {
// Cleartext network traffic is not permitted -- refuse this connection.
throw new IOException("Cleartext traffic not permitted: "
+ url.getProtocol() + "://" + host
+ ((url.getPort() >= 0) ? (":" + url.getPort()) : ""));
}
+ // END Android-added: Enforce NetworkSecurityPolicy.isClearTextTrafficPermitted().
if (userInfo != null) { // get the user and password
int delimiter = userInfo.indexOf(':');
@@ -246,50 +253,56 @@
continue;
}
// OK, we have an http proxy
- // Android-changed: Removed support for proxying FTP over HTTP since it
- // relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ // BEGIN Android-changed: Removed support for proxying FTP over HTTP.
+ // It relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ /*
+ InetSocketAddress paddr = (InetSocketAddress) p.address();
+ try {
+ http = new HttpURLConnection(url, p);
+ http.setDoInput(getDoInput());
+ http.setDoOutput(getDoOutput());
+ if (connectTimeout >= 0) {
+ http.setConnectTimeout(connectTimeout);
+ }
+ if (readTimeout >= 0) {
+ http.setReadTimeout(readTimeout);
+ }
+ http.connect();
+ connected = true;
+ return;
+ } catch (IOException ioe) {
+ sel.connectFailed(uri, paddr, ioe);
+ http = null;
+ }
+ */
sel.connectFailed(uri, p.address(), new IOException("FTP connections over HTTP proxy not supported"));
continue;
-// InetSocketAddress paddr = (InetSocketAddress) p.address();
-// try {
-// http = new HttpURLConnection(url, p);
-// http.setDoInput(getDoInput());
-// http.setDoOutput(getDoOutput());
-// if (connectTimeout >= 0) {
-// http.setConnectTimeout(connectTimeout);
-// }
-// if (readTimeout >= 0) {
-// http.setReadTimeout(readTimeout);
-// }
-// http.connect();
-// connected = true;
-// return;
-// } catch (IOException ioe) {
-// sel.connectFailed(uri, paddr, ioe);
-// http = null;
-// }
+ // END Android-changed: Removed support for proxying FTP over HTTP.
}
}
} else { // per connection proxy specified
p = instProxy;
-// Android-changed: Removed support for proxying FTP over HTTP since it
-// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
-// As specified in the documentation for URL.openConnection(Proxy), we
-// ignore the unsupported proxy and attempt a normal (direct) connection
-// if (p.type() == Proxy.Type.HTTP) {
-// http = new HttpURLConnection(url, instProxy);
-// http.setDoInput(getDoInput());
-// http.setDoOutput(getDoOutput());
-// if (connectTimeout >= 0) {
-// http.setConnectTimeout(connectTimeout);
-// }
-// if (readTimeout >= 0) {
-// http.setReadTimeout(readTimeout);
-// }
-// http.connect();
-// connected = true;
-// return;
-// }
+ // BEGIN Android-changed: Removed support for proxying FTP over HTTP.
+ // It relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ // As specified in the documentation for URL.openConnection(Proxy), we
+ // ignore the unsupported proxy and attempt a normal (direct) connection
+ /*
+ if (p.type() == Proxy.Type.HTTP) {
+ http = new HttpURLConnection(url, instProxy);
+ http.setDoInput(getDoInput());
+ http.setDoOutput(getDoOutput());
+ if (connectTimeout >= 0) {
+ http.setConnectTimeout(connectTimeout);
+ }
+ if (readTimeout >= 0) {
+ http.setReadTimeout(readTimeout);
+ }
+ http.connect();
+ connected = true;
+ return;
+ }
+ */
+ // END Android-changed: Removed support for proxying FTP over HTTP.
}
if (user == null) {
@@ -319,7 +332,7 @@
throw new IOException(fe);
}
try {
- ftp.login(user, password.toCharArray());
+ ftp.login(user, password == null ? null : password.toCharArray());
} catch (sun.net.ftp.FtpProtocolException e) {
ftp.close();
// Backward compatibility
@@ -410,11 +423,14 @@
if (!connected) {
connect();
}
- // Android-changed: Removed support for proxying FTP over HTTP since it
- // relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
-// if (http != null) {
-// return http.getInputStream();
-// }
+
+ // Android-changed: Removed support for proxying FTP over HTTP.
+ // It relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ /*
+ if (http != null) {
+ return http.getInputStream();
+ }
+ */
if (os != null) {
throw new IOException("Already opened for output");
@@ -525,15 +541,18 @@
if (!connected) {
connect();
}
-// Android-changed: Removed support for proxying FTP over HTTP since it
-// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
-// if (http != null) {
-// OutputStream out = http.getOutputStream();
-// // getInputStream() is neccessary to force a writeRequests()
-// // on the http client.
-// http.getInputStream();
-// return out;
-// }
+
+ // Android-changed: Removed support for proxying FTP over HTTP.
+ // It relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+ /*
+ if (http != null) {
+ OutputStream out = http.getOutputStream();
+ // getInputStream() is neccessary to force a writeRequests()
+ // on the http client.
+ http.getInputStream();
+ return out;
+ }
+ */
if (is != null) {
throw new IOException("Already opened for input");
diff --git a/ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java b/ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java
index 62686c6..8e9f8e3 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java
@@ -123,6 +123,7 @@
@Override
+ @SuppressWarnings("deprecation")
protected void parseURL(URL url, String spec,
int start, int limit) {
String file = null;
diff --git a/ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java b/ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java
index ae86964..edd99ff 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
index 4c5dc87..d7c4424 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,7 +125,9 @@
* to get the jarFile, and set it as our permission.
*/
if (getUseCaches()) {
+ boolean oldUseCaches = jarFileURLConnection.getUseCaches();
jarFileURLConnection = factory.getConnection(jarFile);
+ jarFileURLConnection.setUseCaches(oldUseCaches);
}
if ((entryName != null)) {