From: Warren Levy Date: Thu, 3 Jun 1999 22:29:12 +0000 (+0000) Subject: [multiple changes] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a259a24846c8f0e0a9f494af773acff7fa1dcaaf;p=gcc.git [multiple changes] 1999-06-02 Warren Levy * java/net/URL.java (URL(URL,String)): Initialize port to -1. Ignore context if spec is an absolute URL. Fix braindead string comparison. (hashCode): Use JDK 1.2 style algorithm. * java/net/URLStreamHandler.java (parseURL): Reimplement to handle context URL properly. 1999-05-30 Anthony Green * java/net/URLStreamHandler.java (parseURL): Parse relative URLs correctly. Clean up "/../" and "/./" path fragments. From-SVN: r27334 --- diff --git a/libjava/ChangeLog b/libjava/ChangeLog index d6111392b68..bd9afc2e2e6 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,17 @@ +1999-06-02 Warren Levy + + * java/net/URL.java (URL(URL,String)): Initialize port to -1. + Ignore context if spec is an absolute URL. Fix braindead + string comparison. + (hashCode): Use JDK 1.2 style algorithm. + * java/net/URLStreamHandler.java (parseURL): Reimplement to handle + context URL properly. + +1999-05-30 Anthony Green + + * java/net/URLStreamHandler.java (parseURL): Parse relative URLs + correctly. Clean up "/../" and "/./" path fragments. + 1999-05-28 Warren Levy * java/net/DatagramSocket.java (laddr): Removed. diff --git a/libjava/java/net/URL.java b/libjava/java/net/URL.java index da56f49dc2d..b6dc13d8db4 100644 --- a/libjava/java/net/URL.java +++ b/libjava/java/net/URL.java @@ -29,7 +29,7 @@ public final class URL implements Serializable { private String protocol; private String host; - private int port; + private int port = -1; // Initialize for constructor using context. private String file; private String ref; private URLStreamHandler handler; @@ -117,14 +117,22 @@ public final class URL implements Serializable * to the context's file. The optional anchor is not inherited. */ + // If this is an absolute URL, then ignore context completely. + // An absolute URL must have chars prior to "://" but cannot have a colon + // right after the "://". The second colon is for an optional port value + // and implies that the host from the context is used if available. int colon; + if ((colon = spec.indexOf("://", 1)) > 0 && + ! spec.regionMatches(colon, "://:", 0, 4)) + context = null; + int slash; if ((colon = spec.indexOf(':')) > 0 && (colon < (slash = spec.indexOf('/')) || slash < 0)) { // Protocol specified in spec string. protocol = spec.substring(0, colon); - if (context != null && context.protocol == protocol) + if (context != null && context.protocol.equals(protocol)) { // The 1.2 doc specifically says these are copied to the new URL. host = context.host; @@ -222,8 +230,20 @@ public final class URL implements Serializable { // JCL book says this is computed using (only) the hashcodes of the // protocol, host and file fields. Empirical evidence indicates this - // is probably XOR. - return (protocol.hashCode() ^ host.hashCode() ^ file.hashCode()); + // is probably XOR in JDK 1.1. In JDK 1.2 it seems to be a sum including + // the port. + // + // JDK 1.2 online doc infers that host could be null because it + // explicitly states that file cannot be null but is silent on host. + // A simple example with protocol "http" (hashcode 3213448), host null, + // file "/" (hashcode 47) produced a hashcode (3213494) which appeared + // to be the sum of the two hashcodes plus the port. Another example + // using "/index.html" for file bore this out; as well as "#" for file + // (which was reduced to "" with a hashcode of zero). A "" host also + // causes the port number and the two hashcodes to be summed. + + return (protocol.hashCode() + ((host == null) ? 0 : host.hashCode()) + + port + file.hashCode()); } public URLConnection openConnection() throws IOException diff --git a/libjava/java/net/URLStreamHandler.java b/libjava/java/net/URLStreamHandler.java index ae364e4dbf9..ba2114c8068 100644 --- a/libjava/java/net/URLStreamHandler.java +++ b/libjava/java/net/URLStreamHandler.java @@ -28,29 +28,35 @@ public abstract class URLStreamHandler protected void parseURL(URL u, String spec, int start, int limit) { - String tmpStr; - String host = ""; // Initialize to null string. - String file; - int port = -1; - int colon; - + String host = u.getHost(); + int port = u.getPort(); + String file = u.getFile(); + /* TBD: The JDK 1.2 doc specifically says that limit is the position * to stop parsing at and that it will be either the end of the string * or the position of '#'; thus the doc infers that this method does * not set the ref. */ - tmpStr = spec.substring(start, limit); - int hostEnd = 0; - if (tmpStr.startsWith("//")) + if (spec.regionMatches (start, "//", 0, 2)) { - int slash = tmpStr.indexOf('/', 2); - hostEnd = tmpStr.length(); - if (slash >= 0) - hostEnd = slash; + int hostEnd; + int colon; - host = tmpStr.substring(2, hostEnd); - - // Look for optional port number. + start += 2; + int slash = spec.indexOf('/', start); + if (slash >= 0) + hostEnd = slash; + else + hostEnd = limit; + + host = spec.substring (start, hostEnd); + + // Look for optional port number. It is valid for the non-port + // part of the host name to be null (e.g. a URL "http://:80"). + // TBD: JDK 1.2 in this case sets host to null rather than ""; + // this is undocumented and likely an unintended side effect in 1.2 + // so we'll be simple here and stick with "". Note that + // "http://" or "http:///" produce a "" host in JDK 1.2. if ((colon = host.indexOf(':')) >= 0) { try @@ -59,17 +65,55 @@ public abstract class URLStreamHandler } catch (NumberFormatException e) { - ; // Ignore invalid port values; port is already set to -1. + ; // Ignore invalid port values; port is already set to u's + // port. } host = host.substring(0, colon); } + file = null; + start = hostEnd; + } + else if (host == null) + host = ""; + + if (start < limit && spec.charAt(start) == '/') + { + // This is an absolute path name; ignore any file context. + file = spec.substring(start, limit); + } + else if (file == null || file.length() <= 0) + { + // No file context available; just spec for file. + file = "/" + spec.substring(start, limit); + } + else if (start < limit) + { + // Context is available, but only override it if there is a new file. + // FIXME: unsure to what extent `/` and File.separatorChar + // can mix in URLs. Ignore File.separatorChar for now. + file = file.substring(0, file.lastIndexOf('/')) + + "/" + spec.substring(start, limit); } - if (hostEnd < tmpStr.length()) - file = ((tmpStr.startsWith("/")) ? "" : "/") + tmpStr.substring(hostEnd); - else - file = "/"; + int index; + // Replace "/./" with "/". This probably isn't very efficient in + // the general case, but it's probably not bad most of the time. + while ((index = file.indexOf("/./")) >= 0) + file = file.substring(0, index) + file.substring(index + 2); + + // Process "/../" correctly. This probably isn't very efficient in + // the general case, but it's probably not bad most of the time. + while ((index = file.indexOf("/../")) >= 0) + { + // Strip of the previous directory - if it exists. + int previous = file.lastIndexOf('/', index - 1); + if (previous >= 0) + file = file.substring(0, previous) + file.substring(index + 3); + else + file = file.substring(index + 3); + } + u.set(u.getProtocol(), host, port, file, u.getRef()); } @@ -90,12 +134,17 @@ public abstract class URLStreamHandler file = u.getFile(); ref = u.getRef(); - if (! host.equals("")) - { - resStr = resStr + "//" + host; - if (port >= 0) - resStr = resStr + ":" + port; - } + // JDK 1.2 online doc infers that host could be null because it + // explicitly states that file cannot be null, but is silent on host. + // + // Note that this produces different results from JDK 1.2 as JDK 1.2 + // ignores a non-default port if host is null or "". That is inconsistent + // with the spec since the result of this method is spec'ed so it can be + // used to construct a new URL that is equivalent to the original. + if (host == null) + host = ""; + if (port >= 0 || ! (host.length() == 0)) + resStr = resStr + "//" + host + (port < 0 ? "" : ":" + port); resStr = resStr + file;