Author: markt
Date: Sun Aug 1 09:52:35 2010
New Revision: 981190
URL: http://svn.apache.org/viewvc?rev=981190&view=rev
Log:
Update to commons-fileupload 1.2.2
Added:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/InvalidFileNameException.java
- copied, changed from r981187,
commons/proper/fileupload/tags/commons-fileupload-1.2.2/src/java/org/apache/commons/fileupload/InvalidFileNameException.java
Modified:
tomcat/trunk/java/org/apache/catalina/connector/Request.java
tomcat/trunk/java/org/apache/catalina/core/ApplicationPart.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
tomcat/trunk/webapps/docs/changelog.xml
Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Sun Aug 1
09:52:35 2010
@@ -82,12 +82,12 @@ import org.apache.tomcat.util.http.Cooki
import org.apache.tomcat.util.http.FastHttpDateFormat;
import org.apache.tomcat.util.http.Parameters;
import org.apache.tomcat.util.http.ServerCookie;
-import org.apache.tomcat.util.http.fileupload.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileUploadBase;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
-import org.apache.tomcat.util.http.fileupload.ServletFileUpload;
import
org.apache.tomcat.util.http.fileupload.FileUploadBase.InvalidContentTypeException;
+import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
+import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
import org.apache.tomcat.util.http.mapper.MappingData;
import org.apache.tomcat.util.res.StringManager;
Modified: tomcat/trunk/java/org/apache/catalina/core/ApplicationPart.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/ApplicationPart.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/ApplicationPart.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/ApplicationPart.java Sun Aug 1
09:52:35 2010
@@ -31,9 +31,9 @@ import java.util.Map;
import javax.servlet.MultipartConfigElement;
import javax.servlet.http.Part;
-import org.apache.tomcat.util.http.fileupload.DiskFileItem;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.ParameterParser;
+import org.apache.tomcat.util.http.fileupload.disk.DiskFileItem;
/**
* Adaptor to allow {...@link FileItem} objects generated by the package
renamed
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileItem.java Sun
Aug 1 09:52:35 2010
@@ -85,6 +85,10 @@ public interface FileItem extends Serial
* the Opera browser, do include path information.
*
* @return The original filename in the client's filesystem.
+ * @throws InvalidFileNameException The file name contains a NUL character,
+ * which might be an indicator of a security attack. If you intend to
+ * use the file name anyways, catch the exception and use
+ * InvalidFileNameException#getName().
*/
String getName();
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
Sun Aug 1 09:52:35 2010
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -297,19 +298,23 @@ public abstract class FileUploadBase {
*/
public List<FileItem> parseRequest(RequestContext ctx)
throws FileUploadException {
+ List<FileItem> items = new ArrayList<FileItem>();
+ boolean successful = false;
try {
FileItemIterator iter = getItemIterator(ctx);
- List<FileItem> items = new ArrayList<FileItem>();
FileItemFactory fac = getFileItemFactory();
if (fac == null) {
throw new NullPointerException(
"No FileItemFactory has been set.");
}
while (iter.hasNext()) {
- FileItemStream item = iter.next();
+ final FileItemStream item = iter.next();
+ // Don't use getName() here to prevent an
InvalidFileNameException.
+ final String fileName =
((org.apache.tomcat.util.http.fileupload.FileUploadBase.FileItemIteratorImpl.FileItemStreamImpl)
item).name;
FileItem fileItem = fac.createItem(item.getFieldName(),
item.getContentType(), item.isFormField(),
- item.getName());
+ fileName);
+ items.add(fileItem);
try {
Streams.copy(item.openStream(), fileItem.getOutputStream(),
true);
@@ -324,13 +329,24 @@ public abstract class FileUploadBase {
final FileItemHeaders fih = item.getHeaders();
((FileItemHeadersSupport) fileItem).setHeaders(fih);
}
- items.add(fileItem);
}
+ successful = true;
return items;
} catch (FileUploadIOException e) {
throw (FileUploadException) e.getCause();
} catch (IOException e) {
throw new FileUploadException(e.getMessage(), e);
+ } finally {
+ if (!successful) {
+ for (Iterator<FileItem> iterator = items.iterator();
iterator.hasNext();) {
+ FileItem fileItem = iterator.next();
+ try {
+ fileItem.delete();
+ } catch (Throwable e) {
+ // ignore it
+ }
+ }
+ }
}
}
@@ -547,7 +563,7 @@ public abstract class FileUploadBase {
/**
* Default implementation of {...@link FileItemStream}.
*/
- private class FileItemStreamImpl implements FileItemStream {
+ class FileItemStreamImpl implements FileItemStream {
/** The file items content type.
*/
private final String contentType;
@@ -591,13 +607,15 @@ public abstract class FileUploadBase {
if (fileSizeMax != -1) {
if (pContentLength != -1
&& pContentLength > fileSizeMax) {
- FileUploadException e =
+ FileSizeLimitExceededException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + fileSizeMax
- + " characters.",
+ + " bytes.",
pContentLength, fileSizeMax);
+ e.setFileName(pName);
+ e.setFieldName(pFieldName);
throw new FileUploadIOException(e);
}
istream = new LimitedInputStream(istream, fileSizeMax) {
@@ -605,14 +623,16 @@ public abstract class FileUploadBase {
protected void raiseError(long pSizeMax, long pCount)
throws IOException {
itemStream.close(true);
- FileUploadException e =
+ FileSizeLimitExceededException e =
new FileSizeLimitExceededException(
"The field " + fieldName
+ " exceeds its maximum permitted "
+ " size of " + pSizeMax
- + " characters.",
+ + " bytes.",
pCount, pSizeMax);
- throw new FileUploadIOException(e);
+ e.setFieldName(fieldName);
+ e.setFileName(name);
+ throw new FileUploadIOException(e);
}
};
}
@@ -638,9 +658,13 @@ public abstract class FileUploadBase {
/**
* Returns the items file name.
* @return File name, if known, or null.
+ * @throws InvalidFileNameException The file name contains a NUL
character,
+ * which might be an indicator of a security attack. If you
intend to
+ * use the file name anyways, catch the exception and use
+ * InvalidFileNameException#getName().
*/
public String getName() {
- return name;
+ return Streams.checkFileName(name);
}
/**
@@ -1024,7 +1048,7 @@ public abstract class FileUploadBase {
*/
public abstract static class SizeException extends FileUploadException {
- private static final long serialVersionUID = 1L;
+ private static final long serialVersionUID = -8776225574705254126L;
/**
* The actual size of the request.
@@ -1100,6 +1124,16 @@ public abstract class FileUploadBase {
private static final long serialVersionUID = 8150776562029630058L;
/**
+ * File name of the item, which caused the exception.
+ */
+ private String fileName;
+
+ /**
+ * Field name of the item, which caused the exception.
+ */
+ private String fieldName;
+
+ /**
* Constructs a <code>SizeExceededException</code> with
* the specified detail message, and actual and permitted sizes.
*
@@ -1111,6 +1145,40 @@ public abstract class FileUploadBase {
long permitted) {
super(message, actual, permitted);
}
+
+ /**
+ * Returns the file name of the item, which caused the
+ * exception.
+ * @return File name, if known, or null.
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Sets the file name of the item, which caused the
+ * exception.
+ */
+ public void setFileName(String pFileName) {
+ fileName = pFileName;
+ }
+
+ /**
+ * Returns the field name of the item, which caused the
+ * exception.
+ * @return Field name, if known, or null.
+ */
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ /**
+ * Sets the field name of the item, which caused the
+ * exception.
+ */
+ public void setFieldName(String pFieldName) {
+ fieldName = pFieldName;
+ }
}
/**
Copied:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/InvalidFileNameException.java
(from r981187,
commons/proper/fileupload/tags/commons-fileupload-1.2.2/src/java/org/apache/commons/fileupload/InvalidFileNameException.java)
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/InvalidFileNameException.java?p2=tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/InvalidFileNameException.java&p1=commons/proper/fileupload/tags/commons-fileupload-1.2.2/src/java/org/apache/commons/fileupload/InvalidFileNameException.java&r1=981187&r2=981190&rev=981190&view=diff
==============================================================================
---
commons/proper/fileupload/tags/commons-fileupload-1.2.2/src/java/org/apache/commons/fileupload/InvalidFileNameException.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/InvalidFileNameException.java
Sun Aug 1 09:52:35 2010
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.commons.fileupload;
+package org.apache.tomcat.util.http.fileupload;
/**
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
Sun Aug 1 09:52:35 2010
@@ -61,24 +61,22 @@ import org.apache.tomcat.util.http.fileu
* <p>Here is an example of usage of this class.<br>
*
* <pre>
- * try {
- * MultipartStream multipartStream = new MultipartStream(input,
- * boundary);
- * boolean nextPart = multipartStream.skipPreamble();
- * OutputStream output;
- * while(nextPart) {
- * header = chunks.readHeader();
- * // process headers
- * // create some output stream
- * multipartStream.readBodyPart(output);
- * nextPart = multipartStream.readBoundary();
- * }
- * } catch(MultipartStream.MalformedStreamException e) {
- * // the stream failed to follow required syntax
- * } catch(IOException) {
- * // a read or write error occurred
- * }
- *
+ * try {
+ * MultipartStream multipartStream = new MultipartStream(input, boundary);
+ * boolean nextPart = multipartStream.skipPreamble();
+ * OutputStream output;
+ * while(nextPart) {
+ * String header = multipartStream.readHeaders();
+ * // process headers
+ * // create some output stream
+ * multipartStream.readBodyData(output);
+ * nextPart = multipartStream.readBoundary();
+ * }
+ * } catch(MultipartStream.MalformedStreamException e) {
+ * // the stream failed to follow required syntax
+ * } catch(IOException e) {
+ * // a read or write error occurred
+ * }
* </pre>
*
* @author <a href="mailto:[email protected]">Rafal Krzewski</a>
@@ -92,7 +90,7 @@ public class MultipartStream {
* Internal class, which is used to invoke the
* {...@link ProgressListener}.
*/
- static class ProgressNotifier {
+ public static class ProgressNotifier {
/** The listener to invoke.
*/
private final ProgressListener listener;
@@ -128,6 +126,7 @@ public class MultipartStream {
*/
void noteItem() {
++items;
+ notifyListener();
}
/** Called for notifying the listener.
*/
@@ -965,70 +964,4 @@ public class MultipartStream {
return closed;
}
}
-
- // ------------------------------------------------------ Debugging methods
-
-
- // These are the methods that were used to debug this stuff.
- /*
-
- // Dump data.
- protected void dump()
- {
- System.out.println("01234567890");
- byte[] temp = new byte[buffer.length];
- for(int i=0; i<buffer.length; i++)
- {
- if (buffer[i] == 0x0D || buffer[i] == 0x0A)
- {
- temp[i] = 0x21;
- }
- else
- {
- temp[i] = buffer[i];
- }
- }
- System.out.println(new String(temp));
- int i;
- for (i=0; i<head; i++)
- System.out.print(" ");
- System.out.println("h");
- for (i=0; i<tail; i++)
- System.out.print(" ");
- System.out.println("t");
- System.out.flush();
- }
-
- // Main routine, for testing purposes only.
- //
- // @param args A String[] with the command line arguments.
- // @throws Exception, a generic exception.
- public static void main( String[] args )
- throws Exception
- {
- File boundaryFile = new File("boundary.dat");
- int boundarySize = (int)boundaryFile.length();
- byte[] boundary = new byte[boundarySize];
- FileInputStream input = new FileInputStream(boundaryFile);
- input.read(boundary,0,boundarySize);
-
- input = new FileInputStream("multipart.dat");
- MultipartStream chunks = new MultipartStream(input, boundary);
-
- int i = 0;
- String header;
- OutputStream output;
- boolean nextChunk = chunks.skipPreamble();
- while (nextChunk)
- {
- header = chunks.readHeaders();
- System.out.println("!"+header+"!");
- System.out.println("wrote part"+i+".dat");
- output = new FileOutputStream("part"+(i++)+".dat");
- chunks.readBodyData(output);
- nextChunk = chunks.readBoundary();
- }
- }
-
- */
}
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
Sun Aug 1 09:52:35 2010
@@ -35,8 +35,10 @@ import org.apache.tomcat.util.http.fileu
import org.apache.tomcat.util.http.fileupload.FileItemHeaders;
import org.apache.tomcat.util.http.fileupload.FileItemHeadersSupport;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
+import org.apache.tomcat.util.http.fileupload.InvalidFileNameException;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.tomcat.util.http.fileupload.ParameterParser;
+import org.apache.tomcat.util.http.fileupload.util.Streams;
/**
@@ -52,9 +54,12 @@ import org.apache.tomcat.util.http.fileu
* {...@link #getInputStream()} and process the file without attempting to load
* it into memory, which may come handy with large files.
*
- * <p>When using the <code>DiskFileItemFactory</code>, then you should
- * consider the following: Temporary files are automatically deleted as
- * soon as they are no longer needed. (More precisely, when the
+ * <p>Temporary files, which are created for file items, should be
+ * deleted later on. The best way to do this is using a
+ * {...@link FileCleaningTracker}, which you can set on the
+ * {...@link DiskFileItemFactory}. However, if you do use such a tracker,
+ * then you must consider the following: Temporary files are automatically
+ * deleted as soon as they are no longer needed. (More precisely, when the
* corresponding instance of {...@link java.io.File} is garbage collected.)
* This is done by the so-called reaper thread, which is started
* automatically when the class {...@link org.apache.commons.io.FileCleaner}
@@ -269,9 +274,13 @@ public class DiskFileItem
* Returns the original filename in the client's filesystem.
*
* @return The original filename in the client's filesystem.
+ * @throws InvalidFileNameException The file name contains a NUL character,
+ * which might be an indicator of a security attack. If you intend to
+ * use the file name anyways, catch the exception and use
+ * InvalidFileNameException#getName().
*/
public String getName() {
- return fileName;
+ return Streams.checkFileName(fileName);
}
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
---
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java
(original)
+++
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java
Sun Aug 1 09:52:35 2010
@@ -41,15 +41,18 @@ import org.apache.tomcat.util.http.fileu
* </ul>
* </p>
*
- * <p>When using the <code>DiskFileItemFactory</code>, then you should
- * consider the following: Temporary files are automatically deleted as
- * soon as they are no longer needed. (More precisely, when the
+ * <p>Temporary files, which are created for file items, should be
+ * deleted later on. The best way to do this is using a
+ * {...@link FileCleaningTracker}, which you can set on the
+ * {...@link DiskFileItemFactory}. However, if you do use such a tracker,
+ * then you must consider the following: Temporary files are automatically
+ * deleted as soon as they are no longer needed. (More precisely, when the
* corresponding instance of {...@link java.io.File} is garbage collected.)
- * Cleaning up those files is done by an instance of
- * {...@link FileCleaningTracker}, and an associated thread. In a complex
- * environment, for example in a web application, you should consider
- * terminating this thread, for example, when your web application
- * ends. See the section on "Resource cleanup"
+ * This is done by the so-called reaper thread, which is started
+ * automatically when the class {...@link org.apache.commons.io.FileCleaner}
+ * is loaded.
+ * It might make sense to terminate that thread, for example, if
+ * your web application ends. See the section on "Resource cleanup"
* in the users guide of commons-fileupload.</p>
*
* @author <a href="mailto:[email protected]">Martin Cooper</a>
@@ -206,20 +209,19 @@ public class DiskFileItemFactory impleme
/**
* Returns the tracker, which is responsible for deleting temporary
* files.
- * @return An instance of {...@link FileCleaningTracker}, defaults to
- * {...@link org.apache.commons.io.FileCleaner#getInstance()}. Null,
- * if temporary files aren't tracked.
+ * @return An instance of {...@link FileCleaningTracker}, or null
+ * (default), if temporary files aren't tracked.
*/
public FileCleaningTracker getFileCleaningTracker() {
return fileCleaningTracker;
}
/**
- * Returns the tracker, which is responsible for deleting temporary
+ * Sets the tracker, which is responsible for deleting temporary
* files.
* @param pTracker An instance of {...@link FileCleaningTracker},
- * which will from now on track the created files. May be null
- * to disable tracking.
+ * which will from now on track the created files, or null
+ * (default), to disable tracking.
*/
public void setFileCleaningTracker(FileCleaningTracker pTracker) {
fileCleaningTracker = pTracker;
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/Streams.java?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
(original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
Sun Aug 1 09:52:35 2010
@@ -21,6 +21,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import org.apache.tomcat.util.http.fileupload.InvalidFileNameException;
+
/** Utility class for working with streams.
*/
@@ -163,4 +165,34 @@ public final class Streams {
copy(pStream, baos, true);
return baos.toString(pEncoding);
}
+
+ /**
+ * Checks, whether the given file name is valid in the sense,
+ * that it doesn't contain any NUL characters. If the file name
+ * is valid, it will be returned without any modifications. Otherwise,
+ * an {...@link InvalidFileNameException} is raised.
+ * @param pFileName The file name to check
+ * @return Unmodified file name, if valid.
+ * @throws InvalidFileNameException The file name was found to be invalid.
+ */
+ public static String checkFileName(String pFileName) {
+ if (pFileName != null && pFileName.indexOf('\u0000') != -1) {
+ // pFileName.replace("\u0000", "\\0")
+ final StringBuffer sb = new StringBuffer();
+ for (int i = 0; i < pFileName.length(); i++) {
+ char c = pFileName.charAt(i);
+ switch (c) {
+ case 0:
+ sb.append("\\0");
+ break;
+ default:
+ sb.append(c);
+ break;
+ }
+ }
+ throw new InvalidFileNameException(pFileName,
+ "Invalid file name: " + sb);
+ }
+ return pFileName;
+ }
}
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=981190&r1=981189&r2=981190&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Sun Aug 1 09:52:35 2010
@@ -327,6 +327,12 @@
Updated to Ant 1.8.1. The build now requires a minimum of Ant 1.8.x.
(markt)
</update>
+ <update>
+ Update the re-packaged version of commons-fileupload from 1.2.1 to
+ 1.2.2. The layout of re-packaged version was also restored to the
+ original commons-fileupload layout to make merging of future updates
+ easier. (markt)
+ </update>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]