URLs are not unquoted when opening files

Andrew Haley aph@redhat.com
Wed Jul 13 16:01:00 GMT 2005


A file: URL that contains quoted hex characters isn't unquoted when we
try to open the file, so the open fails.  To fix this we unquote in
much the same way as URI does.  It would be nice simply to use
URI.unquote, but it's in a different package and is private.

For compatibility it's important not to unquote except when we
actually want to access the real file.

Andrew.


2005-07-13  Andrew Haley  <aph@redhat.com>

	* gnu/java/net/protocol/file/Connection.java (unquote): New
	method.
	(connect): Unquote filename.
	gnu/java/net/protocol/jar/Connection.java (getInputStream):
	Likewise.  
	(getJarFile): Likewise.

Index: libjava/gnu/java/net/protocol/file/Connection.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/net/protocol/file/Connection.java,v
retrieving revision 1.9
diff -u -r1.9 Connection.java
--- libjava/gnu/java/net/protocol/file/Connection.java	10 Sep 2004 11:06:38 -0000	1.9
+++ libjava/gnu/java/net/protocol/file/Connection.java	13 Jul 2005 15:49:37 -0000
@@ -57,6 +57,7 @@
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
+import java.net.MalformedURLException;
 
 /**
  * This subclass of java.net.URLConnection models a URLConnection via
@@ -113,6 +114,54 @@
   }
   
   /**
+   * Unquote "%" + hex quotes characters
+   *
+   * @param str The string to unquote or null.
+   *
+   * @return The unquoted string or null if str was null.
+   *
+   * @exception MalformedURLException If the given string contains invalid
+   * escape sequences.
+   *
+   * Sadly the same as URI.unquote, but there's nothing we can do to
+   * make it accessible.
+   *
+   */
+  public static String unquote(String str) throws MalformedURLException
+  {
+    if (str == null)
+      return null;
+    byte[] buf = new byte[str.length()];
+    int pos = 0;
+    for (int i = 0; i < str.length(); i++)
+      {
+	char c = str.charAt(i);
+	if (c > 127)
+	  throw new MalformedURLException(str + " : Invalid character");
+	if (c == '%')
+	  {
+	    if (i + 2 >= str.length())
+	      throw new MalformedURLException(str + " : Invalid quoted character");
+	    int hi = Character.digit(str.charAt(++i), 16);
+	    int lo = Character.digit(str.charAt(++i), 16);
+	    if (lo < 0 || hi < 0)
+	      throw new MalformedURLException(str + " : Invalid quoted character");
+	    buf[pos++] = (byte) (hi * 16 + lo);
+	  }
+	else
+	  buf[pos++] = (byte) c;
+      }
+    try
+      {
+	return new String(buf, 0, pos, "utf-8");
+      }
+    catch (java.io.UnsupportedEncodingException x2)
+      {
+	throw (Error) new InternalError().initCause(x2);
+      }
+  }
+
+  /**
    * "Connects" to the file by opening it.
    */
   public void connect() throws IOException
@@ -122,7 +171,7 @@
       return;
     
     // If not connected, then file needs to be openned.
-    file = new File (getURL().getFile());
+    file = new File (unquote(getURL().getFile()));
 
     if (! file.isDirectory())
       {
Index: libjava/gnu/java/net/protocol/jar/Connection.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/net/protocol/jar/Connection.java,v
retrieving revision 1.8.6.1
diff -u -r1.8.6.1 Connection.java
--- libjava/gnu/java/net/protocol/jar/Connection.java	20 May 2005 20:02:16 -0000	1.8.6.1
+++ libjava/gnu/java/net/protocol/jar/Connection.java	13 Jul 2005 15:49:37 -0000
@@ -152,7 +152,8 @@
     if (jarfile != null)
       {
 	// this is the easy way...
-	ZipEntry entry = jarfile.getEntry(getEntryName());
+	ZipEntry entry = jarfile.getEntry
+	  (gnu.java.net.protocol.file.Connection.unquote(getEntryName()));
         
 	if (entry != null)
 	  return jarfile.getInputStream (entry);
@@ -163,12 +164,14 @@
 	JarInputStream zis = new JarInputStream(
 			jarFileURLConnection.getInputStream ());
 
+	String entryName = gnu.java.net.protocol.file.Connection.unquote(getEntryName());
+
 	// This is hideous, we're doing a linear search...
 	for (ZipEntry entry = zis.getNextEntry(); 
 	     entry != null; 
 	     entry = zis.getNextEntry())
 	  {
-	    if (getEntryName().equals(entry.getName()))
+	    if (entryName.equals(entry.getName()))
 	      {
 		int size = (int) entry.getSize();
 		byte[] data = new byte[size];
@@ -205,12 +208,14 @@
 	    jar_file = (JarFile) file_cache.get (jarFileURL);
 	    if (jar_file == null)
 	      {
-		jar_file = new JarFile (jarFileURL.getFile());
+		jar_file = new JarFile 
+		  (gnu.java.net.protocol.file.Connection.unquote(jarFileURL.getFile()));
 		file_cache.put (jarFileURL, jar_file);
 	      }
 	  }
 	else
-	  jar_file = new JarFile (jarFileURL.getFile());
+	  jar_file = new JarFile 
+	    (gnu.java.net.protocol.file.Connection.unquote(jarFileURL.getFile()));
       }
     else
       {



More information about the Java-patches mailing list