Replace LimitedInputStream with BoundedInputStream

This commit is contained in:
Gary Gregory 2023-05-18 17:52:29 -04:00
parent e055978562
commit ce16e698cb
4 changed files with 7 additions and 123 deletions

View File

@ -35,8 +35,8 @@ import org.apache.commons.fileupload2.ProgressListener;
import org.apache.commons.fileupload2.RequestContext;
import org.apache.commons.fileupload2.pub.FileUploadContentTypeException;
import org.apache.commons.fileupload2.pub.FileUploadSizeException;
import org.apache.commons.fileupload2.util.LimitedInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BoundedInputStream;
/**
* The iterator, which is returned by {@link AbstractFileUpload#getItemIterator(RequestContext)}.
@ -269,9 +269,9 @@ public class FileItemIteratorImpl implements FileItemIterator {
requestSize);
}
// N.B. this is eventually closed in MultipartStream processing
input = new LimitedInputStream(ctx.getInputStream(), sizeMax) {
input = new BoundedInputStream(ctx.getInputStream(), sizeMax) {
@Override
protected void raiseError(final long maxLen, final long count) throws IOException {
protected void onMaxLength(final long maxLen, final long count) throws IOException {
throw new FileUploadSizeException(
String.format("The request was rejected because its size (%s) exceeds the configured maximum (%s)", count, maxLen), maxLen, count);
}

View File

@ -26,7 +26,7 @@ import org.apache.commons.fileupload2.InvalidFileNameException;
import org.apache.commons.fileupload2.MultipartStream.ItemInputStream;
import org.apache.commons.fileupload2.disk.DiskFileItem;
import org.apache.commons.fileupload2.pub.FileUploadByteCountLimitException;
import org.apache.commons.fileupload2.util.LimitedInputStream;
import org.apache.commons.io.input.BoundedInputStream;
/**
* Default implementation of {@link FileItemStream}.
@ -103,9 +103,9 @@ public class FileItemStreamImpl implements FileItemStream {
final ItemInputStream itemInputStream = fileItemIteratorImpl.getMultiPartStream().newInputStream();
InputStream istream = itemInputStream;
if (fileSizeMax != -1) {
istream = new LimitedInputStream(istream, fileSizeMax) {
istream = new BoundedInputStream(istream, fileSizeMax) {
@Override
protected void raiseError(final long sizeMax, final long count) throws IOException {
protected void onMaxLength(final long sizeMax, final long count) throws IOException {
itemInputStream.close(true);
throw new FileUploadByteCountLimitException(
String.format("The field %s exceeds its maximum permitted size of %s bytes.", fieldName, sizeMax), count, sizeMax, fileName,

View File

@ -1,117 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.fileupload2.util;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* An input stream, which limits its data size. This stream is used, if the content length is unknown.
*/
public abstract class LimitedInputStream extends FilterInputStream {
/**
* The maximum size of an item, in bytes.
*/
private final long sizeMax;
/**
* The current number of bytes.
*/
private long count;
/**
* Creates a new instance.
*
* @param inputStream The input stream, which shall be limited.
* @param sizeMax The limit; no more than this number of bytes shall be returned by the source stream.
*/
public LimitedInputStream(final InputStream inputStream, final long sizeMax) {
super(inputStream);
this.sizeMax = sizeMax;
}
/**
* Called to check, whether the input streams limit is reached.
*
* @throws IOException The given limit is exceeded.
*/
private void checkLimit() throws IOException {
if (count > sizeMax) {
raiseError(sizeMax, count);
}
}
/**
* Called to indicate, that the input streams limit has been exceeded.
*
* @param sizeMax The input streams limit, in bytes.
* @param count The actual number of bytes.
* @throws IOException The called method is expected to raise an IOException.
*/
protected abstract void raiseError(long sizeMax, long count) throws IOException;
/**
* Reads the next byte of data from this input stream. The value byte is returned as an {@code int} in the range {@code 0} to {@code 255}. If no byte is
* available because the end of the stream has been reached, the value {@code -1} is returned. This method blocks until input data is available, the end of
* the stream is detected, or an exception is thrown.
* <p>
* This method simply performs {@code in.read()} and returns the result.
* </p>
*
* @return the next byte of data, or {@code -1} if the end of the stream is reached.
* @throws IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
@Override
public int read() throws IOException {
final int res = super.read();
if (res != -1) {
count++;
checkLimit();
}
return res;
}
/**
* Reads up to {@code len} bytes of data from this input stream into an array of bytes. If {@code len} is not zero, the method blocks until some input is
* available; otherwise, no bytes are read and {@code 0} is returned.
* <p>
* This method simply performs {@code in.read(b, off, len)} and returns the result.
* </p>
*
* @param b the buffer into which the data is read.
* @param off The start offset in the destination array {@code b}.
* @param len the maximum number of bytes read.
* @return the total number of bytes read into the buffer, or {@code -1} if there is no more data because the end of the stream has been reached.
* @throws NullPointerException If {@code b} is {@code null}.
* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len} is negative, or {@code len} is greater than {@code b.length - off}
* @throws IOException if an I/O error occurs.
* @see java.io.FilterInputStream#in
*/
@Override
public int read(final byte[] b, final int off, final int len) throws IOException {
final int res = super.read(b, off, len);
if (res > 0) {
count += res;
checkLimit();
}
return res;
}
}

View File

@ -73,6 +73,7 @@ The <action> type attribute can be add,update,fix,remove.
<action dev="ggregory" type="remove" due-to="Gary Gregory">Remove deprecated FileUploadBase.getHeader(Map, String).</action>
<action dev="ggregory" type="remove" due-to="Gary Gregory">Remove deprecated FileUploadBase.parseHeaders(String).</action>
<action dev="ggregory" type="remove" due-to="Gary Gregory">Replace org.apache.commons.fileupload2.util.mime.Base64Decoder with java.util.Base64.</action>
<action dev="ggregory" type="remove" due-to="Gary Gregory">Replace LimitedInputStream with BoundedInputStream.</action>
<!-- UPDATE -->
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">Bump actions/cache from 2.1.6 to 3.0.8 #128, #140.</action>
<action dev="ggregory" type="update" due-to="Dependabot, Gary Gregory">Bump actions/checkout from 2.3.4 to 3.0.2 #125.</action>