[ https://issues.apache.org/jira/browse/GERONIMO-6534?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
xiezhi updated GERONIMO-6534: ----------------------------- Description: The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I think it has not been well thought over. The error or exception which raised in scanning entry files should not be past. I actually met a problem when failed to get uri from a tld file because of some validation reason. There is no exception or any other error message. It took a lot of time to find the root cause in debug model. I think it is not a good practice to ignore the exceptions here. /** * Scans the given JarURLConnection for TLD files located in META-INF * (or a subdirectory of it), adding an implicit map entry to the taglib * map for any TLD that has a <uri> element. * * @param conn The JarURLConnection to the JAR file to scan * @param ignore true if any exceptions raised when processing the given * JAR should be ignored, false otherwise */ private void scanJar(JarURLConnection conn, boolean ignore) throws JasperException { JarFile jarFile = null; String resourcePath = conn.getJarFileURL().toString(); try { if (redeployMode) { conn.setUseCaches(false); } jarFile = conn.getJarFile(); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); String name = entry.getName(); if (!name.startsWith("META-INF/")) continue; if (!name.endsWith(".tld")) continue; InputStream stream = jarFile.getInputStream(entry); try { String uri = getUriFromTld(resourcePath, stream); // Add implicit map entry only if its uri is not already // present in the map if (uri != null && mappings.get(uri) == null) { mappings.put(uri, new String[]{ resourcePath, name }); } } finally { if (stream != null) { try { stream.close(); } catch (Throwable t) { // do nothing } } } } } catch (Exception ex) { if (!redeployMode) { // if not in redeploy mode, close the jar in case of an error if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { // ignore } } } if (!ignore) { throw new JasperException(ex); } } finally { if (redeployMode) { // if in redeploy mode, always close the jar if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { // ignore } } } } } ------------------------------------------------------------------------------------------ /* * Scans all JARs accessible to the webapp's classloader and its * parent classloaders for TLDs. * * The list of JARs always includes the JARs under WEB-INF/lib, as well as * all shared JARs in the classloader delegation chain of the webapp's * classloader. * * Considering JARs in the classloader delegation chain constitutes a * Tomcat-specific extension to the TLD search * order defined in the JSP spec. It allows tag libraries packaged as JAR * files to be shared by web applications by simply dropping them in a * location that all web applications have access to (e.g., * <CATALINA_HOME>/common/lib). * * The set of shared JARs to be scanned for TLDs is narrowed down by * the <tt>noTldJars</tt> class variable, which contains the names of JARs * that are known not to contain any TLDs. */ private void scanJars() throws Exception { ClassLoader webappLoader = Thread.currentThread().getContextClassLoader(); ClassLoader loader = webappLoader; while (loader != null) { if (loader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) loader).getURLs(); for (int i=0; i<urls.length; i++) { URLConnection conn = urls[i].openConnection(); if (conn instanceof JarURLConnection) { if (needScanJar(loader, webappLoader, ((JarURLConnection) conn).getJarFile().getName())) { scanJar((JarURLConnection) conn, true); } } else { String urlStr = urls[i].toString(); if (urlStr.startsWith(FILE_PROTOCOL) && urlStr.endsWith(JAR_FILE_SUFFIX) && needScanJar(loader, webappLoader, urlStr)) { URL jarURL = new URL("jar:" + urlStr + "!/"); scanJar((JarURLConnection) jarURL.openConnection(), true); } } } } loader = loader.getParent(); } } was: The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I think it has not been well thought out. The error or exception which raised in scanning entry files should not be past. I actually met a problem when failed to get uri from a tld file because of some validation reason. There is no exception or any other error message. It took a lot of time to find the root cause in debug model. I think it is not a good practice to ignore the exceptions here. /** * Scans the given JarURLConnection for TLD files located in META-INF * (or a subdirectory of it), adding an implicit map entry to the taglib * map for any TLD that has a <uri> element. * * @param conn The JarURLConnection to the JAR file to scan * @param ignore true if any exceptions raised when processing the given * JAR should be ignored, false otherwise */ private void scanJar(JarURLConnection conn, boolean ignore) throws JasperException { JarFile jarFile = null; String resourcePath = conn.getJarFileURL().toString(); try { if (redeployMode) { conn.setUseCaches(false); } jarFile = conn.getJarFile(); Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = (JarEntry) entries.nextElement(); String name = entry.getName(); if (!name.startsWith("META-INF/")) continue; if (!name.endsWith(".tld")) continue; InputStream stream = jarFile.getInputStream(entry); try { String uri = getUriFromTld(resourcePath, stream); // Add implicit map entry only if its uri is not already // present in the map if (uri != null && mappings.get(uri) == null) { mappings.put(uri, new String[]{ resourcePath, name }); } } finally { if (stream != null) { try { stream.close(); } catch (Throwable t) { // do nothing } } } } } catch (Exception ex) { if (!redeployMode) { // if not in redeploy mode, close the jar in case of an error if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { // ignore } } } if (!ignore) { throw new JasperException(ex); } } finally { if (redeployMode) { // if in redeploy mode, always close the jar if (jarFile != null) { try { jarFile.close(); } catch (Throwable t) { // ignore } } } } } ------------------------------------------------------------------------------------------ /* * Scans all JARs accessible to the webapp's classloader and its * parent classloaders for TLDs. * * The list of JARs always includes the JARs under WEB-INF/lib, as well as * all shared JARs in the classloader delegation chain of the webapp's * classloader. * * Considering JARs in the classloader delegation chain constitutes a * Tomcat-specific extension to the TLD search * order defined in the JSP spec. It allows tag libraries packaged as JAR * files to be shared by web applications by simply dropping them in a * location that all web applications have access to (e.g., * <CATALINA_HOME>/common/lib). * * The set of shared JARs to be scanned for TLDs is narrowed down by * the <tt>noTldJars</tt> class variable, which contains the names of JARs * that are known not to contain any TLDs. */ private void scanJars() throws Exception { ClassLoader webappLoader = Thread.currentThread().getContextClassLoader(); ClassLoader loader = webappLoader; while (loader != null) { if (loader instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) loader).getURLs(); for (int i=0; i<urls.length; i++) { URLConnection conn = urls[i].openConnection(); if (conn instanceof JarURLConnection) { if (needScanJar(loader, webappLoader, ((JarURLConnection) conn).getJarFile().getName())) { scanJar((JarURLConnection) conn, true); } } else { String urlStr = urls[i].toString(); if (urlStr.startsWith(FILE_PROTOCOL) && urlStr.endsWith(JAR_FILE_SUFFIX) && needScanJar(loader, webappLoader, urlStr)) { URL jarURL = new URL("jar:" + urlStr + "!/"); scanJar((JarURLConnection) jarURL.openConnection(), true); } } } } loader = loader.getParent(); } } > A potential coding flaw makes scan jar fail without any error or exception > -------------------------------------------------------------------------- > > Key: GERONIMO-6534 > URL: https://issues.apache.org/jira/browse/GERONIMO-6534 > Project: Geronimo > Issue Type: Improvement > Security Level: public(Regular issues) > Components: Tomcat > Affects Versions: 2.1.8, 2.2.1 > Reporter: xiezhi > Priority: Minor > Attachments: GERONIMO-6534.patch > > > The method ScanJar and ScanJars are from GeronimoTldLocationsCache.java. I > think it has not been well thought over. The error or exception which raised > in scanning entry files should not be past. I actually met a problem when > failed to get uri from a tld file because of some validation reason. There is > no exception or any other error message. It took a lot of time to find the > root cause in debug model. > I think it is not a good practice to ignore the exceptions here. > /** > * Scans the given JarURLConnection for TLD files located in META-INF > * (or a subdirectory of it), adding an implicit map entry to the taglib > * map for any TLD that has a <uri> element. > * > * @param conn The JarURLConnection to the JAR file to scan > * @param ignore true if any exceptions raised when processing the given > * JAR should be ignored, false otherwise > */ > private void scanJar(JarURLConnection conn, boolean ignore) > throws JasperException { > JarFile jarFile = null; > String resourcePath = conn.getJarFileURL().toString(); > try { > if (redeployMode) { > conn.setUseCaches(false); > } > jarFile = conn.getJarFile(); > Enumeration entries = jarFile.entries(); > while (entries.hasMoreElements()) { > JarEntry entry = (JarEntry) entries.nextElement(); > String name = entry.getName(); > if (!name.startsWith("META-INF/")) continue; > if (!name.endsWith(".tld")) continue; > InputStream stream = jarFile.getInputStream(entry); > try { > String uri = getUriFromTld(resourcePath, stream); > // Add implicit map entry only if its uri is not already > // present in the map > if (uri != null && mappings.get(uri) == null) { > mappings.put(uri, new String[]{ resourcePath, name }); > } > } finally { > if (stream != null) { > try { > stream.close(); > } catch (Throwable t) { > // do nothing > } > } > } > } > } catch (Exception ex) { > if (!redeployMode) { > // if not in redeploy mode, close the jar in case of an error > if (jarFile != null) { > try { > jarFile.close(); > } catch (Throwable t) { > // ignore > } > } > } > if (!ignore) { > throw new JasperException(ex); > } > } finally { > if (redeployMode) { > // if in redeploy mode, always close the jar > if (jarFile != null) { > try { > jarFile.close(); > } catch (Throwable t) { > // ignore > } > } > } > } > } > > ------------------------------------------------------------------------------------------ > > /* > * Scans all JARs accessible to the webapp's classloader and its > * parent classloaders for TLDs. > * > * The list of JARs always includes the JARs under WEB-INF/lib, as well as > * all shared JARs in the classloader delegation chain of the webapp's > * classloader. > * > * Considering JARs in the classloader delegation chain constitutes a > * Tomcat-specific extension to the TLD search > * order defined in the JSP spec. It allows tag libraries packaged as JAR > * files to be shared by web applications by simply dropping them in a > * location that all web applications have access to (e.g., > * <CATALINA_HOME>/common/lib). > * > * The set of shared JARs to be scanned for TLDs is narrowed down by > * the <tt>noTldJars</tt> class variable, which contains the names of JARs > * that are known not to contain any TLDs. > */ > private void scanJars() throws Exception { > ClassLoader webappLoader > = Thread.currentThread().getContextClassLoader(); > ClassLoader loader = webappLoader; > while (loader != null) { > if (loader instanceof URLClassLoader) { > URL[] urls = ((URLClassLoader) loader).getURLs(); > for (int i=0; i<urls.length; i++) { > URLConnection conn = urls[i].openConnection(); > if (conn instanceof JarURLConnection) { > if (needScanJar(loader, webappLoader, > ((JarURLConnection) > conn).getJarFile().getName())) { > scanJar((JarURLConnection) conn, true); > } > } else { > String urlStr = urls[i].toString(); > if (urlStr.startsWith(FILE_PROTOCOL) > && urlStr.endsWith(JAR_FILE_SUFFIX) > && needScanJar(loader, webappLoader, urlStr)) > { > URL jarURL = new URL("jar:" + urlStr + "!/"); > scanJar((JarURLConnection) > jarURL.openConnection(), > true); > } > } > } > } > loader = loader.getParent(); > } > } -- This message was sent by Atlassian JIRA (v6.3.4#6332)