Author: markt Date: Fri Mar 15 12:08:38 2013 New Revision: 1456916 URL: http://svn.apache.org/r1456916 Log: Merge updates from Commons FileUpload to r1456912
Added: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/UploadContext.java - copied, changed from r1455855, commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/UploadContext.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ - copied from r1456515, commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/util/mime/ Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ (props changed) 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/ParameterParser.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/RequestContext.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItemFactory.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletRequestContext.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/Base64Decoder.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/package-info.java Propchange: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ ------------------------------------------------------------------------------ Merged /commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload:r1455032-1456912 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=1456916&r1=1456915&r2=1456916&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 Fri Mar 15 12:08:38 2013 @@ -20,6 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -256,7 +257,12 @@ public abstract class FileUploadBase { */ public FileItemIterator getItemIterator(RequestContext ctx) throws FileUploadException, IOException { - return new FileItemIteratorImpl(ctx); + try { + return new FileItemIteratorImpl(ctx); + } catch (FileUploadIOException e) { + // unwrap encapsulated SizeException + throw (FileUploadException) e.getCause(); + } } /** @@ -279,20 +285,17 @@ public abstract class FileUploadBase { FileItemIterator iter = getItemIterator(ctx); FileItemFactory fac = getFileItemFactory(); if (fac == null) { - throw new NullPointerException( - "No FileItemFactory has been set."); + throw new NullPointerException("No FileItemFactory has been set."); } while (iter.hasNext()) { final FileItemStream item = iter.next(); // Don't use getName() here to prevent an InvalidFileNameException. final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name; - FileItem fileItem = fac.createItem(item.getFieldName(), - item.getContentType(), item.isFormField(), - fileName); + FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(), + item.isFormField(), fileName); items.add(fileItem); try { - Streams.copy(item.openStream(), fileItem.getOutputStream(), - true); + Streams.copy(item.openStream(), fileItem.getOutputStream(), true); } catch (FileUploadIOException e) { throw (FileUploadException) e.getCause(); } catch (IOException e) { @@ -324,6 +327,39 @@ public abstract class FileUploadBase { } } + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param ctx The context for the request to be parsed. + * + * @return A map of <code>FileItem</code> instances parsed from the request. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @since 1.3 + */ + public Map<String, List<FileItem>> parseParameterMap(RequestContext ctx) + throws FileUploadException { + final List<FileItem> items = parseRequest(ctx); + final Map<String, List<FileItem>> itemsMap = new HashMap<>(items.size()); + + for (FileItem fileItem : items) { + String fieldName = fileItem.getFieldName(); + List<FileItem> mappedItems = itemsMap.get(fieldName); + + if (mappedItems == null) { + mappedItems = new ArrayList<>(); + itemsMap.put(fieldName, mappedItems); + } + + mappedItems.add(fileItem); + } + + return itemsMap; + } + // ------------------------------------------------------ Protected methods /** @@ -776,17 +812,15 @@ public abstract class FileUploadBase { InputStream input = ctx.getInputStream(); - if (sizeMax >= 0) { - long requestSize = ctx.contentLength(); + final long requestSize = ((UploadContext) ctx).contentLength(); - if (requestSize != -1) { - if (requestSize > sizeMax) { - throw new SizeLimitExceededException(String.format( - "the request was rejected because its size (%s) exceeds the configured maximum (%s)", - Long.valueOf(requestSize), - Long.valueOf(sizeMax)), - requestSize, sizeMax); - } + if (sizeMax >= 0) { + if (requestSize != -1 && requestSize > sizeMax) { + throw new SizeLimitExceededException(String.format( + "the request was rejected because its size (%s) exceeds the configured maximum (%s)", + Long.valueOf(requestSize), + Long.valueOf(sizeMax)), + requestSize, sizeMax); } input = new LimitedInputStream(input, sizeMax) { @Override @@ -811,8 +845,7 @@ public abstract class FileUploadBase { throw new FileUploadException("the request was rejected because no multipart boundary was found"); } - notifier = new MultipartStream.ProgressNotifier(listener, - ctx.contentLength()); + notifier = new MultipartStream.ProgressNotifier(listener, requestSize); multi = new MultipartStream(input, boundary, notifier); multi.setHeaderEncoding(charEncoding); @@ -920,7 +953,12 @@ public abstract class FileUploadBase { if (itemValid) { return true; } - return findNextItem(); + try { + return findNextItem(); + } catch (FileUploadIOException e) { + // unwrap encapsulated SizeException + throw (FileUploadException) e.getCause(); + } } /** 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=1456916&r1=1456915&r2=1456916&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 Fri Mar 15 12:08:38 2013 @@ -22,6 +22,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import org.apache.tomcat.util.http.fileupload.FileUploadBase.FileUploadIOException; import org.apache.tomcat.util.http.fileupload.util.Closeable; import org.apache.tomcat.util.http.fileupload.util.Streams; @@ -184,24 +185,24 @@ public class MultipartStream { * A byte sequence that marks the end of <code>header-part</code> * (<code>CRLFCRLF</code>). */ - protected static final byte[] HEADER_SEPARATOR = { CR, LF, CR, LF }; + protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF}; /** * A byte sequence that that follows a delimiter that will be * followed by an encapsulation (<code>CRLF</code>). */ - protected static final byte[] FIELD_SEPARATOR = { CR, LF}; + protected static final byte[] FIELD_SEPARATOR = {CR, LF}; /** * A byte sequence that that follows a delimiter of the last * encapsulation in the stream (<code>--</code>). */ - protected static final byte[] STREAM_TERMINATOR = { DASH, DASH}; + protected static final byte[] STREAM_TERMINATOR = {DASH, DASH}; /** * A byte sequence that precedes a boundary (<code>CRLF--</code>). */ - protected static final byte[] BOUNDARY_PREFIX = { CR, LF, DASH, DASH}; + protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH}; // ----------------------------------------------------------- Data members @@ -377,11 +378,12 @@ public class MultipartStream { * @return <code>true</code> if there are more encapsulations in * this stream; <code>false</code> otherwise. * - * @throws MalformedStreamException if the stream ends unexpecetedly or + * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits + * @throws MalformedStreamException if the stream ends unexpectedly or * fails to follow required syntax. */ public boolean readBoundary() - throws MalformedStreamException { + throws FileUploadIOException, MalformedStreamException { byte[] marker = new byte[2]; boolean nextChunk = false; @@ -407,6 +409,9 @@ public class MultipartStream { throw new MalformedStreamException( "Unexpected characters follow a boundary"); } + } catch (FileUploadIOException e) { + // wraps a SizeException, re-throw as it will be unwrapped later + throw e; } catch (IOException e) { throw new MalformedStreamException("Stream ended unexpectedly"); } @@ -455,9 +460,10 @@ public class MultipartStream { * * @return The <code>header-part</code> of the current encapsulation. * - * @throws MalformedStreamException if the stream ends unexpecetedly. + * @throws FileUploadIOException if the bytes read from the stream exceeded the size limits. + * @throws MalformedStreamException if the stream ends unexpectedly. */ - public String readHeaders() throws MalformedStreamException { + public String readHeaders() throws FileUploadIOException, MalformedStreamException { int i = 0; byte b; // to support multi-byte characters @@ -466,6 +472,9 @@ public class MultipartStream { while (i < HEADER_SEPARATOR.length) { try { b = readByte(); + } catch (FileUploadIOException e) { + // wraps a SizeException, re-throw as it will be unwrapped later + throw e; } catch (IOException e) { throw new MalformedStreamException("Stream ended unexpectedly"); } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java?rev=1456916&r1=1456915&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java Fri Mar 15 12:08:38 2013 @@ -16,10 +16,13 @@ */ package org.apache.tomcat.util.http.fileupload; +import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Locale; import java.util.Map; +import org.apache.tomcat.util.http.fileupload.util.mime.MimeUtility; + /** * A simple parser intended to parse sequences of name/value pairs. * @@ -312,6 +315,14 @@ public class ParameterParser { pos++; // skip '=' paramValue = parseQuotedToken(new char[] { separator }); + + if (paramValue != null) { + try { + paramValue = MimeUtility.decodeText(paramValue); + } catch (UnsupportedEncodingException e) { + // let's keep the original value in this case + } + } } if (hasChar() && (chars[pos] == separator)) { pos++; // skip separator @@ -320,6 +331,7 @@ public class ParameterParser { if (this.lowerCaseNames) { paramName = paramName.toLowerCase(Locale.ENGLISH); } + params.put(paramName, paramValue); } } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/RequestContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/RequestContext.java?rev=1456916&r1=1456915&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/RequestContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/RequestContext.java Fri Mar 15 12:08:38 2013 @@ -21,11 +21,9 @@ import java.io.InputStream; /** * <p>Abstracts access to the request information needed for file uploads. This - * interfsace should be implemented for each type of request that may be + * interface should be implemented for each type of request that may be * handled by FileUpload, such as servlets and portlets.</p> * - * @author <a href="mailto:mart...@apache.org">Martin Cooper</a> - * * @since FileUpload 1.1 * * @version $Id$ @@ -47,14 +45,6 @@ public interface RequestContext { String getContentType(); /** - * Retrieve the content length of the request. - * - * @return The content length of the request. - * @since 1.3 - */ - long contentLength(); - - /** * Retrieve the input stream for the request. * * @return The input stream for the request. Copied: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/UploadContext.java (from r1455855, commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/UploadContext.java) URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/UploadContext.java?p2=tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/UploadContext.java&p1=commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/UploadContext.java&r1=1455855&r2=1456916&rev=1456916&view=diff ============================================================================== --- commons/proper/fileupload/trunk/src/main/java/org/apache/commons/fileupload/UploadContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/UploadContext.java Fri Mar 15 12:08:38 2013 @@ -14,12 +14,16 @@ * 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; /** * Enhanced access to the request information needed for file uploads, * which fixes the Content Length data access in {@link RequestContext}. * + * The reason of introducing this new interface is just for backward compatibility + * and it might vanish for a refactored 2.x version moving the new method into + * RequestContext again. + * * @since 1.3 */ public interface UploadContext extends RequestContext { 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=1456916&r1=1456915&r2=1456916&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 Fri Mar 15 12:08:38 2013 @@ -206,6 +206,7 @@ public class DiskFileItemFactory impleme /** * Returns the tracker, which is responsible for deleting temporary * files. + * * @return An instance of {@link FileCleaningTracker}, or null * (default), if temporary files aren't tracked. */ @@ -216,6 +217,7 @@ public class DiskFileItemFactory impleme /** * 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, or null * (default), to disable tracking. Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java?rev=1456916&r1=1456915&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java Fri Mar 15 12:08:38 2013 @@ -17,13 +17,16 @@ package org.apache.tomcat.util.http.fileupload.servlet; import java.io.IOException; -import java.util.Locale; +import java.util.List; +import java.util.Map; import javax.servlet.http.HttpServletRequest; +import org.apache.tomcat.util.http.fileupload.FileItem; import org.apache.tomcat.util.http.fileupload.FileItemFactory; import org.apache.tomcat.util.http.fileupload.FileItemIterator; import org.apache.tomcat.util.http.fileupload.FileUpload; +import org.apache.tomcat.util.http.fileupload.FileUploadBase; import org.apache.tomcat.util.http.fileupload.FileUploadException; @@ -45,6 +48,11 @@ import org.apache.tomcat.util.http.fileu */ public class ServletFileUpload extends FileUpload { + /** + * Constant for HTTP POST method. + */ + private static final String POST_METHOD = "POST"; + // ---------------------------------------------------------- Class methods /** @@ -58,17 +66,10 @@ public class ServletFileUpload extends F */ public static final boolean isMultipartContent( HttpServletRequest request) { - if (!"post".equals(request.getMethod().toLowerCase(Locale.ENGLISH))) { - return false; - } - String contentType = request.getContentType(); - if (contentType == null) { + if (!POST_METHOD.equalsIgnoreCase(request.getMethod())) { return false; } - if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) { - return true; - } - return false; + return FileUploadBase.isMultipartContent(new ServletRequestContext(request)); } // ----------------------------------------------------------- Constructors @@ -103,6 +104,24 @@ public class ServletFileUpload extends F * * @param request The servlet request to be parsed. * + * @return A map of <code>FileItem</code> instances parsed from the request. + * + * @throws FileUploadException if there are problems reading/parsing + * the request or storing files. + * + * @since 1.3 + */ + public Map<String, List<FileItem>> parseParameterMap(HttpServletRequest request) + throws FileUploadException { + return parseParameterMap(new ServletRequestContext(request)); + } + + /** + * Processes an <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a> + * compliant <code>multipart/form-data</code> stream. + * + * @param request The servlet request to be parsed. + * * @return An iterator to instances of <code>FileItemStream</code> * parsed from the request, in the order that they were * transmitted. Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletRequestContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletRequestContext.java?rev=1456916&r1=1456915&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletRequestContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/servlet/ServletRequestContext.java Fri Mar 15 12:08:38 2013 @@ -22,7 +22,7 @@ import java.io.InputStream; import javax.servlet.http.HttpServletRequest; import org.apache.tomcat.util.http.fileupload.FileUploadBase; -import org.apache.tomcat.util.http.fileupload.RequestContext; +import org.apache.tomcat.util.http.fileupload.UploadContext; /** @@ -33,7 +33,7 @@ import org.apache.tomcat.util.http.fileu * * @version $Id$ */ -public class ServletRequestContext implements RequestContext { +public class ServletRequestContext implements UploadContext { // ----------------------------------------------------- Instance Variables Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/Base64Decoder.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/Base64Decoder.java?rev=1456916&r1=1456515&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/Base64Decoder.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/Base64Decoder.java Fri Mar 15 12:08:38 2013 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.fileupload.util.mime; +package org.apache.tomcat.util.http.fileupload.util.mime; import java.io.IOException; import java.io.OutputStream; @@ -24,41 +24,61 @@ import java.io.OutputStream; */ final class Base64Decoder { - protected final byte[] encodingTable = { - (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', - (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', - (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', - (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', - (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', - (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', - (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', - (byte)'v', - (byte)'w', (byte)'x', (byte)'y', (byte)'z', - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', - (byte)'7', (byte)'8', (byte)'9', - (byte)'+', (byte)'/' + /** + * set up the encoding table. + */ + private static final byte[] ENCODING_TABLE = { + (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', + (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', + (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', + (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n', + (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', + (byte) 'v', + (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', + (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', + (byte) '7', (byte) '8', (byte) '9', + (byte) '+', (byte) '/' }; - protected byte padding = (byte)'='; + /** + * The padding byte. + */ + private static final byte PADDING = (byte) '='; + + /** + * the decoding table size. + */ + private static final int DECODING_TABLE_SIZE = 256; - /* + /** * set up the decoding table. */ - protected final byte[] decodingTable = new byte[256]; + private static final byte[] DECODING_TABLE = new byte[DECODING_TABLE_SIZE]; - protected void initialiseDecodingTable() { - for (int i = 0; i < encodingTable.length; i++) { - decodingTable[encodingTable[i]] = (byte)i; + static { + for (int i = 0; i < ENCODING_TABLE.length; i++) { + DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i; } } - public Base64Decoder() { - initialiseDecodingTable(); + /** + * Hidden constructor, this class must not be instantiated. + */ + private Base64Decoder() { + // do nothing } - private boolean ignore( + /** + * Checks if the input char must be skipped from the decode. + * + * @param c the char has to be checked. + * @return true, if the input char has to be checked, false otherwise. + */ + private static boolean ignore( char c) { - return (c == '\n' || c =='\r' || c == '\t' || c == ' '); + return (c == '\n' || c == '\r' || c == '\t' || c == ' '); } /** @@ -67,7 +87,7 @@ final class Base64Decoder { * * @return the number of bytes produced. */ - public int decode( + public static int decode( byte[] data, int off, int length, @@ -79,7 +99,7 @@ final class Base64Decoder { int end = off + length; while (end > 0) { - if (!ignore((char)data[end - 1])) { + if (!ignore((char) data[end - 1])) { break; } @@ -90,29 +110,29 @@ final class Base64Decoder { int finish = end - 4; while (i < finish) { - while ((i < finish) && ignore((char)data[i])) { + while ((i < finish) && ignore((char) data[i])) { i++; } - b1 = decodingTable[data[i++]]; + b1 = DECODING_TABLE[data[i++]]; - while ((i < finish) && ignore((char)data[i])) { + while ((i < finish) && ignore((char) data[i])) { i++; } - b2 = decodingTable[data[i++]]; + b2 = DECODING_TABLE[data[i++]]; - while ((i < finish) && ignore((char)data[i])) { + while ((i < finish) && ignore((char) data[i])) { i++; } - b3 = decodingTable[data[i++]]; + b3 = DECODING_TABLE[data[i++]]; - while ((i < finish) && ignore((char)data[i])) { + while ((i < finish) && ignore((char) data[i])) { i++; } - b4 = decodingTable[data[i++]]; + b4 = DECODING_TABLE[data[i++]]; out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); @@ -121,27 +141,27 @@ final class Base64Decoder { outLen += 3; } - if (data[end - 2] == padding) { - b1 = decodingTable[data[end - 4]]; - b2 = decodingTable[data[end - 3]]; + if (data[end - 2] == PADDING) { + b1 = DECODING_TABLE[data[end - 4]]; + b2 = DECODING_TABLE[data[end - 3]]; out.write((b1 << 2) | (b2 >> 4)); outLen += 1; - } else if (data[end - 1] == padding) { - b1 = decodingTable[data[end - 4]]; - b2 = decodingTable[data[end - 3]]; - b3 = decodingTable[data[end - 2]]; + } else if (data[end - 1] == PADDING) { + b1 = DECODING_TABLE[data[end - 4]]; + b2 = DECODING_TABLE[data[end - 3]]; + b3 = DECODING_TABLE[data[end - 2]]; out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); outLen += 2; } else { - b1 = decodingTable[data[end - 4]]; - b2 = decodingTable[data[end - 3]]; - b3 = decodingTable[data[end - 2]]; - b4 = decodingTable[data[end - 1]]; + b1 = DECODING_TABLE[data[end - 4]]; + b2 = DECODING_TABLE[data[end - 3]]; + b3 = DECODING_TABLE[data[end - 2]]; + b4 = DECODING_TABLE[data[end - 1]]; out.write((b1 << 2) | (b2 >> 4)); out.write((b2 << 4) | (b3 >> 2)); Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java?rev=1456916&r1=1456515&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java Fri Mar 15 12:08:38 2013 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.fileupload.util.mime; +package org.apache.tomcat.util.http.fileupload.util.mime; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -26,17 +26,19 @@ import java.util.Map; /** * Utility class to decode MIME texts. * - * Imported and retailed from <a href="http://svn.apache.org/repos/asf/geronimo/specs/tags/geronimo-javamail_1.4_spec-1.4/src/main/java/javax/mail/internet/MimeUtility.java">Apache Geronimo</a> - * * @since 1.3 */ public final class MimeUtility { + /** + * The linear whitespace chars sequence. + */ private static final String LINEAR_WHITESPACE = " \t\r\n"; - private static final Map<String, String> MIME2JAVA = new HashMap<String, String>(); - - private static final Base64Decoder BASE64_DECODER = new Base64Decoder(); + /** + * Mappings between MIME and Java charset. + */ + private static final Map<String, String> MIME2JAVA = new HashMap<>(); static { MIME2JAVA.put("iso-2022-cn", "ISO2022CN"); @@ -67,7 +69,7 @@ public final class MimeUtility { * @param text The text to decode. * * @return The decoded test string. - * @exception UnsupportedEncodingException + * @throws UnsupportedEncodingException */ public static String decodeText(String text) throws UnsupportedEncodingException { // if the text contains any encoded tokens, those tokens will be marked with "=?". If the @@ -97,8 +99,7 @@ public final class MimeUtility { ch = text.charAt(offset); if (LINEAR_WHITESPACE.indexOf(ch) != -1) { offset++; - } - else { + } else { // record the location of the first non lwsp and drop down to process the // token characters. endWhiteSpace = offset; @@ -114,8 +115,7 @@ public final class MimeUtility { ch = text.charAt(offset); if (LINEAR_WHITESPACE.indexOf(ch) == -1) { offset++; - } - else { + } else { break; } @@ -130,11 +130,9 @@ public final class MimeUtility { String decodedWord = decodeWord(word); // are any whitespace characters significant? Append 'em if we've got 'em. - if (!previousTokenEncoded) { - if (startWhiteSpace != -1) { - decodedText.append(text.substring(startWhiteSpace, endWhiteSpace)); - startWhiteSpace = -1; - } + if (!previousTokenEncoded && startWhiteSpace != -1) { + decodedText.append(text.substring(startWhiteSpace, endWhiteSpace)); + startWhiteSpace = -1; } // this is definitely a decoded token. previousTokenEncoded = true; @@ -145,6 +143,7 @@ public final class MimeUtility { continue; } catch (ParseException e) { + // just ignore it, skip to next word } } // this is a normal token, so it doesn't matter what the previous token was. Add the white space @@ -171,8 +170,8 @@ public final class MimeUtility { * @param word The possibly encoded word value. * * @return The decoded word. - * @exception ParseException - * @exception UnsupportedEncodingException + * @throws ParseException + * @throws UnsupportedEncodingException */ private static String decodeWord(String word) throws ParseException, UnsupportedEncodingException { // encoded words start with the characters "=?". If this not an encoded word, we throw a @@ -219,10 +218,9 @@ public final class MimeUtility { // Base64 encoded? if (encoding.equals("B")) { - BASE64_DECODER.decode(encodedData, 0, encodedData.length, out); + Base64Decoder.decode(encodedData, 0, encodedData.length, out); } else if (encoding.equals("Q")) { // maybe quoted printable. - QuotedPrintableDecoder dataEncoder = new QuotedPrintableDecoder(); - dataEncoder.decodeWord(encodedData, 0, encodedData.length, out); + QuotedPrintableDecoder.decodeWord(encodedData, 0, encodedData.length, out); } else { throw new UnsupportedEncodingException("Unknown RFC 2047 encoding: " + encoding); } @@ -251,7 +249,10 @@ public final class MimeUtility { String mappedCharset = MIME2JAVA.get(charset.toLowerCase(Locale.ENGLISH)); // if there is no mapping, then the original name is used. Many of the MIME character set // names map directly back into Java. The reverse isn't necessarily true. - return mappedCharset == null ? charset : mappedCharset; + if (mappedCharset == null) { + return charset; + } + return mappedCharset; } } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java?rev=1456916&r1=1456515&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java Fri Mar 15 12:08:38 2013 @@ -14,18 +14,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.fileupload.util.mime; +package org.apache.tomcat.util.http.fileupload.util.mime; /** * @since 1.3 */ -public final class ParseException extends Exception { +final class ParseException extends Exception { /** - * + * The UID to use when serializing this instance. */ private static final long serialVersionUID = 5355281266579392077L; + /** + * Constructs a new exception with the specified detail message. + * + * @param message the detail message. + */ public ParseException(String message) { super(message); } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java?rev=1456916&r1=1456515&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java Fri Mar 15 12:08:38 2013 @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.commons.fileupload.util.mime; +package org.apache.tomcat.util.http.fileupload.util.mime; import java.io.IOException; import java.io.OutputStream; @@ -25,67 +25,44 @@ import java.io.OutputStream; final class QuotedPrintableDecoder { /** - * set up the encoding table. + * Set up the encoding table. */ - static protected final byte[] ENCODING_TABLE = - { - (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', - (byte)'8', (byte)'9', (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F' + private static final byte[] ENCODING_TABLE = { + (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F' }; /** - * set up the decoding table. + * The default number of byte shift for decode. */ - static protected final byte[] DECODING_TABLE = new byte[128]; + private static final int OUT_SHIFT = 4; + + /** + * The decoding table size. + */ + private static final int DECODING_TABLE_SIZE = 128; + + /** + * Set up the decoding table. + */ + private static final byte[] DECODING_TABLE = new byte[DECODING_TABLE_SIZE]; static { // initialize the decoding table for (int i = 0; i < ENCODING_TABLE.length; i++) { - DECODING_TABLE[ENCODING_TABLE[i]] = (byte)i; + DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i; } } - // default number of characters we will write per line. - static private final int DEFAULT_CHARS_PER_LINE = 76; - - // the output stream we're wrapped around - protected OutputStream out; - - // the number of bytes written; - protected int bytesWritten = 0; - - // number of bytes written on the current line - protected int lineCount = 0; - - // line length we're dealing with - protected int lineLength; - - // number of deferred whitespace characters in decode mode. - protected int deferredWhitespace = 0; - - protected int cachedCharacter = -1; - - // indicates whether the last character was a '\r', potentially part of a CRLF sequence. - protected boolean lastCR = false; - - // remember whether last character was a white space. - protected boolean lastWhitespace = false; - - public QuotedPrintableDecoder() { - this(null, DEFAULT_CHARS_PER_LINE); - } - - public QuotedPrintableDecoder(OutputStream out) { - this(out, DEFAULT_CHARS_PER_LINE); - } - - public QuotedPrintableDecoder(OutputStream out, int lineLength) { - this.out = out; - this.lineLength = lineLength; + /** + * Hidden constructor, this class must not be instantiated. + */ + private QuotedPrintableDecoder() { + // do nothing } /** - * decode the uuencoded byte data writing it to the given output stream + * Decode the unencoded byte data writing it to the given output stream. * * @param data The array of byte data to decode. * @param off Starting offset within the array. @@ -95,10 +72,7 @@ final class QuotedPrintableDecoder { * @return the number of bytes produced. * @exception IOException */ - public int decodeWord(byte[] data, int off, int length, OutputStream out) throws IOException { - // make sure we're writing to the correct stream - this.out = out; - + public static int decodeWord(byte[] data, int off, int length, OutputStream out) throws IOException { int endOffset = off + length; int bytesWritten = 0; @@ -129,7 +103,7 @@ final class QuotedPrintableDecoder { // this is a hex pair we need to convert back to a single byte. byte c1 = DECODING_TABLE[b1]; byte c2 = DECODING_TABLE[b2]; - out.write((c1 << 4) | c2); + out.write((c1 << OUT_SHIFT) | c2); // 3 bytes in, one byte out bytesWritten++; } Modified: tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/package-info.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/package-info.java?rev=1456916&r1=1456515&r2=1456916&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/package-info.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/fileupload/util/mime/package-info.java Fri Mar 15 12:08:38 2013 @@ -19,4 +19,4 @@ * MIME decoder implementation, imported and retailed from * <a href="http://svn.apache.org/repos/asf/geronimo/specs/tags/geronimo-javamail_1.4_spec-1.4/">Apache Geronimo</a>. */ -package org.apache.commons.fileupload.util.mime; +package org.apache.tomcat.util.http.fileupload.util.mime; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org