From 671aee8ce3ae9f5e6a5b106c7583b79d4f275b82 Mon Sep 17 00:00:00 2001 From: Dimitris Soumis Date: Tue, 31 Mar 2026 14:46:45 +0300 Subject: [PATCH] Add tests for StandardJarScanner scanManifest option to verify Class-Path manifest entries are followed when enabled and ignored when disabled. --- .../util/scan/TestStandardJarScanner.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/test/org/apache/tomcat/util/scan/TestStandardJarScanner.java b/test/org/apache/tomcat/util/scan/TestStandardJarScanner.java index cabfebc3d3f3..853bde141fec 100644 --- a/test/org/apache/tomcat/util/scan/TestStandardJarScanner.java +++ b/test/org/apache/tomcat/util/scan/TestStandardJarScanner.java @@ -17,14 +17,20 @@ package org.apache.tomcat.util.scan; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; +import java.util.Deque; import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import org.junit.Assert; import org.junit.Test; import org.apache.tomcat.Jar; @@ -57,6 +63,57 @@ public ClassLoader getClassLoader() { scanner.scan(JarScanType.PLUGGABILITY, context, callback); } + @Test + public void testScanManifestDefault() throws Exception { + Assert.assertTrue("Referenced JAR from manifest Class-Path should be scanned", + doTestScanManifest(true)); + } + + @Test + public void testScanManifestDisabled() throws Exception { + Assert.assertFalse("Referenced JAR from manifest Class-Path should not be scanned", + doTestScanManifest(false)); + } + + private boolean doTestScanManifest(boolean scanManifest) throws Exception { + File referencedJar = new File(System.getProperty("java.io.tmpdir"), "referenced.jar"); + referencedJar.deleteOnExit(); + JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(referencedJar), new Manifest()); + jarOutputStream.close(); + + File testJar = new File(System.getProperty("java.io.tmpdir"), "manifest-test.jar"); + testJar.deleteOnExit(); + + Manifest manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + manifest.getMainAttributes().put(Attributes.Name.CLASS_PATH, "referenced.jar"); + + jarOutputStream = new JarOutputStream(new FileOutputStream(testJar), manifest); + jarOutputStream.close(); + + StandardJarScanner scanner = new StandardJarScanner() { + @Override + protected void addClassPath(Deque classPathUrlsToProcess) { + super.addClassPath(classPathUrlsToProcess); + try { + classPathUrlsToProcess.add(testJar.toURI().toURL()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + }; + scanner.setScanManifest(scanManifest); + + LoggingCallback callback = new LoggingCallback(); + scanner.scan(JarScanType.PLUGGABILITY, new TesterServletContext(), callback); + + for (String cb : callback.callbacks) { + if (cb.contains("referenced.jar")) { + return true; + } + } + return false; + } private static class LoggingCallback implements JarScannerCallback {