Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/FileUtils.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/FileUtils.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/FileUtils.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/FileUtils.java Wed Dec 6 10:55:42 2017 @@ -38,6 +38,10 @@ import java.io.IOException; * <li>calculating a checksum * </ul> * <p> + * Note that a specific charset should be specified whenever possible. + * Relying on the platform default means that the code is Locale-dependent. + * Only use the default if the files are known to always use the platform default. + * <p> * Origin of code: Excalibur, Alexandria, Commons-Utils */ public class FileUtils { @@ -53,10 +57,11 @@ public class FileUtils { /** * Deletes a directory recursively. * - * @param directory directory to delete - * @throws IOException in case deletion is unsuccessful + * @param directory directory to delete + * @throws IOException in case deletion is unsuccessful + * @throws IllegalArgumentException if {@code directory} does not exist or is not a directory */ - public static void deleteDirectory(File directory) throws IOException { + public static void deleteDirectory(final File directory) throws IOException { if (!directory.exists()) { return; } @@ -66,8 +71,8 @@ public class FileUtils { } if (!directory.delete()) { - String message = - "Unable to delete directory " + directory + "."; + final String message = + "Unable to delete directory " + directory + "."; throw new IOException(message); } } @@ -76,20 +81,21 @@ public class FileUtils { * Cleans a directory without deleting it. * * @param directory directory to clean - * @throws IOException in case cleaning is unsuccessful + * @throws IOException in case cleaning is unsuccessful + * @throws IllegalArgumentException if {@code directory} does not exist or is not a directory */ - public static void cleanDirectory(File directory) throws IOException { + public static void cleanDirectory(final File directory) throws IOException { if (!directory.exists()) { - String message = directory + " does not exist"; + final String message = directory + " does not exist"; throw new IllegalArgumentException(message); } if (!directory.isDirectory()) { - String message = directory + " is not a directory"; + final String message = directory + " is not a directory"; throw new IllegalArgumentException(message); } - File[] files = directory.listFiles(); + final File[] files = directory.listFiles(); if (files == null) { // null if security restricted throw new IOException("Failed to list contents of " + directory); } @@ -116,25 +122,25 @@ public class FileUtils { * <ul> * <li>A directory to be deleted does not have to be empty.</li> * <li>You get exceptions when a file or directory cannot be deleted. - * (java.io.File methods returns a boolean)</li> + * (java.io.File methods returns a boolean)</li> * </ul> * - * @param file file or directory to delete, must not be {@code null} - * @throws NullPointerException if the directory is {@code null} + * @param file file or directory to delete, must not be {@code null} + * @throws NullPointerException if the directory is {@code null} * @throws FileNotFoundException if the file was not found - * @throws IOException in case deletion is unsuccessful + * @throws IOException in case deletion is unsuccessful */ - public static void forceDelete(File file) throws IOException { + public static void forceDelete(final File file) throws IOException { if (file.isDirectory()) { deleteDirectory(file); } else { - boolean filePresent = file.exists(); + final boolean filePresent = file.exists(); if (!file.delete()) { - if (!filePresent){ + if (!filePresent) { throw new FileNotFoundException("File does not exist: " + file); } - String message = - "Unable to delete file: " + file; + final String message = + "Unable to delete file: " + file; throw new IOException(message); } } @@ -144,11 +150,11 @@ public class FileUtils { * Schedules a file to be deleted when JVM exits. * If file is directory delete it and all sub-directories. * - * @param file file or directory to delete, must not be {@code null} + * @param file file or directory to delete, must not be {@code null} * @throws NullPointerException if the file is {@code null} - * @throws IOException in case deletion is unsuccessful + * @throws IOException in case deletion is unsuccessful */ - public static void forceDeleteOnExit(File file) throws IOException { + public static void forceDeleteOnExit(final File file) throws IOException { if (file.isDirectory()) { deleteDirectoryOnExit(file); } else { @@ -159,11 +165,11 @@ public class FileUtils { /** * Schedules a directory recursively for deletion on JVM exit. * - * @param directory directory to delete, must not be {@code null} + * @param directory directory to delete, must not be {@code null} * @throws NullPointerException if the directory is {@code null} - * @throws IOException in case deletion is unsuccessful + * @throws IOException in case deletion is unsuccessful */ - private static void deleteDirectoryOnExit(File directory) throws IOException { + private static void deleteDirectoryOnExit(final File directory) throws IOException { if (!directory.exists()) { return; } @@ -177,11 +183,11 @@ public class FileUtils { /** * Cleans a directory without deleting it. * - * @param directory directory to clean, must not be {@code null} + * @param directory directory to clean, must not be {@code null} * @throws NullPointerException if the directory is {@code null} - * @throws IOException in case cleaning is unsuccessful + * @throws IOException in case cleaning is unsuccessful */ - private static void cleanDirectoryOnExit(File directory) throws IOException { + private static void cleanDirectoryOnExit(final File directory) throws IOException { if (!directory.exists()) { String message = directory + " does not exist"; throw new IllegalArgumentException(message); @@ -211,6 +217,57 @@ public class FileUtils { } } + /** + * Makes a directory, including any necessary but nonexistent parent + * directories. If a file already exists with specified name but it is + * not a directory then an IOException is thrown. + * If the directory cannot be created (or does not already exist) + * then an IOException is thrown. + * + * @param directory directory to create, must not be {@code null} + * @throws NullPointerException if the directory is {@code null} + * @throws IOException if the directory cannot be created or the file already exists but is not a directory + */ + public static void forceMkdir(final File directory) throws IOException { + if (directory.exists()) { + if (!directory.isDirectory()) { + final String message = + "File " + + directory + + " exists and is " + + "not a directory. Unable to create directory."; + throw new IOException(message); + } + } else { + if (!directory.mkdirs()) { + // Double-check that some other thread or process hasn't made + // the directory in the background + if (!directory.isDirectory()) { + final String message = + "Unable to create directory " + directory; + throw new IOException(message); + } + } + } + } + + /** + * Makes any necessary but nonexistent parent directories for a given File. If the parent directory cannot be + * created then an IOException is thrown. + * + * @param file file with parent to create, must not be {@code null} + * @throws NullPointerException if the file is {@code null} + * @throws IOException if the parent directory cannot be created + * @since 2.5 + */ + public static void forceMkdirParent(final File file) throws IOException { + final File parent = file.getParentFile(); + if (parent == null) { + return; + } + forceMkdir(parent); + } + /** * Determines whether the specified file is a Symbolic Link rather than an actual file.
Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/IOUtils.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/IOUtils.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/IOUtils.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/IOUtils.java Wed Dec 6 10:55:42 2017 @@ -54,7 +54,7 @@ import java.io.OutputStream; * Origin of code: Excalibur. */ public class IOUtils { - // NOTE: This class is focussed on InputStream, OutputStream, Reader and + // NOTE: This class is focused on InputStream, OutputStream, Reader and // Writer. Each method should take at least one of these as a parameter, // or return one of them. @@ -82,7 +82,7 @@ public class IOUtils { * finally blocks. * <p> * Example code: - * + * </p> * <pre> * Closeable closeable = null; * try { @@ -95,9 +95,9 @@ public class IOUtils { * IOUtils.closeQuietly(closeable); * } * </pre> - * + * <p> * Closing all streams: - * + * </p> * <pre> * try { * return IOUtils.copy(inputStream, outputStream); @@ -107,8 +107,7 @@ public class IOUtils { * } * </pre> * - * @param closeable - * the objects to close, may be null or already closed + * @param closeable the objects to close, may be null or already closed * @since 2.0 */ public static void closeQuietly(final Closeable closeable) { @@ -124,7 +123,7 @@ public class IOUtils { // copy from InputStream //----------------------------------------------------------------------- /** - * Copy bytes from an <code>InputStream</code> to an + * Copies bytes from an <code>InputStream</code> to an * <code>OutputStream</code>. * <p> * This method buffers the input internally, so there is no need to use a @@ -135,15 +134,15 @@ public class IOUtils { * number of bytes cannot be returned as an int. For large streams * use the <code>copyLarge(InputStream, OutputStream)</code> method. * - * @param input the <code>InputStream</code> to read from - * @param output the <code>OutputStream</code> to write to + * @param input the <code>InputStream</code> to read from + * @param output the <code>OutputStream</code> to write to * @return the number of bytes copied, or -1 if > Integer.MAX_VALUE * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs + * @throws IOException if an I/O error occurs * @since 1.1 */ - public static int copy(InputStream input, OutputStream output) throws IOException { - long count = copyLarge(input, output); + public static int copy(final InputStream input, final OutputStream output) throws IOException { + final long count = copyLarge(input, output); if (count > Integer.MAX_VALUE) { return -1; } @@ -151,7 +150,7 @@ public class IOUtils { } /** - * Copy bytes from a large (over 2GB) <code>InputStream</code> to an + * Copies bytes from a large (over 2GB) <code>InputStream</code> to an * <code>OutputStream</code>. * <p> * This method buffers the input internally, so there is no need to use a @@ -159,14 +158,14 @@ public class IOUtils { * <p> * The buffer size is given by {@link #DEFAULT_BUFFER_SIZE}. * - * @param input the <code>InputStream</code> to read from - * @param output the <code>OutputStream</code> to write to + * @param input the <code>InputStream</code> to read from + * @param output the <code>OutputStream</code> to write to * @return the number of bytes copied * @throws NullPointerException if the input or output is null - * @throws IOException if an I/O error occurs + * @throws IOException if an I/O error occurs * @since 1.3 */ - public static long copyLarge(InputStream input, OutputStream output) + public static long copyLarge(final InputStream input, final OutputStream output) throws IOException { byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; @@ -193,7 +192,8 @@ public class IOUtils { * @throws IOException if a read error occurs * @since 2.2 */ - public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { + public static int read(final InputStream input, final byte[] buffer, final int offset, final int length) + throws IOException { if (length < 0) { throw new IllegalArgumentException("Length must not be negative: " + length); } @@ -220,12 +220,13 @@ public class IOUtils { * @param offset initial offset into buffer * @param length length to read, must be >= 0 * - * @throws IOException if there is a problem reading the file + * @throws IOException if there is a problem reading the file * @throws IllegalArgumentException if length is negative - * @throws EOFException if the number of bytes read was incorrect + * @throws EOFException if the number of bytes read was incorrect * @since 2.2 */ - public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) throws IOException { + public static void readFully(final InputStream input, final byte[] buffer, final int offset, final int length) + throws IOException { final int actual = read(input, buffer, offset, length); if (actual != length) { throw new EOFException("Length to read: " + length + " actual: " + actual); @@ -241,9 +242,9 @@ public class IOUtils { * @param input where to read input from * @param buffer destination * - * @throws IOException if there is a problem reading the file + * @throws IOException if there is a problem reading the file * @throws IllegalArgumentException if length is negative - * @throws EOFException if the number of bytes read was incorrect + * @throws EOFException if the number of bytes read was incorrect * @since 2.2 */ public static void readFully(final InputStream input, final byte[] buffer) throws IOException { Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java Wed Dec 6 10:55:42 2017 @@ -87,6 +87,7 @@ public class MultipartStream { * {@link ProgressListener}. */ public static class ProgressNotifier { + /** * The listener to invoke. */ @@ -226,7 +227,7 @@ public class MultipartStream { private final byte[] boundary; /** - * The table for Knuth-Morris-Pratt search algorithm + * The table for Knuth-Morris-Pratt search algorithm. */ private int[] boundaryTable; @@ -302,7 +303,7 @@ public class MultipartStream { } this.input = input; - this.bufSize = Math.max(bufSize, boundaryLength*2); + this.bufSize = Math.max(bufSize, boundaryLength * 2); this.buffer = new byte[this.bufSize]; this.notifier = pNotifier; @@ -732,7 +733,6 @@ public class MultipartStream { */ public static class IllegalBoundaryException extends IOException { - /** * The UID to use when serializing this instance. */ Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/ThresholdingOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/ThresholdingOutputStream.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/ThresholdingOutputStream.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/ThresholdingOutputStream.java Wed Dec 6 10:55:42 2017 @@ -68,7 +68,7 @@ public abstract class ThresholdingOutput * * @param threshold The number of bytes at which to trigger an event. */ - public ThresholdingOutputStream(int threshold) + public ThresholdingOutputStream(final int threshold) { this.threshold = threshold; } @@ -82,10 +82,10 @@ public abstract class ThresholdingOutput * * @param b The byte to be written. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ @Override - public void write(int b) throws IOException + public void write(final int b) throws IOException { checkThreshold(1); getStream().write(b); @@ -99,10 +99,10 @@ public abstract class ThresholdingOutput * * @param b The array of bytes to be written. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ @Override - public void write(byte b[]) throws IOException + public void write(final byte b[]) throws IOException { checkThreshold(b.length); getStream().write(b); @@ -118,10 +118,10 @@ public abstract class ThresholdingOutput * @param off The start offset in the byte array. * @param len The number of bytes to write. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ @Override - public void write(byte b[], int off, int len) throws IOException + public void write(final byte b[], final int off, final int len) throws IOException { checkThreshold(len); getStream().write(b, off, len); @@ -133,7 +133,7 @@ public abstract class ThresholdingOutput * Flushes this output stream and forces any buffered output bytes to be * written out. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ @Override public void flush() throws IOException @@ -146,7 +146,7 @@ public abstract class ThresholdingOutput * Closes this output stream and releases any system resources associated * with this stream. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ @Override public void close() throws IOException @@ -155,7 +155,7 @@ public abstract class ThresholdingOutput { flush(); } - catch (IOException ignored) + catch (final IOException ignored) { // ignore } @@ -190,9 +190,9 @@ public abstract class ThresholdingOutput * @param count The number of bytes about to be written to the underlying * output stream. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ - protected void checkThreshold(int count) throws IOException + protected void checkThreshold(final int count) throws IOException { if (!thresholdExceeded && written + count > threshold) { @@ -210,7 +210,7 @@ public abstract class ThresholdingOutput * * @return The underlying output stream. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ protected abstract OutputStream getStream() throws IOException; @@ -220,7 +220,7 @@ public abstract class ThresholdingOutput * subclass should take whatever action necessary on this event. This may * include changing the underlying output stream. * - * @exception IOException if an error occurs. + * @throws IOException if an error occurs. */ protected abstract void thresholdReached() throws IOException; } Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java Wed Dec 6 10:55:42 2017 @@ -140,6 +140,12 @@ public class DiskFileItem */ private FileItemHeaders headers; + /** + * Default content charset to be used when no explicit charset + * parameter is provided by the sender. + */ + private String defaultCharset = DEFAULT_CHARSET; + // ----------------------------------------------------------- Constructors /** @@ -335,7 +341,7 @@ public class DiskFileItem byte[] rawdata = get(); String charset = getCharSet(); if (charset == null) { - charset = DEFAULT_CHARSET; + charset = defaultCharset; } try { return new String(rawdata, charset); @@ -422,7 +428,7 @@ public class DiskFileItem public void delete() { cachedContent = null; File outputFile = getStoreLocation(); - if (outputFile != null && outputFile.exists()) { + if (outputFile != null && !isInMemory() && outputFile.exists()) { outputFile.delete(); } } @@ -535,7 +541,7 @@ public class DiskFileItem */ @Override protected void finalize() { - if (dfos == null) { + if (dfos == null || dfos.isInMemory()) { return; } File outputFile = dfos.getFile(); @@ -622,4 +628,21 @@ public class DiskFileItem headers = pHeaders; } + /** + * Returns the default charset for use when no explicit charset + * parameter is provided by the sender. + * @return the default charset + */ + public String getDefaultCharset() { + return defaultCharset; + } + + /** + * Sets the default charset for use when no explicit charset + * parameter is provided by the sender. + * @param charset the default charset + */ + public void setDefaultCharset(String charset) { + defaultCharset = charset; + } } Modified: tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java (original) +++ tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java Wed Dec 6 10:55:42 2017 @@ -77,6 +77,12 @@ public class DiskFileItemFactory impleme */ private int sizeThreshold = DEFAULT_SIZE_THRESHOLD; + /** + * Default content charset to be used when no explicit charset + * parameter is provided by the sender. + */ + private String defaultCharset = DiskFileItem.DEFAULT_CHARSET; + // ----------------------------------------------------------- Constructors /** @@ -173,7 +179,27 @@ public class DiskFileItemFactory impleme @Override public FileItem createItem(String fieldName, String contentType, boolean isFormField, String fileName) { - return new DiskFileItem(fieldName, contentType, + DiskFileItem result = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); + result.setDefaultCharset(defaultCharset); + return result; + } + + /** + * Returns the default charset for use when no explicit charset + * parameter is provided by the sender. + * @return the default charset + */ + public String getDefaultCharset() { + return defaultCharset; + } + + /** + * Sets the default charset for use when no explicit charset + * parameter is provided by the sender. + * @param pCharset the default charset + */ + public void setDefaultCharset(String pCharset) { + defaultCharset = pCharset; } } Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1817285&r1=1817284&r2=1817285&view=diff ============================================================================== --- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Dec 6 10:55:42 2017 @@ -67,6 +67,14 @@ </add> </changelog> </subsection> + <subsection name="Other"> + <changelog> + <update> + Update the internal fork of Commons FileUpload to 6c00d57 (2017-11-23) + to pick up some code clean-up. (markt) + </update> + </changelog> + </subsection> </section> <section name="Tomcat 7.0.83 (violetagg)"> <subsection name="Catalina"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org