Patch: File.toURL() and URLStreamHandler.parseURL() fixes
Ranjit Mathew
rmathew@hotmail.com
Sun Feb 23 16:25:00 GMT 2003
Hi,
As promised earlier, this is a fuller patch for the URL
parsing problems in libgcj w.r.t. Win32.
In the process, I found a problem with File.isAbsolute( )
which affected the generated URLs on Win32 - on Win32, a
path is not absolute even if it starts with a '\' as the
drive specifier needs to be prefixed. For example, "\temp"
could mean either "c:\temp" or "d:\temp" or whatever,
depending on the current working directory of the user.
This is also consistent with Sun's JDK.
I have made File.toURL( ) more consistent with the URLs
emitted by Sun's JDK - the URLs are like "file:/c:/foo/bar.txt"
on Win32 and "file:/foo/bar.txt" on UNIX. (Tested with
Sun's JDK 1.3.1 on Solaris 2.6 and JDK 1.4.1 on Win98.)
Finally, according to the JDK docs, if a relative path
is used with a context URL, it should be canonicalised - check
the JDK 1.4.1 docs for URL( URL context, String spec).
After this patch, the output of GCJ matches that of
Sun's JDK for a large number of cases, at least on
Win98 and with Sun's JDK 1.4.1.
It also solves the original problem reported by Erik
about loading and reading a property file using
getResourceAsStream( ) of the system ClassLoader.
Ranjit.
Index: ChangeLog
from Ranjit Mathew <rmathew@hotmail.com>
* java/io/File (getAbsolutePath): Prefix drive specifier on
Windows for paths starting with a '\'.
(toURL): Make URL more consistent with what Sun's JDK returns.
* java/io/natFileWin32.cc (java::io::File::isAbsolute): Return
true only if the path is a UNC network path or it starts with a
drive specifier.
* java/net/URLStreamHandler.java (parseURL): Correct minor typo.
Be prepared to handle either '/' or '\\' in the file path for
Windows if using the "file" protocol.
Canonicalise the file path if using a relative path in the given
context and the "file" protocol.
Index: java/io/File.java
===================================================================
--- java/io/File.java 2003-02-23 16:35:53.000000000 +0530
+++ java/io/File.java 2003-02-23 20:49:49.000000000 +0530
@@ -1,5 +1,5 @@
// File.java - File name
-/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
This file is part of libgcj.
@@ -159,5 +159,14 @@
if (isAbsolute ())
return path;
- return System.getProperty("user.dir") + separatorChar + path;
+ else if (separatorChar == '\\'
+ && path.length () > 0 && path.charAt (0) == '\\')
+ {
+ // On Windows, even if the path starts with a '\\' it is not
+ // really absolute until we prefix the drive specifier from
+ // the current working directory to it.
+ return System.getProperty ("user.dir").substring (0, 2) + path;
+ }
+ else
+ return System.getProperty ("user.dir") + separatorChar + path;
}
@@ -290,6 +299,12 @@
public URL toURL () throws MalformedURLException
{
- return new URL ("file://" + getAbsolutePath ()
- + (isDirectory() ? "/" : ""));
+ // On Win32, Sun's JDK returns URLs of the form "file:/c:/foo/bar.txt",
+ // while on UNIX, it returns URLs of the form "file:/foo/bar.txt".
+ if (separatorChar == '\\')
+ return new URL ("file:/" + getAbsolutePath ().replace ('\\', '/')
+ + (isDirectory() ? "/" : ""));
+ else
+ return new URL ("file:" + getAbsolutePath ()
+ + (isDirectory() ? "/" : ""));
}
Index: java/io/natFileWin32.cc
===================================================================
--- java/io/natFileWin32.cc 2003-02-23 20:06:26.000000000 +0530
+++ java/io/natFileWin32.cc 2003-02-23 20:49:20.000000000 +0530
@@ -120,7 +120,12 @@
java::io::File::isAbsolute (void)
{
- if (path->length() > 0
- && (path->charAt(0) == '/' || path->charAt(0) == '\\'))
+ // See if the path represents a Windows UNC network path.
+ if (path->length () > 1
+ && (path->charAt (0) == '\\') && (path->charAt (1) == '\\'))
return true;
+
+ // Note that the path is not an absolute path even if it starts with
+ // a '/' or a '\' because it lacks a drive specifier.
+
if (path->length() < 3)
return false;
Index: java/net/URLStreamHandler.java
===================================================================
--- java/net/URLStreamHandler.java 2003-02-19 00:33:08.000000000 +0530
+++ java/net/URLStreamHandler.java 2003-02-23 21:19:27.000000000 +0530
@@ -1,4 +1,4 @@
/* URLStreamHandler.java -- Abstract superclass for all protocol handlers
- Copyright (C) 1998, 1999, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -40,4 +40,5 @@
import java.io.IOException;
+import java.io.File;
/*
@@ -113,5 +114,5 @@
* syntax should override this method. The lone exception is that if
* the protocol name set in the URL is "file", this method will accept
- * a an empty hostname (i.e., "file:///"), which is legal for that protocol
+ * an empty hostname (i.e., "file:///"), which is legal for that protocol
*
* @param url The URL object in which to store the results
@@ -177,6 +178,30 @@
{
// Context is available, but only override it if there is a new file.
- file = file.substring(0, file.lastIndexOf('/'))
- + '/' + spec.substring(start, end);
+ char sepChar = '/';
+ int lastSlash = file.lastIndexOf (sepChar);
+ if (lastSlash < 0 && File.separatorChar != sepChar
+ && 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)
+ + sepChar + spec.substring (start, end);
+
+ if (url.getProtocol ().equals ("file"))
+ {
+ // For "file" URLs constructed relative to a context, we
+ // need to canonicalise the file path.
+ try
+ {
+ file = new File (file).getCanonicalPath ();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
ref = null;
}
More information about the Java-patches
mailing list