src/java.base/share/classes/java/net/URL.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54696 0907dce4b90e
child 58679 9c3209ff7550
--- a/src/java.base/share/classes/java/net/URL.java	Thu Oct 17 20:27:44 2019 +0100
+++ b/src/java.base/share/classes/java/net/URL.java	Thu Oct 17 20:53:35 2019 +0100
@@ -45,6 +45,7 @@
 
 import jdk.internal.access.JavaNetURLAccess;
 import jdk.internal.access.SharedSecrets;
+import sun.net.util.IPAddressUtil;
 import sun.security.util.SecurityConstants;
 import sun.security.action.GetPropertyAction;
 
@@ -174,6 +175,7 @@
 public final class URL implements java.io.Serializable {
 
     static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol";
+    @java.io.Serial
     static final long serialVersionUID = -7627629688361524110L;
 
     /**
@@ -327,10 +329,13 @@
      * </ol>
      *
      * <p>Protocol handlers for the following protocols are guaranteed
-     * to exist on the search path :-
-     * <blockquote><pre>
-     *     http, https, file, and jar
-     * </pre></blockquote>
+     * to exist on the search path:
+     * <ul>
+     * <li>{@code http}</li>
+     * <li>{@code https}</li>
+     * <li>{@code file}</li>
+     * <li>{@code jar}</li>
+     * </ul>
      * Protocol handlers for additional protocols may also be  available.
      * Some protocol handlers, for example those used for loading platform
      * classes or classes on the class path, may not be overridden. The details
@@ -344,7 +349,7 @@
      * @param      host       the name of the host.
      * @param      port       the port number on the host.
      * @param      file       the file on the host
-     * @exception  MalformedURLException  if an unknown protocol or the port
+     * @throws     MalformedURLException  if an unknown protocol or the port
      *                  is a negative number other than -1
      * @see        java.lang.System#getProperty(java.lang.String)
      * @see        java.net.URL#setURLStreamHandlerFactory(
@@ -373,7 +378,7 @@
      * @param      protocol   the name of the protocol to use.
      * @param      host       the name of the host.
      * @param      file       the file on the host.
-     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @throws     MalformedURLException  if an unknown protocol is specified.
      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
      *                  int, java.lang.String)
      */
@@ -407,9 +412,9 @@
      * @param      port       the port number on the host.
      * @param      file       the file on the host
      * @param      handler    the stream handler for the URL.
-     * @exception  MalformedURLException  if an unknown protocol or the port
+     * @throws     MalformedURLException  if an unknown protocol or the port
                         is a negative number other than -1
-     * @exception  SecurityException
+     * @throws     SecurityException
      *        if a security manager exists and its
      *        {@code checkPermission} method doesn't allow
      *        specifying a stream handler explicitly.
@@ -466,13 +471,29 @@
             this.file = path;
         }
 
-        // Note: we don't do validation of the URL here. Too risky to change
+        // Note: we don't do full validation of the URL here. Too risky to change
         // right now, but worth considering for future reference. -br
         if (handler == null &&
             (handler = getURLStreamHandler(protocol)) == null) {
             throw new MalformedURLException("unknown protocol: " + protocol);
         }
         this.handler = handler;
+        if (host != null && isBuiltinStreamHandler(handler)) {
+            String s = IPAddressUtil.checkExternalForm(this);
+            if (s != null) {
+                throw new MalformedURLException(s);
+            }
+        }
+        if ("jar".equalsIgnoreCase(protocol)) {
+            if (handler instanceof sun.net.www.protocol.jar.Handler) {
+                // URL.openConnection() would throw a confusing exception
+                // so generate a better exception here instead.
+                String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
+                if (s != null) {
+                    throw new MalformedURLException(s);
+                }
+            }
+        }
     }
 
     /**
@@ -483,7 +504,7 @@
      * constructor with a {@code null} first argument.
      *
      * @param      spec   the {@code String} to parse as a URL.
-     * @exception  MalformedURLException  if no protocol is specified, or an
+     * @throws     MalformedURLException  if no protocol is specified, or an
      *               unknown protocol is found, or {@code spec} is {@code null},
      *               or the parsed URL fails to comply with the specific syntax
      *               of the associated protocol.
@@ -532,7 +553,7 @@
      *
      * @param      context   the context in which to parse the specification.
      * @param      spec      the {@code String} to parse as a URL.
-     * @exception  MalformedURLException  if no protocol is specified, or an
+     * @throws     MalformedURLException  if no protocol is specified, or an
      *               unknown protocol is found, or {@code spec} is {@code null},
      *               or the parsed URL fails to comply with the specific syntax
      *               of the associated protocol.
@@ -554,11 +575,11 @@
      * @param      context   the context in which to parse the specification.
      * @param      spec      the {@code String} to parse as a URL.
      * @param      handler   the stream handler for the URL.
-     * @exception  MalformedURLException  if no protocol is specified, or an
+     * @throws     MalformedURLException  if no protocol is specified, or an
      *               unknown protocol is found, or {@code spec} is {@code null},
      *               or the parsed URL fails to comply with the specific syntax
      *               of the associated protocol.
-     * @exception  SecurityException
+     * @throws     SecurityException
      *        if a security manager exists and its
      *        {@code checkPermission} method doesn't allow
      *        specifying a stream handler.
@@ -1031,14 +1052,19 @@
      * to a URI. However, some URLs that are not strictly in compliance
      * can not be converted to a URI.
      *
-     * @exception URISyntaxException if this URL is not formatted strictly according to
+     * @throws    URISyntaxException if this URL is not formatted strictly according to
      *            RFC2396 and cannot be converted to a URI.
      *
      * @return    a URI instance equivalent to this URL.
      * @since 1.5
      */
     public URI toURI() throws URISyntaxException {
-        return new URI (toString());
+        URI uri = new URI(toString());
+        if (authority != null && isBuiltinStreamHandler(handler)) {
+            String s = IPAddressUtil.checkAuthority(this);
+            if (s != null) throw new URISyntaxException(authority, s);
+        }
+        return uri;
     }
 
     /**
@@ -1066,7 +1092,7 @@
      *
      * @return     a {@link java.net.URLConnection URLConnection} linking
      *             to the URL.
-     * @exception  IOException  if an I/O exception occurs.
+     * @throws     IOException  if an I/O exception occurs.
      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
      *             int, java.lang.String)
      */
