Author: markt Date: Fri Mar 5 13:34:31 2010 New Revision: 919406 URL: http://svn.apache.org/viewvc?rev=919406&view=rev Log: * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48109 Extend try/finally to ensure InputStream is closed
Modified: tomcat/tc5.5.x/trunk/STATUS.txt tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml Modified: tomcat/tc5.5.x/trunk/STATUS.txt URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/STATUS.txt?rev=919406&r1=919405&r2=919406&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/STATUS.txt (original) +++ tomcat/tc5.5.x/trunk/STATUS.txt Fri Mar 5 13:34:31 2010 @@ -77,10 +77,3 @@ https://issues.apache.org/bugzilla/attachment.cgi?id=24918 +1: kkolinko, markt -1: - -* Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=48109 - Extend try/finally to ensure InputStream is closed - Patch by markt - http://svn.apache.org/viewvc?rev=907819&view=rev - +1: kkolinko, rjung, markt - -1: Modified: tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java?rev=919406&r1=919405&r2=919406&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java (original) +++ tomcat/tc5.5.x/trunk/container/catalina/src/share/org/apache/catalina/loader/WebappClassLoader.java Fri Mar 5 13:34:31 2010 @@ -152,6 +152,7 @@ } + protected final class PrivilegedGetClassLoader implements PrivilegedAction { @@ -166,6 +167,8 @@ } } + + // ------------------------------------------------------- Static Variables @@ -367,7 +370,6 @@ protected File loaderDir = null; protected String canonicalLoaderDir = null; - /** * The PermissionCollection for each CodeSource for a web * application context. @@ -571,7 +573,6 @@ canonicalLoaderDir = null; } } - } /** @@ -970,7 +971,7 @@ // Return the class we have located if (log.isTraceEnabled()) log.debug(" Returning class " + clazz); - + if ((log.isTraceEnabled()) && (clazz != null)) { ClassLoader cl; if (securityManager != null){ @@ -1574,7 +1575,7 @@ clearReferences(); started = false; - + int length = files.length; for (int i = 0; i < length; i++) { files[i] = null; @@ -1919,13 +1920,11 @@ int pos = name.lastIndexOf('.'); if (pos != -1) packageName = name.substring(0, pos); - + Package pkg = null; - + if (packageName != null) { - pkg = getPackage(packageName); - // Define the package (if null) if (pkg == null) { if (entry.manifest == null) { @@ -1937,9 +1936,9 @@ } } } - - if (securityManager != null) { + if (securityManager != null) { + // Checking sealing if (pkg != null) { boolean sealCheck = true; @@ -2097,147 +2096,150 @@ synchronized (jarFiles) { - if (!openJARs()) { - return null; - } - for (i = 0; (entry == null) && (i < jarFilesLength); i++) { - - jarEntry = jarFiles[i].getJarEntry(path); - - if (jarEntry != null) { - - entry = new ResourceEntry(); - try { - entry.codeBase = getURL(jarRealFiles[i], false); - String jarFakeUrl = getURI(jarRealFiles[i]).toString(); - jarFakeUrl = "jar:" + jarFakeUrl + "!/" + path; - entry.source = new URL(jarFakeUrl); - entry.lastModified = jarRealFiles[i].lastModified(); - } catch (MalformedURLException e) { - return null; - } - contentLength = (int) jarEntry.getSize(); - try { - entry.manifest = jarFiles[i].getManifest(); - binaryStream = jarFiles[i].getInputStream(jarEntry); - } catch (IOException e) { - return null; - } - - // Extract resources contained in JAR to the workdir - if (antiJARLocking && !(path.endsWith(".class"))) { - byte[] buf = new byte[1024]; - File resourceFile = new File - (loaderDir, jarEntry.getName()); - if (!resourceFile.exists()) { - Enumeration entries = jarFiles[i].entries(); - while (entries.hasMoreElements()) { - JarEntry jarEntry2 = - (JarEntry) entries.nextElement(); - if (!(jarEntry2.isDirectory()) - && (!jarEntry2.getName().endsWith - (".class"))) { - resourceFile = new File - (loaderDir, jarEntry2.getName()); - try { - if (!resourceFile.getCanonicalPath().startsWith( - canonicalLoaderDir)) { - throw new IllegalArgumentException( - sm.getString("webappClassLoader.illegalJarPath", - jarEntry2.getName())); - } - } catch (IOException ioe) { - throw new IllegalArgumentException( - sm.getString("webappClassLoader.validationErrorJarPath", - jarEntry2.getName()), ioe); - } - resourceFile.getParentFile().mkdirs(); - FileOutputStream os = null; - InputStream is = null; - try { - is = jarFiles[i].getInputStream - (jarEntry2); - os = new FileOutputStream - (resourceFile); - while (true) { - int n = is.read(buf); - if (n <= 0) { - break; - } - os.write(buf, 0, n); - } - } catch (IOException e) { - // Ignore - } finally { + try { + if (!openJARs()) { + return null; + } + for (i = 0; (entry == null) && (i < jarFilesLength); i++) { + + jarEntry = jarFiles[i].getJarEntry(path); + + if (jarEntry != null) { + + entry = new ResourceEntry(); + try { + entry.codeBase = getURL(jarRealFiles[i], false); + String jarFakeUrl = getURI(jarRealFiles[i]).toString(); + jarFakeUrl = "jar:" + jarFakeUrl + "!/" + path; + entry.source = new URL(jarFakeUrl); + entry.lastModified = jarRealFiles[i].lastModified(); + } catch (MalformedURLException e) { + return null; + } + contentLength = (int) jarEntry.getSize(); + try { + entry.manifest = jarFiles[i].getManifest(); + binaryStream = jarFiles[i].getInputStream(jarEntry); + } catch (IOException e) { + return null; + } + + // Extract resources contained in JAR to the workdir + if (antiJARLocking && !(path.endsWith(".class"))) { + byte[] buf = new byte[1024]; + File resourceFile = new File + (loaderDir, jarEntry.getName()); + if (!resourceFile.exists()) { + Enumeration entries = jarFiles[i].entries(); + while (entries.hasMoreElements()) { + JarEntry jarEntry2 = + (JarEntry) entries.nextElement(); + if (!(jarEntry2.isDirectory()) + && (!jarEntry2.getName().endsWith + (".class"))) { + resourceFile = new File + (loaderDir, jarEntry2.getName()); try { - if (is != null) { - is.close(); + if (!resourceFile.getCanonicalPath().startsWith( + canonicalLoaderDir)) { + throw new IllegalArgumentException( + sm.getString("webappClassLoader.illegalJarPath", + jarEntry2.getName())); } - } catch (IOException e) { - } + } catch (IOException ioe) { + throw new IllegalArgumentException( + sm.getString("webappClassLoader.validationErrorJarPath", + jarEntry2.getName()), ioe); + } + resourceFile.getParentFile().mkdirs(); + FileOutputStream os = null; + InputStream is = null; try { - if (os != null) { - os.close(); + is = jarFiles[i].getInputStream + (jarEntry2); + os = new FileOutputStream + (resourceFile); + while (true) { + int n = is.read(buf); + if (n <= 0) { + break; + } + os.write(buf, 0, n); } } catch (IOException e) { + // Ignore + } finally { + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + } + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + } } } } } } + } - - } - - } - - if (entry == null) { - synchronized (notFoundResources) { - notFoundResources.put(name, name); + } - return null; - } - - if (binaryStream != null) { - - byte[] binaryContent = new byte[contentLength]; - - int pos = 0; - try { - - while (true) { - int n = binaryStream.read(binaryContent, pos, - binaryContent.length - pos); - if (n <= 0) - break; - pos += n; + + if (entry == null) { + synchronized (notFoundResources) { + notFoundResources.put(name, name); } - } catch (IOException e) { - log.error(sm.getString("webappClassLoader.readError", name), e); return null; - } finally { - try { - binaryStream.close(); - } catch (IOException e) {} } - if (fileNeedConvert) { - String str = new String(binaryContent,0,pos); + + if (binaryStream != null) { + + byte[] binaryContent = new byte[contentLength]; + + int pos = 0; try { - binaryContent = str.getBytes("UTF-8"); - } catch (Exception e) { + + while (true) { + int n = binaryStream.read(binaryContent, pos, + binaryContent.length - pos); + if (n <= 0) + break; + pos += n; + } + } catch (IOException e) { + log.error(sm.getString("webappClassLoader.readError", name), e); return null; } + if (fileNeedConvert) { + String str = new String(binaryContent,0,pos); + try { + binaryContent = str.getBytes("UTF-8"); + } catch (Exception e) { + return null; + } + } + entry.binaryContent = binaryContent; + + // The certificates are only available after the JarEntry + // associated input stream has been fully read + if (jarEntry != null) { + entry.certificates = jarEntry.getCertificates(); + } + } - entry.binaryContent = binaryContent; - - // The certificates are only available after the JarEntry - // associated input stream has been fully read - if (jarEntry != null) { - entry.certificates = jarEntry.getCertificates(); + } finally { + if (binaryStream != null) { + try { + binaryStream.close(); + } catch (IOException e) { /* Ignore */} } - } - } // Add the entry in the local resource repository Modified: tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml?rev=919406&r1=919405&r2=919406&view=diff ============================================================================== --- tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml (original) +++ tomcat/tc5.5.x/trunk/container/webapps/docs/changelog.xml Fri Mar 5 13:34:31 2010 @@ -202,6 +202,10 @@ <bug>47987</bug>: Limit size of not found resources cache. (markt) </fix> <fix> + <bug>48109</bug>: Ensure InputStream is closed in WebappClassLoader + on error conditions. (markt) + </fix> + <fix> <bug>48311</bug>: APR should not be initialised if the APR life-cycle listener is not enabled. (markt) </fix> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org