Fixes #3856 - Different behaviour with maxFormContentSize=0 if Content-Length header is present/missing.

Changes after review.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2019-07-23 22:01:13 +02:00
parent d939c9435a
commit 2629961e74
4 changed files with 53 additions and 52 deletions

View File

@ -503,51 +503,42 @@ public class Request implements HttpServletRequest
if (_context != null)
{
maxFormContentSize = _context.getContextHandler().getMaxFormContentSize();
maxFormKeys = _context.getContextHandler().getMaxFormKeys();
ContextHandler contextHandler = _context.getContextHandler();
maxFormContentSize = contextHandler.getMaxFormContentSize();
maxFormKeys = contextHandler.getMaxFormKeys();
}
if (maxFormContentSize < 0)
{
Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
if (obj == null)
maxFormContentSize = 200000;
else if (obj instanceof Number)
{
Number size = (Number)obj;
maxFormContentSize = size.intValue();
}
if (obj instanceof Number)
maxFormContentSize = ((Number)obj).intValue();
else if (obj instanceof String)
{
maxFormContentSize = Integer.parseInt((String)obj);
}
if (maxFormContentSize < 0)
maxFormContentSize = 200000;
}
if (maxFormKeys < 0)
{
Object obj = _channel.getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
if (obj == null)
maxFormKeys = 1000;
else if (obj instanceof Number)
{
Number keys = (Number)obj;
maxFormKeys = keys.intValue();
}
if (obj instanceof Number)
maxFormKeys = ((Number)obj).intValue();
else if (obj instanceof String)
{
maxFormKeys = Integer.parseInt((String)obj);
}
if (maxFormKeys < 0)
maxFormKeys = 1000;
}
int contentLength = getContentLength();
if (maxFormContentSize >= 0 && contentLength > maxFormContentSize)
throw new IllegalStateException("Form too large: " + contentLength + " > " + maxFormContentSize);
if (contentLength > maxFormContentSize)
throw new IllegalStateException("Form is larger than max length " + maxFormContentSize);
InputStream in = getInputStream();
if (_input.isAsync())
throw new IllegalStateException("Cannot extract parameters with async IO");
UrlEncoded.decodeTo(in, params, getCharacterEncoding(), contentLength < 0 ? maxFormContentSize : -1, maxFormKeys);
UrlEncoded.decodeTo(in, params, getCharacterEncoding(), maxFormContentSize, maxFormKeys);
}
catch (IOException e)
{

View File

@ -192,8 +192,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Gracefu
private Logger _logger;
private boolean _allowNullPathInfo;
private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys", -1).intValue();
private int _maxFormContentSize = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormContentSize", -1).intValue();
private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys", -1);
private int _maxFormContentSize = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormContentSize", -1);
private boolean _compactPath = false;
private boolean _usingSecurityManager = System.getSecurityManager() != null;

View File

@ -18,9 +18,7 @@
package org.eclipse.jetty.servlet;
import java.io.IOException;
import java.util.function.Function;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -90,7 +88,6 @@ public class FormTest
public void testMaxFormContentSizeZeroWithContentLength() throws Exception
{
testMaxFormContentSizeZero(true);
}
private void testMaxFormContentSizeZero(boolean addContentLength) throws Exception
@ -101,7 +98,7 @@ public class FormTest
return new HttpServlet()
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
protected void service(HttpServletRequest request, HttpServletResponse response)
{
request.getParameterMap();
}
@ -132,9 +129,10 @@ public class FormTest
start(handler ->
{
handler.setMaxFormKeys(0);
return new HttpServlet() {
return new HttpServlet()
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
protected void service(HttpServletRequest request, HttpServletResponse response)
{
request.getParameterMap();
}
@ -142,8 +140,7 @@ public class FormTest
});
Fields formParams = new Fields();
formParams.add("foo1", "bar1");
formParams.add("foo2", "bar2");
formParams.add("foo", "bar");
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.method(HttpMethod.POST)
.path(contextPath + servletPath)

View File

@ -385,15 +385,15 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
* @param in InputSteam to read
* @param map MultiMap to add parameters to
* @param maxLength maximum length of form to read
* @param maxKeys maximum number of keys to read or -1 for no limit
* @throws IOException if unable to decode inputstream as ISO8859-1
* @param maxKeys maximum number of keys to read
* @throws IOException if unable to decode InputStream as ISO8859-1
*/
public static void decode88591To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys)
throws IOException
{
synchronized (map)
{
StringBuffer buffer = new StringBuffer();
StringBuilder buffer = new StringBuilder();
String key = null;
String value = null;
@ -411,14 +411,13 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
{
map.add(key, value);
}
else if (value != null && value.length() > 0)
else if (value.length() > 0)
{
map.add(value, "");
}
key = null;
value = null;
if (maxKeys >= 0 && map.size() > maxKeys)
throw new IllegalStateException(String.format("Form with too many keys [%d > %d]", map.size(), maxKeys));
checkMaxKeys(map, maxKeys);
break;
case '=':
@ -445,8 +444,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
buffer.append((char)b);
break;
}
if (maxLength >= 0 && (++totalLength > maxLength))
throw new IllegalStateException("Form is larger than max length " + maxLength);
checkMaxLength(++totalLength, maxLength);
}
if (key != null)
@ -459,6 +457,8 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
{
map.add(buffer.toString(), "");
}
checkMaxKeys(map, maxKeys);
}
}
@ -468,7 +468,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
* @param in InputSteam to read
* @param map MultiMap to add parameters to
* @param maxLength maximum form length to decode
* @param maxKeys the maximum number of keys to read or -1 for no limit
* @param maxKeys the maximum number of keys to read
* @throws IOException if unable to decode input stream
*/
public static void decodeUtf8To(InputStream in, MultiMap<String> map, int maxLength, int maxKeys)
@ -500,8 +500,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
}
key = null;
value = null;
if (maxKeys >= 0 && map.size() > maxKeys)
throw new IllegalStateException(String.format("Form with too many keys [%d > %d]", map.size(), maxKeys));
checkMaxKeys(map, maxKeys);
break;
case '=':
@ -528,8 +527,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
buffer.append((byte)b);
break;
}
if (maxLength >= 0 && (++totalLength > maxLength))
throw new IllegalStateException("Form is larger than max length " + maxLength);
checkMaxLength(++totalLength, maxLength);
}
if (key != null)
@ -542,6 +540,8 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
{
map.add(buffer.toReplacedString(), "");
}
checkMaxKeys(map, maxKeys);
}
}
@ -651,8 +651,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
}
key = null;
value = null;
if (maxKeys >= 0 && map.size() > maxKeys)
throw new IllegalStateException(String.format("Form with too many keys [%d > %d]", map.size(), maxKeys));
checkMaxKeys(map, maxKeys);
break;
case '=':
if (key != null)
@ -676,10 +675,7 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
output.write(c);
break;
}
totalLength++;
if (maxLength >= 0 && totalLength > maxLength)
throw new IllegalStateException("Form is larger than max length " + maxLength);
checkMaxLength(++totalLength, maxLength);
}
size = output.size();
@ -690,11 +686,28 @@ public class UrlEncoded extends MultiMap<String> implements Cloneable
map.add(key, value);
}
else if (size > 0)
{
map.add(output.toString(charset), "");
}
checkMaxKeys(map, maxKeys);
}
}
}
private static void checkMaxKeys(MultiMap<String> map, int maxKeys)
{
int size = map.size();
if (maxKeys >= 0 && size > maxKeys)
throw new IllegalStateException(String.format("Form with too many keys [%d > %d]", size, maxKeys));
}
private static void checkMaxLength(int length, int maxLength)
{
if (maxLength >= 0 && length > maxLength)
throw new IllegalStateException("Form is larger than max length " + maxLength);
}
/**
* Decode String with % encoding.
* This method makes the assumption that the majority of calls