classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

URL's fix


From: Guilhem Lavaux
Subject: URL's fix
Date: Wed, 29 Oct 2003 19:29:48 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3.1) Gecko/20030428

Hi all !


I noticed some misbehaviour of classpath's URL compared to Sun's JDK while merging these classes in kaffe's library. Kaffe's regression test "URLTest" was failing nearly completely. BTW, there was an error when url of the type "http://anonymous:address@hidden/"; was entered: URL reports to detect "anonymous" as the host. This patch fixes all these things.

There is only one drawback: to be able to report errors in parseUrl() (for jar protocol especially) I was obliged to introduce a new error class inheriting from java.lang.Error. This is the only solution to be able to report errors.

Here is the corresponding ChangeLog entry:

2003-10-29      Guilhem Lavaux <address@hidden>

        * gnu/java/net/URLParseError.java: New error class.

        * gnu/java/net/protocol/jar/Handler.java:
        (parseUrl) Fixed error reporting. Fixed URL access
        using relative path.

        * java/net/URL.java:
        (URL) Reports Error generated using URLParseError as
        MalformedURLException.
        
        * java/net/URLStreamHandler:
        (parseUrl) Fixed URL parsing ('@' should be checked
        to distinguish port from userinfo). Fixed relative
        URL handling.

Cheers,
Guilhem.