@@ -1087,13 +1113,13 @@
      *             will be made. If direct connection is desired,
      *             Proxy.NO_PROXY should be specified.
      * @return     a {@code URLConnection} to the URL.
-     * @exception  IOException  if an I/O exception occurs.
-     * @exception  SecurityException if a security manager is present
+     * @throws     IOException  if an I/O exception occurs.
+     * @throws     SecurityException if a security manager is present
      *             and the caller doesn't have permission to connect
      *             to the proxy.
-     * @exception  IllegalArgumentException will be thrown if proxy is null,
+     * @throws     IllegalArgumentException will be thrown if proxy is null,
      *             or proxy has the wrong type
-     * @exception  UnsupportedOperationException if the subclass that
+     * @throws     UnsupportedOperationException if the subclass that
      *             implements the protocol handler doesn't support
      *             this method.
      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
@@ -1132,7 +1158,7 @@
      * </pre></blockquote>
      *
      * @return     an input stream for reading from the URL connection.
-     * @exception  IOException  if an I/O exception occurs.
+     * @throws     IOException  if an I/O exception occurs.
      * @see        java.net.URL#openConnection()
      * @see        java.net.URLConnection#getInputStream()
      */
@@ -1147,7 +1173,7 @@
      * </pre></blockquote>
      *
      * @return     the contents of this URL.
-     * @exception  IOException  if an I/O exception occurs.
+     * @throws     IOException  if an I/O exception occurs.
      * @see        java.net.URLConnection#getContent()
      */
     public final Object getContent() throws java.io.IOException {
@@ -1164,7 +1190,7 @@
      * @return     the content object of this URL that is the first match of
      *               the types specified in the classes array.
      *               null if none of the requested types are supported.
-     * @exception  IOException  if an I/O exception occurs.
+     * @throws     IOException  if an I/O exception occurs.
      * @see        java.net.URLConnection#getContent(Class[])
      * @since 1.3
      */
@@ -1192,8 +1218,8 @@
      * This could result in a SecurityException.
      *
      * @param      fac   the desired factory.
-     * @exception  Error  if the application has already set a factory.
-     * @exception  SecurityException  if a security manager exists and its
+     * @throws     Error  if the application has already set a factory.
+     * @throws     SecurityException  if a security manager exists and its
      *             {@code checkSetFactory} method doesn't allow
      *             the operation.
      * @see        java.net.URL#URL(java.lang.String, java.lang.String,
@@ -1477,6 +1503,7 @@
      * @serialField    hashCode int
      *
      */
+    @java.io.Serial
     private static final ObjectStreamField[] serialPersistentFields = {
         new ObjectStreamField("protocol", String.class),
         new ObjectStreamField("host", String.class),
@@ -1496,6 +1523,7 @@
      * the protocol variable returns a valid URLStreamHandler and
      * throw an IOException if it does not.
      */
+    @java.io.Serial
     private synchronized void writeObject(java.io.ObjectOutputStream s)
         throws IOException
     {
@@ -1507,6 +1535,7 @@
      * stream.  It reads the components of the URL and finds the local
      * stream handler.
      */
+    @java.io.Serial
     private synchronized void readObject(java.io.ObjectInputStream s)
             throws IOException, ClassNotFoundException {
         GetField gf = s.readFields();
@@ -1538,7 +1567,7 @@
      * @throws ObjectStreamException if a new object replacing this
      * object could not be created
      */
-
+   @java.io.Serial
    private Object readResolve() throws ObjectStreamException {
 
         URLStreamHandler handler = null;
@@ -1635,6 +1664,10 @@
         return replacementURL;
     }
 
+    boolean isBuiltinStreamHandler(URLStreamHandler handler) {
+       return isBuiltinStreamHandler(handler.getClass().getName());
+    }
+
     private boolean isBuiltinStreamHandler(String handlerClassName) {
         return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
     }