You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2023/06/11 21:33:15 UTC
[commons-fileupload] 03/04: Use Charset instead of String
This is an automated email from the ASF dual-hosted git repository.
ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-fileupload.git
commit c2f45e91d9b03646ba9a29a25b9d1625dac5237c
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Jun 11 17:20:52 2023 -0400
Use Charset instead of String
Update internal names
---
.../commons/fileupload2/AbstractFileUpload.java | 15 +++----
.../commons/fileupload2/FileItemInputImpl.java | 2 +-
.../fileupload2/FileItemInputIteratorImpl.java | 48 +++++++++++-----------
.../apache/commons/fileupload2/MultipartInput.java | 47 +++++++++------------
.../commons/fileupload2/ParameterParser.java | 6 +--
.../apache/commons/fileupload2/RequestContext.java | 14 +++++++
6 files changed, 68 insertions(+), 64 deletions(-)
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/AbstractFileUpload.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/AbstractFileUpload.java
index e0e0085..3b533a7 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/AbstractFileUpload.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/AbstractFileUpload.java
@@ -19,6 +19,7 @@ package org.apache.commons.fileupload2;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
@@ -118,7 +119,7 @@ public abstract class AbstractFileUpload {
/**
* The content encoding to use when reading part headers.
*/
- private String headerEncoding;
+ private Charset headerCharset;
/**
* The progress listener.
@@ -160,7 +161,7 @@ public abstract class AbstractFileUpload {
* Gets the field name, which is given by the content-disposition header.
*
* @param contentDisposition The content-dispositions header value.
- * @return The field jake
+ * @return The field name.
*/
private String getFieldName(final String contentDisposition) {
String fieldName = null;
@@ -251,8 +252,8 @@ public abstract class AbstractFileUpload {
*
* @return The encoding used to read part headers.
*/
- public String getHeaderEncoding() {
- return headerEncoding;
+ public Charset getHeaderCharset() {
+ return headerCharset;
}
/**
@@ -488,10 +489,10 @@ public abstract class AbstractFileUpload {
* Specifies the character encoding to be used when reading the headers of individual part. When not specified, or {@code null}, the request encoding is
* used. If that is also not specified, or {@code null}, the platform default encoding is used.
*
- * @param encoding The encoding used to read part headers.
+ * @param headerCharset The encoding used to read part headers.
*/
- public void setHeaderEncoding(final String encoding) {
- headerEncoding = encoding;
+ public void setHeaderCharset(final Charset headerCharset) {
+ this.headerCharset = headerCharset;
}
/**
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputImpl.java
index a559fb6..dababa3 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputImpl.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputImpl.java
@@ -96,7 +96,7 @@ class FileItemInputImpl implements FileItemInput {
contentLength, fileSizeMax, fileName, fieldName);
}
// OK to construct stream now
- final ItemInputStream itemInputStream = fileItemInputIteratorImpl.getMultiPartStream().newInputStream();
+ final ItemInputStream itemInputStream = fileItemInputIteratorImpl.getMultiPartInput().newInputStream();
InputStream istream = itemInputStream;
if (fileSizeMax != -1) {
istream = new BoundedInputStream(istream, fileSizeMax) {
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputIteratorImpl.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputIteratorImpl.java
index 2b6dc7a..5156035 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputIteratorImpl.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/FileItemInputIteratorImpl.java
@@ -18,12 +18,14 @@ package org.apache.commons.fileupload2;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Objects;
+import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BoundedInputStream;
@@ -44,7 +46,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
*
* @see RequestContext
*/
- private final RequestContext ctx;
+ private final RequestContext requestContext;
/**
* The maximum allowed size of a complete request.
@@ -59,7 +61,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
/**
* The multi part stream to process.
*/
- private MultipartInput multiPartStream;
+ private MultipartInput multiPartInput;
/**
* The notifier, which used for triggering the {@link ProgressListener}.
@@ -108,7 +110,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
this.fileUpload = fileUploadBase;
this.sizeMax = fileUploadBase.getSizeMax();
this.fileSizeMax = fileUploadBase.getFileSizeMax();
- this.ctx = Objects.requireNonNull(requestContext, "requestContext");
+ this.requestContext = Objects.requireNonNull(requestContext, "requestContext");
this.skipPreamble = true;
findNextItem();
}
@@ -127,7 +129,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
currentItem.close();
currentItem = null;
}
- final MultipartInput multi = getMultiPartStream();
+ final MultipartInput multi = getMultiPartInput();
for (;;) {
final boolean nextPart;
if (skipPreamble) {
@@ -214,11 +216,11 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
return fileSizeMax;
}
- public MultipartInput getMultiPartStream() throws FileUploadException, IOException {
- if (multiPartStream == null) {
- init(fileUpload, ctx);
+ public MultipartInput getMultiPartInput() throws FileUploadException, IOException {
+ if (multiPartInput == null) {
+ init(fileUpload, requestContext);
}
- return multiPartStream;
+ return multiPartInput;
}
@Override
@@ -244,21 +246,21 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
return findNextItem();
}
- protected void init(final AbstractFileUpload fileUploadBase, final RequestContext requestContext) throws FileUploadException, IOException {
- final String contentType = ctx.getContentType();
+ protected void init(final AbstractFileUpload fileUploadBase, final RequestContext initContext) throws FileUploadException, IOException {
+ final String contentType = requestContext.getContentType();
if (null == contentType || !contentType.toLowerCase(Locale.ENGLISH).startsWith(AbstractFileUpload.MULTIPART)) {
throw new FileUploadContentTypeException(String.format("the request doesn't contain a %s or %s stream, content type header is %s",
AbstractFileUpload.MULTIPART_FORM_DATA, AbstractFileUpload.MULTIPART_MIXED, contentType), contentType);
}
- final long contentLengthInt = ctx.getContentLength();
+ final long contentLengthInt = requestContext.getContentLength();
// @formatter:off
- final long requestSize = RequestContext.class.isAssignableFrom(ctx.getClass())
+ final long requestSize = RequestContext.class.isAssignableFrom(requestContext.getClass())
// Inline conditional is OK here CHECKSTYLE:OFF
- ? ctx.getContentLength()
+ ? requestContext.getContentLength()
: contentLengthInt;
// CHECKSTYLE:ON
// @formatter:on
- final InputStream input; // N.B. this is eventually closed in MultipartInput processing
+ final InputStream inputStream; // N.B. this is eventually closed in MultipartInput processing
if (sizeMax >= 0) {
if (requestSize != -1 && requestSize > sizeMax) {
throw new FileUploadSizeException(
@@ -266,7 +268,7 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
requestSize);
}
// N.B. this is eventually closed in MultipartInput processing
- input = new BoundedInputStream(ctx.getInputStream(), sizeMax) {
+ inputStream = new BoundedInputStream(requestContext.getInputStream(), sizeMax) {
@Override
protected void onMaxLength(final long maxLen, final long count) throws IOException {
throw new FileUploadSizeException(
@@ -274,28 +276,24 @@ class FileItemInputIteratorImpl implements FileItemInputIterator {
}
};
} else {
- input = ctx.getInputStream();
- }
-
- String charEncoding = fileUploadBase.getHeaderEncoding();
- if (charEncoding == null) {
- charEncoding = ctx.getCharacterEncoding();
+ inputStream = requestContext.getInputStream();
}
+ final Charset charset = Charsets.toCharset(fileUploadBase.getHeaderCharset(), requestContext.getCharset());
multiPartBoundary = fileUploadBase.getBoundary(contentType);
if (multiPartBoundary == null) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
+ IOUtils.closeQuietly(inputStream); // avoid possible resource leak
throw new FileUploadException("the request was rejected because no multipart boundary was found");
}
progressNotifier = new MultipartInput.ProgressNotifier(fileUploadBase.getProgressListener(), requestSize);
try {
- multiPartStream = MultipartInput.builder().setInputStream(input).setBoundary(multiPartBoundary).setProgressNotifier(progressNotifier).get();
+ multiPartInput = MultipartInput.builder().setInputStream(inputStream).setBoundary(multiPartBoundary).setProgressNotifier(progressNotifier).get();
} catch (final IllegalArgumentException e) {
- IOUtils.closeQuietly(input); // avoid possible resource leak
+ IOUtils.closeQuietly(inputStream); // avoid possible resource leak
throw new FileUploadContentTypeException(String.format("The boundary specified in the %s header is too long", AbstractFileUpload.CONTENT_TYPE), e);
}
- multiPartStream.setHeaderEncoding(charEncoding);
+ multiPartInput.setHeaderCharset(charset);
}
/**
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartInput.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartInput.java
index 827fae3..6f79dcf 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartInput.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/MultipartInput.java
@@ -24,6 +24,7 @@ import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import org.apache.commons.fileupload2.FileItemInput.ItemSkippedException;
+import org.apache.commons.io.Charsets;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.build.AbstractOrigin;
import org.apache.commons.io.build.AbstractStreamBuilder;
@@ -531,32 +532,32 @@ public final class MultipartInput {
/**
* The maximum length of {@code header-part} that will be processed (10 kilobytes = 10240 bytes.).
*/
- public static final int HEADER_PART_SIZE_MAX = 10240;
+ public static final int HEADER_PART_SIZE_MAX = 10_240;
/**
* The default length of the buffer used for processing a request.
*/
- protected static final int DEFAULT_BUFSIZE = 4096;
+ static final int DEFAULT_BUFSIZE = 4096;
/**
* A byte sequence that marks the end of {@code header-part} ({@code CRLFCRLF}).
*/
- protected static final byte[] HEADER_SEPARATOR = { CR, LF, CR, LF };
+ 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}).
*/
- protected static final byte[] FIELD_SEPARATOR = { CR, LF };
+ static final byte[] FIELD_SEPARATOR = { CR, LF };
/**
* A byte sequence that that follows a delimiter of the last encapsulation in the stream ({@code --}).
*/
- protected static final byte[] STREAM_TERMINATOR = { DASH, DASH };
+ static final byte[] STREAM_TERMINATOR = { DASH, DASH };
/**
* A byte sequence that precedes a boundary ({@code CRLF--}).
*/
- protected static final byte[] BOUNDARY_PREFIX = { CR, LF, DASH, DASH };
+ static final byte[] BOUNDARY_PREFIX = { CR, LF, DASH, DASH };
/**
* Compares {@code count} first bytes in the arrays {@code a} and {@code b}.
@@ -566,7 +567,7 @@ public final class MultipartInput {
* @param count How many bytes should be compared.
* @return {@code true} if {@code count} first bytes in arrays {@code a} and {@code b} are equal.
*/
- public static boolean arrayEquals(final byte[] a, final byte[] b, final int count) {
+ static boolean arrayEquals(final byte[] a, final byte[] b, final int count) {
for (int i = 0; i < count; i++) {
if (a[i] != b[i]) {
return false;
@@ -634,7 +635,7 @@ public final class MultipartInput {
/**
* The content encoding to use when reading headers.
*/
- private String headerEncoding;
+ private Charset headerCharset;
/**
* The progress notifier, if any, or null.
@@ -765,8 +766,8 @@ public final class MultipartInput {
*
* @return The encoding used to read part headers.
*/
- public String getHeaderEncoding() {
- return headerEncoding;
+ public Charset getHeaderCharset() {
+ return headerCharset;
}
/**
@@ -863,9 +864,6 @@ public final class MultipartInput {
* <p>
* Headers are returned verbatim to the input stream, including the trailing {@code CRLF} marker. Parsing is left to the application.
* </p>
- * <p>
- * <strong>TODO</strong> allow limiting maximum header size to protect against abuse.
- * </p>
*
* @return The {@code header-part} of the current encapsulation.
* @throws FileUploadSizeException if the bytes read from the stream exceeded the size limits.
@@ -898,19 +896,12 @@ public final class MultipartInput {
baos.write(b);
}
- String headers;
- if (headerEncoding != null) {
- try {
- headers = baos.toString(headerEncoding);
- } catch (final UnsupportedEncodingException e) {
- // Fall back to platform default if specified encoding is not supported.
- headers = baos.toString();
- }
- } else {
- headers = baos.toString();
+ try {
+ return baos.toString(Charsets.toCharset(headerCharset, Charset.defaultCharset()).name());
+ } catch (final UnsupportedEncodingException e) {
+ // not possible
+ throw new IllegalStateException(e);
}
-
- return headers;
}
/**
@@ -940,10 +931,10 @@ public final class MultipartInput {
* Sets the character encoding to be used when reading the headers of individual parts. When not specified, or {@code null}, the platform default encoding
* is used.
*
- * @param headerEncoding The encoding used to read part headers.
+ * @param headerCharset The encoding used to read part headers.
*/
- public void setHeaderEncoding(final String headerEncoding) {
- this.headerEncoding = headerEncoding;
+ public void setHeaderCharset(final Charset headerCharset) {
+ this.headerCharset = headerCharset;
}
/**
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/ParameterParser.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
index cd65201..94e4cdd 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/ParameterParser.java
@@ -288,10 +288,10 @@ public class ParameterParser {
/**
* Sets the flag if parameter names are to be converted to lower case when name/value pairs are parsed.
*
- * @param b {@code true} if parameter names are to be converted to lower case when name/value pairs are parsed. {@code false} otherwise.
+ * @param lowerCaseNames {@code true} if parameter names are to be converted to lower case when name/value pairs are parsed. {@code false} otherwise.
*/
- public void setLowerCaseNames(final boolean b) {
- this.lowerCaseNames = b;
+ public void setLowerCaseNames(final boolean lowerCaseNames) {
+ this.lowerCaseNames = lowerCaseNames;
}
}
diff --git a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/RequestContext.java b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/RequestContext.java
index b463497..ca87751 100644
--- a/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/RequestContext.java
+++ b/commons-fileupload2-core/src/main/java/org/apache/commons/fileupload2/RequestContext.java
@@ -18,6 +18,10 @@ package org.apache.commons.fileupload2;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.UnsupportedCharsetException;
+
+import org.apache.commons.io.Charsets;
/**
* Abstracts access to the request information needed for file uploads.
@@ -34,6 +38,16 @@ public interface RequestContext {
*/
String getCharacterEncoding();
+ /**
+ * Gets the character encoding for the request.
+ *
+ * @return The character encoding for the request.
+ * @throws UnsupportedCharsetException If the named charset is unavailable (unchecked exception).
+ */
+ default Charset getCharset() throws UnsupportedCharsetException {
+ return Charsets.toCharset(getCharacterEncoding(), null);
+ }
+
/**
* Gets the content length of the request.
*