This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/11.0.x by this push:
     new ee1361afb4 Fix BZ 69426 - restore code source support
ee1361afb4 is described below

commit ee1361afb422c4097d858a383f54ffc68d904843
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Nov 4 13:11:06 2024 +0000

    Fix BZ 69426 - restore code source support
    
    Restore providing a value (rather than null) for
    Class.getProtectionDomain().getCodeSource().getLocation() as a number of
    libraries and JRE features depend on this being non-null even when a
    SecurityManager is not is use.
---
 java/org/apache/catalina/WebResource.java          | 15 ++++++-----
 .../catalina/loader/WebappClassLoaderBase.java     | 12 +++++----
 .../webresources/AbstractArchiveResource.java      | 30 +++++++++++++++++++---
 .../AbstractSingleArchiveResource.java             | 10 +++++---
 .../catalina/webresources/CachedResource.java      |  5 ++++
 .../catalina/webresources/EmptyResource.java       |  5 ++++
 .../apache/catalina/webresources/FileResource.java |  9 +++++++
 .../apache/catalina/webresources/JarResource.java  |  2 +-
 .../catalina/webresources/JarResourceRoot.java     | 12 +++++++++
 .../catalina/webresources/JarWarResource.java      |  2 +-
 .../apache/catalina/webresources/WarResource.java  |  2 +-
 webapps/docs/changelog.xml                         |  6 +++++
 12 files changed, 88 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/catalina/WebResource.java 
b/java/org/apache/catalina/WebResource.java
index 5ae97d552f..9b73613540 100644
--- a/java/org/apache/catalina/WebResource.java
+++ b/java/org/apache/catalina/WebResource.java
@@ -138,15 +138,18 @@ public interface WebResource {
     URL getURL();
 
     /**
+     * Returns the code base for this resource.
+     * <p>
+     * The expectation is that this will be deprecated and then removed once 
the SecurityManager has been fully removed
+     * from the JRE and it has been confirmed that the JRE no longer depends 
on code base.
+     *
      * @return the code base for this resource that will be used when looking 
up the assigned permissions for the code
      *             base in the security policy file when running under a 
security manager.
-     *
-     * @deprecated Unused. Will be removed in Tomcat 12 onwards.
      */
-    @Deprecated
-    default URL getCodeBase() {
-        return null;
-    }
+    URL getCodeBase();
+    //default URL getCodeBase() {
+    //    return null;
+    //}
 
     /**
      * @return a reference to the WebResourceRoot of which this WebResource is 
a part.
diff --git a/java/org/apache/catalina/loader/WebappClassLoaderBase.java 
b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
index 2a0776dab2..41ec44e6c2 100644
--- a/java/org/apache/catalina/loader/WebappClassLoaderBase.java
+++ b/java/org/apache/catalina/loader/WebappClassLoaderBase.java
@@ -358,9 +358,9 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
     private volatile LifecycleState state = LifecycleState.NEW;
 
     /*
-     * Class resources are not cached since they are loaded on first use and 
the resource is then no longer required.
-     * It does help, however, to cache classes that are not found as in some 
scenarios the same class will be searched
-     * for many times and the greater the number of JARs/classes, the longer 
that lookup will take.
+     * Class resources are not cached since they are loaded on first use and 
the resource is then no longer required. It
+     * does help, however, to cache classes that are not found as in some 
scenarios the same class will be searched for
+     * many times and the greater the number of JARs/classes, the longer that 
lookup will take.
      */
     private final ConcurrentLruCache<String> notFoundClassResources = new 
ConcurrentLruCache<>(1000);
 
@@ -2095,6 +2095,7 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
                 return null;
             }
             Manifest manifest = resource.getManifest();
