You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2021/09/01 16:14:41 UTC
[tomcat] branch 9.0.x updated: Update Tomcat's internal fork of
Commons FileUpload
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 2a5d0b0 Update Tomcat's internal fork of Commons FileUpload
2a5d0b0 is described below
commit 2a5d0b00ad426f9888453a9987d6ce889be7cb6b
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Sep 1 17:12:12 2021 +0100
Update Tomcat's internal fork of Commons FileUpload
---
MERGE.txt | 2 +-
java/org/apache/catalina/connector/Request.java | 3 +-
java/org/apache/catalina/core/ApplicationPart.java | 2 +-
.../tomcat/util/http/fileupload/FileItem.java | 8 +-
.../tomcat/util/http/fileupload/FileUpload.java | 2 +-
.../util/http/fileupload/FileUploadBase.java | 18 +---
.../util/http/fileupload/MultipartStream.java | 4 +-
.../util/http/fileupload/ParameterParser.java | 12 +--
.../util/http/fileupload/disk/DiskFileItem.java | 116 ++++++++++-----------
.../http/fileupload/impl/FileItemIteratorImpl.java | 22 +++-
.../http/fileupload/impl/FileItemStreamImpl.java | 29 +++---
.../ParseException.java => impl/package-info.java} | 21 +---
.../http/fileupload/servlet/ServletFileUpload.java | 2 +-
.../http/fileupload/util/FileItemHeadersImpl.java | 6 +-
.../tomcat/util/http/fileupload/util/Streams.java | 16 +--
.../http/fileupload/util/mime/MimeUtility.java | 35 ++++---
.../http/fileupload/util/mime/ParseException.java | 2 +-
.../util/mime/QuotedPrintableDecoder.java | 3 +-
.../http/fileupload/util/mime/RFC2231Utility.java | 44 ++++++--
webapps/docs/changelog.xml | 4 +
20 files changed, 176 insertions(+), 175 deletions(-)
diff --git a/MERGE.txt b/MERGE.txt
index 7b10d6a..73ecd41 100644
--- a/MERGE.txt
+++ b/MERGE.txt
@@ -51,7 +51,7 @@ FileUpload
Sub-tree:
src/main/java/org/apache/commons/fileupload2
The SHA1 ID / tag for the most recent commit to be merged to Tomcat is:
-ee0a7131b6b87586b28542de354951414dedac3f (2021-01-15)
+33d2d79230bb851642435821b380904d24752ee1 (2021-09-01)
Note: Tomcat's copy of fileupload also includes classes copied manually from
Commons IO.
diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
index e1a0e77..40445e0 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -107,7 +107,6 @@ import org.apache.tomcat.util.http.Parameters.FailReason;
import org.apache.tomcat.util.http.ServerCookie;
import org.apache.tomcat.util.http.ServerCookies;
import org.apache.tomcat.util.http.fileupload.FileItem;
-import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.impl.InvalidContentTypeException;
import org.apache.tomcat.util.http.fileupload.impl.SizeException;
@@ -2962,7 +2961,7 @@ public class Request implements HttpServletRequest {
parameters.setParseFailedReason(FailReason.POST_TOO_LARGE);
checkSwallowInput();
partsParseException = new IllegalStateException(e);
- } catch (FileUploadException e) {
+ } catch (IOException e) {
parameters.setParseFailedReason(FailReason.IO_ERROR);
partsParseException = new IOException(e);
} catch (IllegalStateException e) {
diff --git a/java/org/apache/catalina/core/ApplicationPart.java b/java/org/apache/catalina/core/ApplicationPart.java
index d6400b5..5c6cc0c 100644
--- a/java/org/apache/catalina/core/ApplicationPart.java
+++ b/java/org/apache/catalina/core/ApplicationPart.java
@@ -123,7 +123,7 @@ public class ApplicationPart implements Part {
}
}
- public String getString(String encoding) throws UnsupportedEncodingException {
+ public String getString(String encoding) throws UnsupportedEncodingException, IOException {
return fileItem.getString(encoding);
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/FileItem.java b/java/org/apache/tomcat/util/http/fileupload/FileItem.java
index 29aa496..d1e0523 100644
--- a/java/org/apache/tomcat/util/http/fileupload/FileItem.java
+++ b/java/org/apache/tomcat/util/http/fileupload/FileItem.java
@@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UncheckedIOException;
import java.io.UnsupportedEncodingException;
/**
@@ -104,8 +105,10 @@ public interface FileItem extends FileItemHeadersSupport {
* Returns the contents of the file item as an array of bytes.
*
* @return The contents of the file item as an array of bytes.
+ *
+ * @throws UncheckedIOException if an I/O error occurs
*/
- byte[] get();
+ byte[] get() throws UncheckedIOException;
/**
* Returns the contents of the file item as a String, using the specified
@@ -118,8 +121,9 @@ public interface FileItem extends FileItemHeadersSupport {
*
* @throws UnsupportedEncodingException if the requested character
* encoding is not available.
+ * @throws IOException if an I/O error occurs
*/
- String getString(String encoding) throws UnsupportedEncodingException;
+ String getString(String encoding) throws UnsupportedEncodingException, IOException;
/**
* Returns the contents of the file item as a String, using the default
diff --git a/java/org/apache/tomcat/util/http/fileupload/FileUpload.java b/java/org/apache/tomcat/util/http/fileupload/FileUpload.java
index 9be9caa..f0cfebc 100644
--- a/java/org/apache/tomcat/util/http/fileupload/FileUpload.java
+++ b/java/org/apache/tomcat/util/http/fileupload/FileUpload.java
@@ -43,7 +43,7 @@ public class FileUpload
// ----------------------------------------------------------- Constructors
/**
- * Constructs an uninitialised instance of this class.
+ * Constructs an uninitialized instance of this class.
*
* A factory must be
* configured, using {@code setFileItemFactory()}, before attempting
diff --git a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
index 30a582c..7d678c2 100644
--- a/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
+++ b/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java
@@ -26,7 +26,6 @@ import java.util.Map;
import java.util.Objects;
import org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl;
-import org.apache.tomcat.util.http.fileupload.impl.FileItemStreamImpl;
import org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException;
import org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException;
import org.apache.tomcat.util.http.fileupload.util.FileItemHeadersImpl;
@@ -70,10 +69,7 @@ public abstract class FileUploadBase {
if (contentType == null) {
return false;
}
- if (contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART)) {
- return true;
- }
- return false;
+ return contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART);
}
// ----------------------------------------------------- Manifest constants
@@ -278,12 +274,13 @@ public abstract class FileUploadBase {
boolean successful = false;
try {
final FileItemIterator iter = getItemIterator(ctx);
- final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(), "No FileItemFactory has been set.");
+ final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(),
+ "No FileItemFactory has been set.");
final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE];
while (iter.hasNext()) {
final FileItemStream item = iter.next();
// Don't use getName() here to prevent an InvalidFileNameException.
- final String fileName = ((FileItemStreamImpl) item).getName();
+ final String fileName = item.getName();
final FileItem fileItem = fileItemFactory.createItem(item.getFieldName(), item.getContentType(),
item.isFormField(), fileName);
items.add(fileItem);
@@ -337,12 +334,7 @@ public abstract class FileUploadBase {
for (final FileItem fileItem : items) {
final String fieldName = fileItem.getFieldName();
- List<FileItem> mappedItems = itemsMap.get(fieldName);
-
- if (mappedItems == null) {
- mappedItems = new ArrayList<>();
- itemsMap.put(fieldName, mappedItems);
- }
+ List<FileItem> mappedItems = itemsMap.computeIfAbsent(fieldName, k -> new ArrayList<>());
mappedItems.add(fileItem);
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java b/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
index 595a975..ab6e8e5 100644
--- a/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
+++ b/java/org/apache/tomcat/util/http/fileupload/MultipartStream.java
@@ -401,7 +401,7 @@ public class MultipartStream {
public boolean readBoundary()
throws FileUploadIOException, MalformedStreamException {
final byte[] marker = new byte[2];
- boolean nextChunk = false;
+ boolean nextChunk;
head += boundaryLength;
try {
@@ -532,7 +532,7 @@ public class MultipartStream {
baos.write(b);
}
- String headers = null;
+ String headers;
if (headerEncoding != null) {
try {
headers = baos.toString(headerEncoding);
diff --git a/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java b/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java
index d5b90c2..91a97ae 100644
--- a/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java
+++ b/java/org/apache/tomcat/util/http/fileupload/ParameterParser.java
@@ -233,8 +233,8 @@ public class ParameterParser {
char separator = separators[0];
if (str != null) {
int idx = str.length();
- for (char separator2 : separators) {
- int tmp = str.indexOf(separator2);
+ for (final char separator2 : separators) {
+ final int tmp = str.indexOf(separator2);
if (tmp != -1 && tmp < idx) {
idx = tmp;
separator = separator2;
@@ -299,12 +299,12 @@ public class ParameterParser {
return new HashMap<>();
}
final HashMap<String, String> params = new HashMap<>();
- this.chars = charArray;
+ this.chars = charArray.clone();
this.pos = offset;
this.len = length;
- String paramName = null;
- String paramValue = null;
+ String paramName;
+ String paramValue;
while (hasChar()) {
paramName = parseToken(new char[] {
'=', separator });
@@ -326,7 +326,7 @@ public class ParameterParser {
if (hasChar() && (charArray[pos] == separator)) {
pos++; // skip separator
}
- if ((paramName != null) && (paramName.length() > 0)) {
+ if ((paramName != null) && !paramName.isEmpty()) {
paramName = RFC2231Utility.stripDelimiter(paramName);
if (this.lowerCaseNames) {
paramName = paramName.toLowerCase(Locale.ENGLISH);
diff --git a/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java b/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
index 2f2c25d..4dcc3d9 100644
--- a/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
+++ b/java/org/apache/tomcat/util/http/fileupload/disk/DiskFileItem.java
@@ -25,7 +25,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.io.UncheckedIOException;
import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
@@ -191,7 +193,7 @@ public class DiskFileItem
public InputStream getInputStream()
throws IOException {
if (!isInMemory()) {
- return new FileInputStream(dfos.getFile());
+ return Files.newInputStream(dfos.getFile().toPath());
}
if (cachedContent == null) {
@@ -268,13 +270,14 @@ public class DiskFileItem
public long getSize() {
if (size >= 0) {
return size;
- } else if (cachedContent != null) {
+ }
+ if (cachedContent != null) {
return cachedContent.length;
- } else if (dfos.isInMemory()) {
+ }
+ if (dfos.isInMemory()) {
return dfos.getData().length;
- } else {
- return dfos.getFile().length();
}
+ return dfos.getFile().length();
}
/**
@@ -284,28 +287,25 @@ public class DiskFileItem
*
* @return The contents of the file as an array of bytes
* or {@code null} if the data cannot be read
+ *
+ * @throws UncheckedIOException if an I/O error occurs
*/
@Override
- public byte[] get() {
+ public byte[] get() throws UncheckedIOException {
if (isInMemory()) {
if (cachedContent == null && dfos != null) {
cachedContent = dfos.getData();
}
- return cachedContent;
+ return cachedContent != null ? cachedContent.clone() : new byte[0];
}
byte[] fileData = new byte[(int) getSize()];
- InputStream fis = null;
- try {
- fis = new FileInputStream(dfos.getFile());
+ try (InputStream fis = Files.newInputStream(dfos.getFile().toPath())) {
IOUtils.readFully(fis, fileData);
- } catch (final IOException e) {
- fileData = null;
- } finally {
- IOUtils.closeQuietly(fis);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
}
-
return fileData;
}
@@ -323,7 +323,7 @@ public class DiskFileItem
*/
@Override
public String getString(final String charset)
- throws UnsupportedEncodingException {
+ throws UnsupportedEncodingException, IOException {
return new String(get(), charset);
}
@@ -338,15 +338,15 @@ public class DiskFileItem
*/
@Override
public String getString() {
- final byte[] rawdata = get();
- String charset = getCharSet();
- if (charset == null) {
- charset = defaultCharset;
- }
try {
- return new String(rawdata, charset);
- } catch (final UnsupportedEncodingException e) {
- return new String(rawdata);
+ byte[] rawData = get();
+ String charset = getCharSet();
+ if (charset == null) {
+ charset = defaultCharset;
+ }
+ return new String(rawData, charset);
+ } catch (final IOException e) {
+ return new String(new byte[0]);
}
}
@@ -373,46 +373,14 @@ public class DiskFileItem
@Override
public void write(final File file) throws Exception {
if (isInMemory()) {
- FileOutputStream fout = null;
- try {
- fout = new FileOutputStream(file);
+ try (OutputStream fout = Files.newOutputStream(file.toPath())) {
fout.write(get());
- fout.close();
- } finally {
- IOUtils.closeQuietly(fout);
+ } catch (IOException e) {
+ throw new IOException("Unexpected output data");
}
} else {
final File outputFile = getStoreLocation();
- if (outputFile != null) {
- // Save the length of the file
- size = outputFile.length();
- /*
- * The uploaded file is being stored on disk
- * in a temporary location so move it to the
- * desired file.
- */
- if (file.exists()) {
- if (!file.delete()) {
- throw new FileUploadException(
- "Cannot write uploaded file to disk!");
- }
- }
- if (!outputFile.renameTo(file)) {
- BufferedInputStream in = null;
- BufferedOutputStream out = null;
- try {
- in = new BufferedInputStream(
- new FileInputStream(outputFile));
- out = new BufferedOutputStream(
- new FileOutputStream(file));
- IOUtils.copy(in, out);
- out.close();
- } finally {
- IOUtils.closeQuietly(in);
- IOUtils.closeQuietly(out);
- }
- }
- } else {
+ if (outputFile == null) {
/*
* For whatever reason we cannot write the
* file to disk.
@@ -420,6 +388,30 @@ public class DiskFileItem
throw new FileUploadException(
"Cannot write uploaded file to disk!");
}
+ // Save the length of the file
+ size = outputFile.length();
+ /*
+ * The uploaded file is being stored on disk
+ * in a temporary location so move it to the
+ * desired file.
+ */
+ if (file.exists() && !file.delete()) {
+ throw new FileUploadException(
+ "Cannot write uploaded file to disk!");
+ }
+ if (!outputFile.renameTo(file)) {
+ BufferedInputStream in = null;
+ BufferedOutputStream out = null;
+ try {
+ in = new BufferedInputStream(new FileInputStream(outputFile));
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ IOUtils.copy(in, out);
+ out.close();
+ } finally {
+ IOUtils.closeQuietly(in);
+ IOUtils.closeQuietly(out);
+ }
+ }
}
}
@@ -503,11 +495,9 @@ public class DiskFileItem
* @return An {@link java.io.OutputStream OutputStream} that can be used
* for storing the contents of the file.
*
- * @throws IOException if an error occurs.
*/
@Override
- public OutputStream getOutputStream()
- throws IOException {
+ public OutputStream getOutputStream() {
if (dfos == null) {
final File outputFile = getTempFile();
dfos = new DeferredFileOutputStream(sizeThreshold, outputFile);
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java
index 6e2d574..29e89f6 100644
--- a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemIteratorImpl.java
@@ -42,9 +42,24 @@ import org.apache.tomcat.util.http.fileupload.util.LimitedInputStream;
* {@link FileUploadBase#getItemIterator(RequestContext)}.
*/
public class FileItemIteratorImpl implements FileItemIterator {
+ /**
+ * The file uploads processing utility.
+ * @see FileUploadBase
+ */
private final FileUploadBase fileUploadBase;
+ /**
+ * The request context.
+ * @see RequestContext
+ */
private final RequestContext ctx;
- private long sizeMax, fileSizeMax;
+ /**
+ * The maximum allowed size of a complete request.
+ */
+ private long sizeMax;
+ /**
+ * The maximum allowed size of a single uploaded file.
+ */
+ private long fileSizeMax;
@Override
@@ -326,10 +341,11 @@ public class FileItemIteratorImpl implements FileItemIterator {
final List<FileItem> items = new ArrayList<>();
while (hasNext()) {
final FileItemStream fis = next();
- final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(), fis.getContentType(), fis.isFormField(), fis.getName());
+ final FileItem fi = fileUploadBase.getFileItemFactory().createItem(fis.getFieldName(),
+ fis.getContentType(), fis.isFormField(), fis.getName());
items.add(fi);
}
return items;
}
-}
\ No newline at end of file
+}
diff --git a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java
index dd02e6d..bab5d98 100644
--- a/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/FileItemStreamImpl.java
@@ -33,6 +33,11 @@ import org.apache.tomcat.util.http.fileupload.util.Streams;
* Default implementation of {@link FileItemStream}.
*/
public class FileItemStreamImpl implements FileItemStream {
+ /**
+ * The File Item iterator implementation.
+ *
+ * @see FileItemIteratorImpl
+ */
private final FileItemIteratorImpl fileItemIteratorImpl;
/**
@@ -48,7 +53,7 @@ public class FileItemStreamImpl implements FileItemStream {
/**
* The file items file name.
*/
- final String name;
+ private final String name;
/**
* Whether the file item is a form field.
@@ -87,18 +92,16 @@ public class FileItemStreamImpl implements FileItemStream {
contentType = pContentType;
formField = pFormField;
final long fileSizeMax = fileItemIteratorImpl.getFileSizeMax();
- if (fileSizeMax != -1) { // Check if limit is already exceeded
- if (pContentLength != -1
- && pContentLength > fileSizeMax) {
- final FileSizeLimitExceededException e =
- new FileSizeLimitExceededException(
- String.format("The field %s exceeds its maximum permitted size of %s bytes.",
- fieldName, Long.valueOf(fileSizeMax)),
- pContentLength, fileSizeMax);
- e.setFileName(pName);
- e.setFieldName(pFieldName);
- throw new FileUploadIOException(e);
- }
+ if (fileSizeMax != -1 && pContentLength != -1
+ && pContentLength > fileSizeMax) {
+ final FileSizeLimitExceededException e =
+ new FileSizeLimitExceededException(
+ String.format("The field %s exceeds its maximum permitted size of %s bytes.",
+ fieldName, Long.valueOf(fileSizeMax)),
+ pContentLength, fileSizeMax);
+ e.setFileName(pName);
+ e.setFieldName(pFieldName);
+ throw new FileUploadIOException(e);
}
// OK to construct stream now
final ItemInputStream itemStream = fileItemIteratorImpl.getMultiPartStream().newInputStream();
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java b/java/org/apache/tomcat/util/http/fileupload/impl/package-info.java
similarity index 62%
copy from java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java
copy to java/org/apache/tomcat/util/http/fileupload/impl/package-info.java
index ea102a9..134a3f6 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java
+++ b/java/org/apache/tomcat/util/http/fileupload/impl/package-info.java
@@ -14,25 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.tomcat.util.http.fileupload.util.mime;
/**
- * @since 1.3
+ * Implementations and exceptions utils.
*/
-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(final String message) {
- super(message);
- }
-
-}
+package org.apache.tomcat.util.http.fileupload.impl;
diff --git a/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java b/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java
index 98dec64..268bad8 100644
--- a/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java
+++ b/java/org/apache/tomcat/util/http/fileupload/servlet/ServletFileUpload.java
@@ -73,7 +73,7 @@ public class ServletFileUpload extends FileUpload {
// ----------------------------------------------------------- Constructors
/**
- * Constructs an uninitialised instance of this class. A factory must be
+ * Constructs an uninitialized instance of this class. A factory must be
* configured, using {@code setFileItemFactory()}, before attempting
* to parse requests.
*
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/FileItemHeadersImpl.java b/java/org/apache/tomcat/util/http/fileupload/util/FileItemHeadersImpl.java
index 1047dc3..ebf1fec 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/FileItemHeadersImpl.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/FileItemHeadersImpl.java
@@ -87,11 +87,7 @@ public class FileItemHeadersImpl implements FileItemHeaders, Serializable {
*/
public synchronized void addHeader(final String name, final String value) {
final String nameLower = name.toLowerCase(Locale.ENGLISH);
- List<String> headerValueList = headerNameToValueListMap.get(nameLower);
- if (null == headerValueList) {
- headerValueList = new ArrayList<>();
- headerNameToValueListMap.put(nameLower, headerValueList);
- }
+ List<String> headerValueList = headerNameToValueListMap.computeIfAbsent(nameLower, k -> new ArrayList<>());
headerValueList.add(value);
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/Streams.java b/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
index 1ba6106..03c1f90 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/Streams.java
@@ -21,7 +21,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.apache.tomcat.util.http.fileupload.InvalidFileNameException;
/**
@@ -63,7 +62,8 @@ public final class Streams {
* @return Number of bytes, which have been copied.
* @throws IOException An I/O error occurred.
*/
- public static long copy(final InputStream inputStream, final OutputStream outputStream, final boolean closeOutputStream)
+ public static long copy(final InputStream inputStream, final OutputStream outputStream,
+ final boolean closeOutputStream)
throws IOException {
return copy(inputStream, outputStream, closeOutputStream, new byte[DEFAULT_BUFFER_SIZE]);
}
@@ -90,9 +90,8 @@ public final class Streams {
final OutputStream outputStream, final boolean closeOutputStream,
final byte[] buffer)
throws IOException {
- OutputStream out = outputStream;
- InputStream in = inputStream;
- try {
+ try (OutputStream out = outputStream;
+ InputStream in = inputStream) {
long total = 0;
for (;;) {
final int res = in.read(buffer);
@@ -112,16 +111,9 @@ public final class Streams {
} else {
out.flush();
}
- out = null;
}
in.close();
- in = null;
return total;
- } finally {
- IOUtils.closeQuietly(in);
- if (closeOutputStream) {
- IOUtils.closeQuietly(out);
- }
}
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java b/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java
index a4da181..70a4fb3 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/mime/MimeUtility.java
@@ -19,6 +19,7 @@ package org.apache.tomcat.util.http.fileupload.util.mime;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -33,11 +34,6 @@ import org.apache.tomcat.util.codec.binary.Base64;
public final class MimeUtility {
/**
- * The {@code US-ASCII} charset identifier constant.
- */
- private static final String US_ASCII_CHARSET = "US-ASCII";
-
- /**
* The marker to indicate text is encoded with BASE64 algorithm.
*/
private static final String BASE64_ENCODING_MARKER = "B";
@@ -68,8 +64,15 @@ public final class MimeUtility {
private static final Map<String, String> MIME2JAVA = new HashMap<>();
static {
+ MIME2JAVA.put("iso-2022-cn", "ISO2022CN");
+ MIME2JAVA.put("iso-2022-kr", "ISO2022KR");
+ MIME2JAVA.put("utf-8", "UTF8");
+ MIME2JAVA.put("utf8", "UTF8");
MIME2JAVA.put("ja_jp.iso2022-7", "ISO2022JP");
MIME2JAVA.put("ja_jp.eucjp", "EUCJIS");
+ MIME2JAVA.put("euc-kr", "KSC5601");
+ MIME2JAVA.put("euckr", "KSC5601");
+ MIME2JAVA.put("us-ascii", "ISO-8859-1");
MIME2JAVA.put("x-us-ascii", "ISO-8859-1");
}
@@ -117,14 +120,13 @@ public final class MimeUtility {
while (offset < endOffset) {
// step over the white space characters.
ch = text.charAt(offset);
- if (LINEAR_WHITESPACE.indexOf(ch) != -1) { // whitespace found
- offset++;
- } else {
+ if (LINEAR_WHITESPACE.indexOf(ch) == -1) {
// record the location of the first non lwsp and drop down to process the
// token characters.
endWhiteSpace = offset;
break;
}
+ offset++;
}
} else {
// we have a word token. We need to scan over the word and then try to parse it.
@@ -133,11 +135,10 @@ public final class MimeUtility {
while (offset < endOffset) {
// step over the non white space characters.
ch = text.charAt(offset);
- if (LINEAR_WHITESPACE.indexOf(ch) == -1) { // not white space
- offset++;
- } else {
+ if (LINEAR_WHITESPACE.indexOf(ch) != -1) {
break;
}
+ offset++;
//NB: Trailing whitespace on these header strings will just be discarded.
}
@@ -151,7 +152,7 @@ public final class MimeUtility {
// are any whitespace characters significant? Append 'em if we've got 'em.
if (!previousTokenEncoded && startWhiteSpace != -1) {
- decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));
+ decodedText.append(text, startWhiteSpace, endWhiteSpace);
startWhiteSpace = -1;
}
// this is definitely a decoded token.
@@ -169,7 +170,7 @@ public final class MimeUtility {
// this is a normal token, so it doesn't matter what the previous token was. Add the white space
// if we have it.
if (startWhiteSpace != -1) {
- decodedText.append(text.substring(startWhiteSpace, endWhiteSpace));
+ decodedText.append(text, startWhiteSpace, endWhiteSpace);
startWhiteSpace = -1;
}
// this is not a decoded token.
@@ -190,8 +191,8 @@ public final class MimeUtility {
* @param word The possibly encoded word value.
*
* @return The decoded word.
- * @throws ParseException
- * @throws UnsupportedEncodingException
+ * @throws ParseException in case of a parse error of the RFC 2047
+ * @throws UnsupportedEncodingException Thrown when Invalid RFC 2047 encoding was found
*/
private static String decodeWord(final String word) throws ParseException, UnsupportedEncodingException {
// encoded words start with the characters "=?". If this not an encoded word, we throw a
@@ -226,7 +227,7 @@ public final class MimeUtility {
final String encodedText = word.substring(encodingPos + 1, encodedTextPos);
// seems a bit silly to encode a null string, but easy to deal with.
- if (encodedText.length() == 0) {
+ if (encodedText.isEmpty()) {
return "";
}
@@ -239,7 +240,7 @@ public final class MimeUtility {
if (encoding.equals(BASE64_ENCODING_MARKER)) {
decodedData = Base64.decodeBase64(encodedText);
} else if (encoding.equals(QUOTEDPRINTABLE_ENCODING_MARKER)) { // maybe quoted printable.
- byte[] encodedData = encodedText.getBytes(US_ASCII_CHARSET);
+ byte[] encodedData = encodedText.getBytes(StandardCharsets.US_ASCII);
QuotedPrintableDecoder.decode(encodedData, out);
decodedData = out.toByteArray();
} else {
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java b/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java
index ea102a9..bf31a53 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/mime/ParseException.java
@@ -31,7 +31,7 @@ final class ParseException extends Exception {
*
* @param message the detail message.
*/
- public ParseException(final String message) {
+ ParseException(final String message) {
super(message);
}
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java b/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java
index b7a75de..3a563b9 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/mime/QuotedPrintableDecoder.java
@@ -44,8 +44,7 @@ final class QuotedPrintableDecoder {
* @param out The output stream used to return the decoded data.
*
* @return the number of bytes produced.
- * @throws IOException if a problem occurs during either decoding or
- * writing to the stream
+ * @throws IOException if an IO error occurs
*/
public static int decode(final byte[] data, final OutputStream out) throws IOException {
int off = 0;
diff --git a/java/org/apache/tomcat/util/http/fileupload/util/mime/RFC2231Utility.java b/java/org/apache/tomcat/util/http/fileupload/util/mime/RFC2231Utility.java
index 99333f4..c15bb20 100644
--- a/java/org/apache/tomcat/util/http/fileupload/util/mime/RFC2231Utility.java
+++ b/java/org/apache/tomcat/util/http/fileupload/util/mime/RFC2231Utility.java
@@ -22,7 +22,8 @@ import java.io.UnsupportedEncodingException;
* Utility class to decode/encode character set on HTTP Header fields based on RFC 2231.
* This implementation adheres to RFC 5987 in particular, which was defined for HTTP headers
*
- * RFC 5987 builds on RFC 2231, but has lesser scope like <a href="https://tools.ietf.org/html/rfc5987#section-3.2">mandatory charset definition</a>
+ * RFC 5987 builds on RFC 2231, but has lesser scope like
+ * <a href="https://tools.ietf.org/html/rfc5987#section-3.2">mandatory charset definition</a>
* and <a href="https://tools.ietf.org/html/rfc5987#section-4">no parameter continuation</a>
*
* <p>
@@ -30,10 +31,22 @@ import java.io.UnsupportedEncodingException;
* @see <a href="https://tools.ietf.org/html/rfc5987">RFC 5987</a>
*/
public final class RFC2231Utility {
-
+ /**
+ * The Hexadecimal values char array.
+ */
private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
-
- private static final byte[] HEX_DECODE = new byte[0x80];
+ /**
+ * The Hexadecimal representation of 127.
+ */
+ private static final byte MASK = 0x7f;
+ /**
+ * The Hexadecimal representation of 128.
+ */
+ private static final int MASK_128 = 0x80;
+ /**
+ * The Hexadecimal decode value.
+ */
+ private static final byte[] HEX_DECODE = new byte[MASK_128];
// create a ASCII decoded array of Hexadecimal values
static {
@@ -44,8 +57,15 @@ public final class RFC2231Utility {
}
/**
+ * Private constructor so that no instances can be created. This class
+ * contains only static utility methods.
+ */
+ private RFC2231Utility() {
+ }
+
+ /**
* Checks if Asterisk (*) at the end of parameter name to indicate,
- * if it has charset and language information to decode the value
+ * if it has charset and language information to decode the value.
* @param paramName The parameter, which is being checked.
* @return {@code true}, if encoded as per RFC 2231, {@code false} otherwise
*/
@@ -58,7 +78,7 @@ public final class RFC2231Utility {
/**
* If {@code paramName} has Asterisk (*) at the end, it will be stripped off,
- * else the passed value will be returned
+ * else the passed value will be returned.
* @param paramName The parameter, which is being inspected.
* @return stripped {@code paramName} of Asterisk (*), if RFC2231 encoded
*/
@@ -83,7 +103,8 @@ public final class RFC2231Utility {
* <b>Eg 3.</b> {@code UTF-8''%c2%a3%20and%20%e2%82%ac%20rates}
* will be decoded to {@code £ and € rates}.
*
- * @param encodedText - Text to be decoded has a format of {@code <charset>'<language>'<encoded_value>} and ASCII only
+ * @param encodedText - Text to be decoded has a format of {@code <charset>'<language>'<encoded_value>}
+ * and ASCII only
* @return Decoded text based on charset encoding
* @throws UnsupportedEncodingException The requested character set wasn't found.
*/
@@ -104,11 +125,12 @@ public final class RFC2231Utility {
}
/**
- * Convert {@code text} to their corresponding Hex value
+ * Convert {@code text} to their corresponding Hex value.
* @param text - ASCII text input
* @return Byte array of characters decoded from ASCII table
*/
private static byte[] fromHex(final String text) {
+ final int shift = 4;
final ByteArrayOutputStream out = new ByteArrayOutputStream(text.length());
for (int i = 0; i < text.length();) {
final char c = text.charAt(i++);
@@ -116,9 +138,9 @@ public final class RFC2231Utility {
if (i > text.length() - 2) {
break; // unterminated sequence
}
- final byte b1 = HEX_DECODE[text.charAt(i++) & 0x7f];
- final byte b2 = HEX_DECODE[text.charAt(i++) & 0x7f];
- out.write((b1 << 4) | b2);
+ final byte b1 = HEX_DECODE[text.charAt(i++) & MASK];
+ final byte b2 = HEX_DECODE[text.charAt(i++) & MASK];
+ out.write((b1 << shift) | b2);
} else {
out.write((byte) c);
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index abb2055..cf33647 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -211,6 +211,10 @@
Add Apache Derby 10.14.2.0 to the testsuite dependencies, for JDBC
and DataSource testing. (remm)
</update>
+ <add>
+ Update the internal fork of Apache Commons FileUpload to 33d2d79
+ (2021-09-01, 2.0-SNAPSHOT). Refactoring and code clean-up. (markt)
+ </add>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org