Hi,

Roman found a nasty bug in our URL handling when constructing a complete
spec with a base URL of a different protocol. We need to make sure to
use the URLStreamHandler of the base URL when constructing a new URL
from a base and a (partial) spec (see bug #25141, for which there is
already a mauve test - Thanks Tom!). But not when the spec is a complete
URL (in which case we can just throw away the base URL).

Our chaining of constructors made it a little difficult to see whether a
supplied URLStreamHandler came from the user (in which case it must
always be used) and when it was derived from the base URL. So this patch
adds a new private constructor that gets called from all public
constructors that take a base and a spec so they can indicate whether
the URLStreamHandler is user supplied or not.

2006-12-07  Mark Wielaard  <[EMAIL PROTECTED]>

    * java/net/URL.java (URL(URL,String,URLStreamHandler,boolean)): New
    private constructor.
    (URL(URL,String,URLStreamHandler)): Call new constructor.
    (URL(URL,String)): Likewise.
    (URL(String)): Likewise.

A mauve test has been added and this makes jgecko work much better. Will
also go onto release and generics branch. Note that libgcj already has
this behavior, but still has bug #25141 because URL.java isn't merged.  

Committed,

Mark
Index: java/net/URL.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/net/URL.java,v
retrieving revision 1.55
diff -u -r1.55 URL.java
--- java/net/URL.java	2 Aug 2006 23:14:19 -0000	1.55
+++ java/net/URL.java	7 Dec 2006 20:07:26 -0000
@@ -322,7 +322,8 @@
    */
   public URL(String spec) throws MalformedURLException
   {
-    this((URL) null, spec != null ? spec : "", (URLStreamHandler) null);
+    this((URL) null, spec != null ? spec : "", (URLStreamHandler) null,
+	 false);
   }
 
   /**
@@ -343,7 +344,9 @@
    */
   public URL(URL context, String spec) throws MalformedURLException
   {
-    this(context, spec, (context == null) ? (URLStreamHandler)null : context.ph);
+    this(context, spec,
+	 (context == null) ? (URLStreamHandler) null : context.ph,
+	 false);
   }
 
   /**
@@ -377,6 +380,23 @@
   public URL(URL context, String spec, URLStreamHandler ph)
     throws MalformedURLException
   {
+    this(context, spec, ph, true);
+  }
+
+  /**
+   * Private constructor called by all other constructors taking
+   * a context and spec.
+   *
+   * @param context The context in which to parse the specification
+   * @param spec The string to parse as an URL
+   * @param ph The stream handler for the URL
+   * @param phFromUser Whether or not the user supplied the URLStreamHandler
+   *
+   */
+  private URL(URL context, String spec, URLStreamHandler ph,
+	      boolean phFromUser)
+    throws MalformedURLException
+  {
     /* A protocol is defined by the doc as the substring before a ':'
      * as long as the ':' occurs before any '/'.
      *
@@ -397,7 +417,11 @@
     if ((colon = spec.indexOf("://", 1)) > 0
 	&& ((colon < slash || slash < 0))
         && ! spec.regionMatches(colon, "://:", 0, 4))
-      context = null;
+      {
+	context = null;
+	if (! phFromUser)
+	  ph = null;
+      }
 
     boolean protocolSpecified = false;
 
@@ -458,7 +482,7 @@
     if (ph != null)
       {
 	SecurityManager s = System.getSecurityManager();
-	if (s != null)
+	if (s != null && phFromUser)
 	  s.checkPermission(new NetPermission("specifyStreamHandler"));
 
 	this.ph = ph;

Reply via email to