P.S.: I'm sorry Mark. You have a new patch in the input queue. ;-)
Index: gnu/java/net/protocol/jar/Handler.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/net/protocol/jar/Handler.java,v
retrieving revision 1.6
diff -u -r1.6 Handler.java
--- gnu/java/net/protocol/jar/Handler.java      20 Oct 2003 13:57:39 -0000      
1.6
+++ gnu/java/net/protocol/jar/Handler.java      29 Oct 2003 18:03:13 -0000
@@ -42,6 +42,8 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
+import java.net.MalformedURLException;
+import gnu.java.net.URLParseError;
 
 /**
  * @author Kresten Krab Thorup <address@hidden>
@@ -88,12 +90,14 @@
         && file != "")
       { //has context url
        url_string = url_string.substring (start, end);
-        if (url_string.startsWith("/"))
+        if (url_string.startsWith ("/"))
           { //url string is an absolute path
             int idx = file.lastIndexOf ("!/");
-            if (idx == -1) //context path is weird
-                file = file + "!" + url_string; 
-            else
+           if (idx < 0)
+             throw new URLParseError ("no !/ in spec");
+            //if (idx == -1) //context path is weird
+            //    file = file + "!" + url_string; 
+            //else
                 file = file.substring (0, idx + 1) + url_string;
           }
         else
@@ -108,7 +112,7 @@
               // according to Java API Documentation, here is a little 
different 
               // with URLStreamHandler.parseURL
               // but JDK seems doesn't handle it well
-              file = file + "/" + url_string;
+              file = file.substring(0, idx + 1) + url_string;
           }
         
         setURL (url, "jar", url.getHost(), url.getPort(), file, null);
@@ -125,9 +129,23 @@
     
     // Skip remains of protocol
     url_string = url_string.substring (start, end);
+
+    int jar_stop;
+    if ((jar_stop = url_string.indexOf ("!/")) < 0)
+      throw new URLParseError ("no !/ in spec");
+
+    try
+      {
+       new URL (url_string.substring (0, jar_stop));
+      }
+    catch (MalformedURLException e)
+      {
+       throw new URLParseError("invalid inner URL: " + e.getMessage());
+      }
+    
     
     if (!url.getProtocol().equals ("jar") )
-      return;
+      throw new URLParseError("unexpected protocol " + url.getProtocol());
         
     setURL (url, "jar", url.getHost(), url.getPort(), url_string, null);
   }
Index: java/net/URL.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/URL.java,v
retrieving revision 1.21
diff -u -r1.21 URL.java
--- java/net/URL.java   2 Oct 2003 11:57:56 -0000       1.21
+++ java/net/URL.java   29 Oct 2003 18:03:20 -0000
@@ -45,6 +45,7 @@
 import java.io.ObjectOutputStream;
 import java.util.HashMap;
 import java.util.StringTokenizer;
+import gnu.java.net.URLParseError;
 
 /*
  * Written using on-line Java Platform 1.2 API Specification, as well
@@ -409,8 +410,9 @@
         authority = context.authority;
       }
     else       // Protocol NOT specified in spec. and no context available.
-      throw new
-         MalformedURLException("Absolute URL required with null context");
+               // We do as if it was truely the protocol (behaviour of the
+               // JDK 1.4).
+      protocol = spec;
 
     if (ph != null)
       {
@@ -431,8 +433,15 @@
     // is to be excluded by passing the 'limit' as the indexOf the '#'
     // if one exists, otherwise pass the end of the string.
     int hashAt = spec.indexOf('#', colon + 1);
-    this.ph.parseURL(this, spec, colon + 1,
-                    hashAt < 0 ? spec.length() : hashAt);
+    try 
+      {
+        this.ph.parseURL(this, spec, colon + 1,
+                        hashAt < 0 ? spec.length() : hashAt);
+      }
+    catch (URLParseError e)
+      {
+        throw new MalformedURLException(e.getMessage());
+      }
     if (hashAt >= 0)
       ref = spec.substring(hashAt + 1);
 
Index: java/net/URLStreamHandler.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/URLStreamHandler.java,v
retrieving revision 1.19
diff -u -r1.19 URLStreamHandler.java
--- java/net/URLStreamHandler.java      19 Sep 2003 06:19:42 -0000      1.19
+++ java/net/URLStreamHandler.java      29 Oct 2003 18:03:21 -0000
@@ -129,11 +129,12 @@
     
     if (spec.regionMatches (start, "//", 0, 2))
       {
+       String genuineHost;
        int hostEnd;
-       int colon;
+       int colon, at_host;
 
        start += 2;
-       int slash = spec.indexOf('/', start);
+       int slash = spec.indexOf ('/', start);
        if (slash >= 0) 
          hostEnd = slash;
         else
@@ -141,24 +142,37 @@
 
        host = spec.substring (start, hostEnd);
        
+       // We first need a genuine host name (with userinfo).
+       // So we check for '@': if it's present check the port in the
+       // section after '@' in the other case check it in the full string.
+       // P.S.: We don't care having '@' at the beginning of the string.
+       if ((at_host = host.indexOf ('@')) >= 0)
+         genuineHost = host.substring (at_host);
+       else
+         genuineHost = host;
+
        // 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)
+       if ((colon = genuineHost.indexOf (':')) >= 0)
          {
            try
              {
-               port = Integer.parseInt(host.substring(colon + 1));
+               port = Integer.parseInt (genuineHost.substring (colon + 1));
              }
            catch (NumberFormatException e)
              {
                ; // Ignore invalid port values; port is already set to u's
                  // port.
              }
-           host = host.substring(0, colon);
+           // Now we must cut the port number in the original string.
+           if (at_host >= 0)
+             host = host.substring (0, at_host + colon);
+           else
+             host = host.substring (0, colon);
          }
        file = null;
        start = hostEnd;
@@ -166,12 +180,20 @@
     else if (host == null) 
       host = "";
 
-    if (file == null || file.length() == 0
-       || (start < end && spec.charAt(start) == '/')) 
+    if (file == null || file.length() == 0)
       {
        // No file context available; just spec for file.
-       // Or this is an absolute path name; ignore any file context.
-       file = spec.substring(start, end);
+       // First check that spec is absolute. If it's not the case
+       // prepend a '/'.
+       file = spec.substring (start, end);
+       ref = null;
+       if (start < end && spec.charAt(start) != '/')
+         file = "/" + file;
+      }
+    else if (start < end && spec.charAt(start) == '/') 
+      {
+       // This is an absolute path name; ignore any file context.
+       file = spec.substring (start, end);
        ref = null;
       } 
     else if (start < end)
@@ -180,26 +202,26 @@
         char sepChar = '/';
         int lastSlash = file.lastIndexOf (sepChar);
         if (lastSlash < 0 && File.separatorChar != sepChar
-            && url.getProtocol ().equals ("file"))
+            && url.getProtocol().equals ("file"))
           {
             // On Windows, even '\' is allowed in a "file" URL.
             sepChar = File.separatorChar;
             lastSlash = file.lastIndexOf (sepChar);
           }
         
-        file = file.substring(0, lastSlash)
+        file = file.substring (0, lastSlash)
                 + sepChar + spec.substring (start, end);
 
-        if (url.getProtocol ().equals ("file"))
+        if (url.getProtocol().equals ("file"))
           {
             // For "file" URLs constructed relative to a context, we
             // need to canonicalise the file path.
             try
               {
-               boolean endsWithSlash = file.charAt(file.length() - 1) == '/';
-                file = new File (file).getCanonicalPath ();
+               boolean endsWithSlash = file.charAt (file.length() - 1) == '/';
+                file = new File (file).getCanonicalPath();
                if (endsWithSlash
-                   && file.charAt(file.length() - 1) != '/')
+                   && file.charAt (file.length() - 1) != '/')
                  file += '/';
               }
             catch (IOException e)
--- /dev/null   1970-01-01 01:00:00.000000000 +0100
+++ gnu/java/net/URLParseError.java     2003-10-29 19:09:15.000000000 +0100
@@ -0,0 +1,56 @@
+/* URLParseError.java -- Helps bypassing the exception limitation for
+   parseUrl
+   Copyright (C) 2003 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+ 
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+package gnu.java.net;
+
+/**
+ * This class helps the people writing protocols to report URL parse
+ * errors in parseUrl as this method cannot report other exceptions
+ * than Errors.
+ *
+ * The main drawback is that it uses the Error mechanism which should not
+ * be used for that type of error reporting.
+ *
+ * @author Guilhem Lavaux <address@hidden>
+ */
+
+public class URLParseError extends Error {
+       public URLParseError(String msg)
+       {
+               super(msg);
+       }
+}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]