2016-03-01 17:20 GMT+03:00  <ma...@apache.org>:
> Author: markt
> Date: Tue Mar  1 14:20:56 2016
> New Revision: 1733077
>
> URL: http://svn.apache.org/viewvc?rev=1733077&view=rev
> Log:
> Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=59001
> Correctly handle the case when Tomcat is installed on a path where one of the 
> segments ends in an exclamation mark.
>
> Modified:
>     tomcat/trunk/java/org/apache/catalina/startup/ClassLoaderFactory.java
>     tomcat/trunk/java/org/apache/catalina/startup/ContextConfig.java
>     tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java
>     tomcat/trunk/java/org/apache/catalina/startup/Tomcat.java
>     tomcat/trunk/java/org/apache/catalina/webresources/JarResourceSet.java
>     tomcat/trunk/java/org/apache/catalina/webresources/JarWarResourceSet.java
>     tomcat/trunk/java/org/apache/tomcat/util/buf/UriUtil.java
>     tomcat/trunk/java/org/apache/tomcat/util/scan/StandardJarScanner.java
>     tomcat/trunk/webapps/docs/changelog.xml
>
> Modified: 
> tomcat/trunk/java/org/apache/catalina/startup/ClassLoaderFactory.java
> URL: 
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/ClassLoaderFactory.java?rev=1733077&r1=1733076&r2=1733077&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/catalina/startup/ClassLoaderFactory.java 
> (original)
> +++ tomcat/trunk/java/org/apache/catalina/startup/ClassLoaderFactory.java Tue 
> Mar  1 14:20:56 2016
> @@ -18,6 +18,7 @@ package org.apache.catalina.startup;
>
>  import java.io.File;
>  import java.io.IOException;
> +import java.net.MalformedURLException;
>  import java.net.URL;
>  import java.net.URLClassLoader;
>  import java.security.AccessController;
> @@ -160,7 +161,7 @@ public final class ClassLoaderFactory {
>          if (repositories != null) {
>              for (Repository repository : repositories)  {
>                  if (repository.getType() == RepositoryType.URL) {
> -                    URL url = new URL(repository.getLocation());
> +                    URL url = buildClassLoaderUrl(repository.getLocation());
>                      if (log.isDebugEnabled())
>                          log.debug("  Including URL " + url);
>                      set.add(url);
> @@ -170,7 +171,7 @@ public final class ClassLoaderFactory {
>                      if (!validateFile(directory, RepositoryType.DIR)) {
>                          continue;
>                      }
> -                    URL url = directory.toURI().toURL();
> +                    URL url = buildClassLoaderUrl(directory);
>                      if (log.isDebugEnabled())
>                          log.debug("  Including directory " + url);
>                      set.add(url);
> @@ -180,7 +181,7 @@ public final class ClassLoaderFactory {
>                      if (!validateFile(file, RepositoryType.JAR)) {
>                          continue;
>                      }
> -                    URL url = file.toURI().toURL();
> +                    URL url = buildClassLoaderUrl(file);
>                      if (log.isDebugEnabled())
>                          log.debug("  Including jar file " + url);
>                      set.add(url);
> @@ -209,7 +210,7 @@ public final class ClassLoaderFactory {
>                          if (log.isDebugEnabled())
>                              log.debug("    Including glob jar file "
>                                  + file.getAbsolutePath());
> -                        URL url = file.toURI().toURL();
> +                        URL url = buildClassLoaderUrl(file);
>                          set.add(url);
>                      }
>                  }
> @@ -273,6 +274,30 @@ public final class ClassLoaderFactory {
>          return true;
>      }
>
> +
> +    /*
> +     * These two methods would ideally be in the utility class
> +     * org.apache.tomcat.util.buf.UriUtil but that class is not visible until
> +     * after the class loaders have been constructed.
> +     */
> +    public static URL buildClassLoaderUrl(String urlString) throws 
> MalformedURLException {
> +        // URLs passed to class loaders may point to directories that contain
> +        // JARs. If these URLs are used to construct URLs for resources in a 
> JAR
> +        // the URL will be used as is. It is therefore necessary to ensure 
> that
> +        // the sequence "!/" is not present in a class loader URL.
> +        String result = urlString.replaceAll("!/", "%21/");
> +        return new URL(result);
> +    }
> +
> +
> +    public static URL buildClassLoaderUrl(File file) throws 
> MalformedURLException {
> +        // Could be a directory or a file
> +        String fileUrlString = file.toURI().toURL().toString();
> +        fileUrlString = fileUrlString.replaceAll("!/", "%21/");
> +        return new URL(fileUrlString);

One more note to this commit.

java.net.URI.toURL() is implemented as the following in JDK 8u72

    public URL toURL()
        throws MalformedURLException {
        if (!isAbsolute())
            throw new IllegalArgumentException("URI is not absolute");
        return new URL(toString());
    }


The above does  File -> URI -> String -> URL,  URL -> String -> String  -> URL.

1. I do not see any testcases in this commit.

The last step performs parsing of String into URL. It needs a testcase
that the parsing performed by (new URL(fileUrlString)) does not
convert "%21/" back to "!/", nullifying the efforts.


2. It will be cheaper to process the String generated from
URI.toString(), making it

File -> URI -> String -> String  -> URL.

        String fileUriString = file.toURI().toString();
        fileUriString = fileUrlString.replaceAll("!/", "%21/");
        return new URL(fileUrlString);


> +    }
> +
> +
>      public static enum RepositoryType {
>          DIR,
>          GLOB,
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to