+            URL codeBase = resource.getCodeBase();
             Certificate[] certificates = resource.getCertificates();
 
             if (transformers.size() > 0) {
@@ -2136,7 +2137,7 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
                         if (manifest == null) {
                             definePackage(packageName, null, null, null, null, 
null, null, null);
                         } else {
-                            definePackage(packageName, manifest, null);
+                            definePackage(packageName, manifest, codeBase);
                         }
                     } catch (IllegalArgumentException e) {
                         // Ignore: normal error due to dual definition of 
package
@@ -2146,7 +2147,8 @@ public abstract class WebappClassLoaderBase extends 
URLClassLoader
             }
 
             try {
-                clazz = defineClass(name, binaryContent, 0, 
binaryContent.length, new CodeSource(null, certificates));
+                clazz = defineClass(name, binaryContent, 0, 
binaryContent.length,
+                        new CodeSource(codeBase, certificates));
             } catch (UnsupportedClassVersionError ucve) {
                 throw new UnsupportedClassVersionError(
                         ucve.getLocalizedMessage() + " " + 
sm.getString("webappClassLoader.wrongVersion", name));
diff --git a/java/org/apache/catalina/webresources/AbstractArchiveResource.java 
b/java/org/apache/catalina/webresources/AbstractArchiveResource.java
index c6b45631b4..657fd7522d 100644
--- a/java/org/apache/catalina/webresources/AbstractArchiveResource.java
+++ b/java/org/apache/catalina/webresources/AbstractArchiveResource.java
@@ -35,23 +35,33 @@ public abstract class AbstractArchiveResource extends 
AbstractResource {
     private final AbstractArchiveResourceSet archiveResourceSet;
     private final String baseUrl;
     private final JarEntry resource;
+    private final String codeBaseUrl;
     private final String name;
     private boolean readCerts = false;
     private Certificate[] certificates;
 
-
+    /*
+     * Deprecated even though this is the "new" constructor as code needs to 
call the old constructor for now.
+     */
     @Deprecated
     protected AbstractArchiveResource(AbstractArchiveResourceSet 
archiveResourceSet, String webAppPath, String baseUrl,
-            JarEntry jarEntry, @SuppressWarnings("unused") String codeBaseUrl) 
{
-        this(archiveResourceSet, webAppPath, baseUrl, jarEntry);
+            JarEntry jarEntry) {
+        this(archiveResourceSet, webAppPath, baseUrl, jarEntry, null);
     }
 
+    /*
+     * The expectation is that this will be deprecated and then removed once 
the SecurityManager has been fully removed
+     * from the JRE and it has been confirmed that the JRE no longer depends 
on code base.
+     *
+     * See https://bz.apache.org/bugzilla/show_bug.cgi?id=69426
+     */
     protected AbstractArchiveResource(AbstractArchiveResourceSet 
archiveResourceSet, String webAppPath, String baseUrl,
-            JarEntry jarEntry) {
+            JarEntry jarEntry, String codeBaseUrl) {
         super(archiveResourceSet.getRoot(), webAppPath);
         this.archiveResourceSet = archiveResourceSet;
         this.baseUrl = baseUrl;
         this.resource = jarEntry;
+        this.codeBaseUrl = codeBaseUrl;
 
         String resourceName = resource.getName();
         if (resourceName.charAt(resourceName.length() - 1) == '/') {
@@ -157,6 +167,18 @@ public abstract class AbstractArchiveResource extends 
AbstractResource {
         }
     }
 
+    @Override
+    public URL getCodeBase() {
+        try {
+            return new URI(codeBaseUrl).toURL();
+        } catch (MalformedURLException | URISyntaxException e) {
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(sm.getString("fileResource.getUrlFail", 
codeBaseUrl), e);
+            }
+            return null;
+        }
+    }
+
     @Override
     public final byte[] getContent() {
         long len = getContentLength();
diff --git 
a/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java 
b/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java
index e6cafcd228..cb45aa668b 100644
--- a/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java
+++ b/java/org/apache/catalina/webresources/AbstractSingleArchiveResource.java
@@ -23,13 +23,15 @@ import java.util.jar.JarFile;
 
 public abstract class AbstractSingleArchiveResource extends 
AbstractArchiveResource {
 
-
-    @Deprecated
     protected AbstractSingleArchiveResource(AbstractArchiveResourceSet 
archiveResourceSet, String webAppPath,
-            String baseUrl, JarEntry jarEntry, @SuppressWarnings("unused") 
String codeBaseUrl) {
-        this(archiveResourceSet, webAppPath, baseUrl, jarEntry);
+            String baseUrl, JarEntry jarEntry, String codeBaseUrl) {
+        super(archiveResourceSet, webAppPath, baseUrl, jarEntry, codeBaseUrl);
     }
 
+    /*
+     * Deprecated even though this is the "new" constructor as code needs to 
call the old constructor for now.
+     */
+    @Deprecated
     protected AbstractSingleArchiveResource(AbstractArchiveResourceSet 
archiveResourceSet, String webAppPath,
             String baseUrl, JarEntry jarEntry) {
         super(archiveResourceSet, webAppPath, baseUrl, jarEntry);
diff --git a/java/org/apache/catalina/webresources/CachedResource.java 
b/java/org/apache/catalina/webresources/CachedResource.java
index 28c0de5bb0..ef9236fc1a 100644
--- a/java/org/apache/catalina/webresources/CachedResource.java
+++ b/java/org/apache/catalina/webresources/CachedResource.java
@@ -368,6 +368,11 @@ public class CachedResource implements WebResource {
         }
     }
 
+    @Override
+    public URL getCodeBase() {
+        return webResource.getCodeBase();
+    }
+
     @Override
     public Certificate[] getCertificates() {
         return webResource.getCertificates();
diff --git a/java/org/apache/catalina/webresources/EmptyResource.java 
b/java/org/apache/catalina/webresources/EmptyResource.java
index 99393fe1f5..7b35876bc1 100644
--- a/java/org/apache/catalina/webresources/EmptyResource.java
+++ b/java/org/apache/catalina/webresources/EmptyResource.java
@@ -150,6 +150,11 @@ public class EmptyResource implements WebResource {
         return null;
     }
 
+    @Override
+    public URL getCodeBase() {
+        return null;
+    }
+
     @Override
     public Certificate[] getCertificates() {
         return null;
diff --git a/java/org/apache/catalina/webresources/FileResource.java 
b/java/org/apache/catalina/webresources/FileResource.java
index f109893d9e..354022f909 100644
--- a/java/org/apache/catalina/webresources/FileResource.java
+++ b/java/org/apache/catalina/webresources/FileResource.java
@@ -289,6 +289,15 @@ public class FileResource extends AbstractResource {
         }
     }
 
+    @Override
+    public URL getCodeBase() {
+        if (getWebappPath().startsWith("/WEB-INF/classes/") && 
name.endsWith(".class")) {
+            return 
getWebResourceRoot().getResource("/WEB-INF/classes/").getURL();
+        } else {
+            return getURL();
+        }
+    }
+
     @Override
     public Certificate[] getCertificates() {
         return null;
diff --git a/java/org/apache/catalina/webresources/JarResource.java 
b/java/org/apache/catalina/webresources/JarResource.java
index e7976702d4..56199304ec 100644
--- a/java/org/apache/catalina/webresources/JarResource.java
+++ b/java/org/apache/catalina/webresources/JarResource.java
@@ -31,7 +31,7 @@ public class JarResource extends 
AbstractSingleArchiveResource {
 
     public JarResource(AbstractArchiveResourceSet archiveResourceSet, String 
webAppPath, String baseUrl,
             JarEntry jarEntry) {
-        super(archiveResourceSet, webAppPath, "jar:" + baseUrl + "!/", 
jarEntry);
+        super(archiveResourceSet, webAppPath, "jar:" + baseUrl + "!/", 
jarEntry, baseUrl);
     }
 
 
diff --git a/java/org/apache/catalina/webresources/JarResourceRoot.java 
b/java/org/apache/catalina/webresources/JarResourceRoot.java
index 7432515a95..cdd6e1b1fa 100644
--- a/java/org/apache/catalina/webresources/JarResourceRoot.java
+++ b/java/org/apache/catalina/webresources/JarResourceRoot.java
@@ -133,6 +133,18 @@ public class JarResourceRoot extends AbstractResource {
         }
     }
 
+    @Override
+    public URL getCodeBase() {
+        try {
+            return new URI(baseUrl).toURL();
+        } catch (MalformedURLException | URISyntaxException e) {
+            if (getLog().isDebugEnabled()) {
+                getLog().debug(sm.getString("fileResource.getUrlFail", 
baseUrl), e);
+            }
+            return null;
+        }
+    }
+
     @Override
     protected Log getLog() {
         return log;
diff --git a/java/org/apache/catalina/webresources/JarWarResource.java 
b/java/org/apache/catalina/webresources/JarWarResource.java
index 9be3bb986c..dcefd22213 100644
--- a/java/org/apache/catalina/webresources/JarWarResource.java
+++ b/java/org/apache/catalina/webresources/JarWarResource.java
@@ -39,7 +39,7 @@ public class JarWarResource extends AbstractArchiveResource {
             JarEntry jarEntry, String archivePath) {
 
         super(archiveResourceSet, webAppPath, "jar:war:" + baseUrl + 
UriUtil.getWarSeparator() + archivePath + "!/",
-                jarEntry);
+                jarEntry, "war:" + baseUrl + UriUtil.getWarSeparator() + 
archivePath);
         this.archivePath = archivePath;
     }
 
diff --git a/java/org/apache/catalina/webresources/WarResource.java 
b/java/org/apache/catalina/webresources/WarResource.java
index e18f048386..4672a3923f 100644
--- a/java/org/apache/catalina/webresources/WarResource.java
+++ b/java/org/apache/catalina/webresources/WarResource.java
@@ -32,7 +32,7 @@ public class WarResource extends 
AbstractSingleArchiveResource {
 
     public WarResource(AbstractArchiveResourceSet archiveResourceSet, String 
webAppPath, String baseUrl,
             JarEntry jarEntry) {
-        super(archiveResourceSet, webAppPath, "war:" + baseUrl + 
UriUtil.getWarSeparator(), jarEntry);
+        super(archiveResourceSet, webAppPath, "war:" + baseUrl + 
UriUtil.getWarSeparator(), jarEntry, baseUrl);
     }
 
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 8f83d69e64..b642d85e2d 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -235,6 +235,12 @@
         levels of nested includes. Based on a patch provided by John
         Engebretson. (markt)
       </fix>
+      <fix>
+        <bug>69426</bug>: Restore providing a value (rather than null) for
+        <code>Class.getProtectionDomain().getCodeSource().getLocation()</code>
+        as a number of libraries and JRE features depend on this being non-null
+        even when a SecurityManager is not is use. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


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

Reply via email to