diff --git a/9.0.10.tar.gz b/9.0.10.tar.gz
deleted file mode 100644
index 157288e..0000000
Binary files a/9.0.10.tar.gz and /dev/null differ
diff --git a/CVE-2018-11784.patch b/CVE-2018-11784.patch
deleted file mode 100644
index 4bf1bb2..0000000
--- a/CVE-2018-11784.patch
+++ /dev/null
@@ -1,27 +0,0 @@
---- a/webapps/docs/changelog.xml 2018-06-20 13:35:40.000000000 -0400
-+++ b/webapps/docs/changelog_1.xml 2019-06-24 08:35:44.801000000 -0400
-@@ -164,6 +164,10 @@
- the authenticated Subject to include at least one Principal of a type
- specified by userClassNames. (markt)
-
-+
-+ When generating a redirect to a directory in the Default Servlet, avoid
-+ generating a protocol relative redirect. (markt)
-+
-
-
-
---- a/java/org/apache/catalina/servlets/DefaultServlet.java 2018-06-20 13:35:34.000000000 -0400
-+++ b/java/org/apache/catalina/servlets/DefaultServlet_1.java 2019-06-24 08:40:08.699000000 -0400
-@@ -1324,6 +1324,10 @@ public class DefaultServlet extends Http
- location.append('?');
- location.append(request.getQueryString());
- }
-+ // Avoid protocol relative redirects
-+ while (location.length() > 1 && location.charAt(1) == '/') {
-+ location.deleteCharAt(0);
-+ }
- response.sendRedirect(response.encodeRedirectURL(location.toString()));
- }
-
-
diff --git a/CVE-2019-0199-1.patch b/CVE-2019-0199-1.patch
deleted file mode 100644
index d05be52..0000000
--- a/CVE-2019-0199-1.patch
+++ /dev/null
@@ -1,75 +0,0 @@
---- tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:17:08 1852697
-+++ tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:01 1852698
-@@ -42,8 +42,10 @@
- public class Http2Protocol implements UpgradeProtocol {
-
- static final long DEFAULT_READ_TIMEOUT = 10000;
-- static final long DEFAULT_KEEP_ALIVE_TIMEOUT = -1;
- static final long DEFAULT_WRITE_TIMEOUT = 10000;
-+ static final long DEFAULT_KEEP_ALIVE_TIMEOUT = -1;
-+ static final long DEFAULT_STREAM_READ_TIMEOUT = 20000;
-+ static final long DEFAULT_STREAM_WRITE_TIMEOUT = 20000;
- // The HTTP/2 specification recommends a minimum default of 100
- static final long DEFAULT_MAX_CONCURRENT_STREAMS = 200;
- // Maximum amount of streams which can be concurrently executed over
-@@ -57,9 +59,14 @@
- private static final byte[] ALPN_IDENTIFIER = ALPN_NAME.getBytes(StandardCharsets.UTF_8);
-
- // All timeouts in milliseconds
-+ // These are the socket level timeouts
- private long readTimeout = DEFAULT_READ_TIMEOUT;
-- private long keepAliveTimeout = DEFAULT_KEEP_ALIVE_TIMEOUT;
- private long writeTimeout = DEFAULT_WRITE_TIMEOUT;
-+ private long keepAliveTimeout = DEFAULT_KEEP_ALIVE_TIMEOUT;
-+ // These are the stream level timeouts
-+ private long streamReadTimeout = DEFAULT_STREAM_READ_TIMEOUT;
-+ private long streamWriteTimeout = DEFAULT_STREAM_WRITE_TIMEOUT;
-+
- private long maxConcurrentStreams = DEFAULT_MAX_CONCURRENT_STREAMS;
- private int maxConcurrentStreamExecution = DEFAULT_MAX_CONCURRENT_STREAM_EXECUTION;
- // If a lower initial value is required, set it here but DO NOT change the
-@@ -145,6 +152,16 @@
- }
-
-
-+ public long getWriteTimeout() {
-+ return writeTimeout;
-+ }
-+
-+
-+ public void setWriteTimeout(long writeTimeout) {
-+ this.writeTimeout = writeTimeout;
-+ }
-+
-+
- public long getKeepAliveTimeout() {
- return keepAliveTimeout;
- }
-@@ -155,13 +172,23 @@
- }
-
-
-- public long getWriteTimeout() {
-- return writeTimeout;
-+ public long getStreamReadTimeout() {
-+ return streamReadTimeout;
- }
-
-
-- public void setWriteTimeout(long writeTimeout) {
-- this.writeTimeout = writeTimeout;
-+ public void setStreamReadTimeout(long streamReadTimeout) {
-+ this.streamReadTimeout = streamReadTimeout;
-+ }
-+
-+
-+ public long getStreamWriteTimeout() {
-+ return streamWriteTimeout;
-+ }
-+
-+
-+ public void setStreamWriteTimeout(long streamWriteTimeout) {
-+ this.streamWriteTimeout = streamWriteTimeout;
- }
-
-
diff --git a/CVE-2019-0199-10.patch b/CVE-2019-0199-10.patch
deleted file mode 100644
index fef53b2..0000000
--- a/CVE-2019-0199-10.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java 2019-06-09 21:03:54.790000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java 2019-06-09 21:05:12.133000000 -0400
-@@ -905,7 +905,7 @@ class Stream extends AbstractStream impl
- throw new IOException(sm.getString("stream.inputBuffer.reset"));
- }
-
-- if (inBuffer.position() == 0) {
-+ if (inBuffer.position() == 0 && isActive() && !isInputFinished()) {
- String msg = sm.getString("stream.inputBuffer.readTimeout");
- StreamException se = new StreamException(
- msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
-
diff --git a/CVE-2019-0199-11.patch b/CVE-2019-0199-11.patch
deleted file mode 100644
index 33e7526..0000000
--- a/CVE-2019-0199-11.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/java/org/apache/coyote/http2/Stream.java 2019-06-11 21:24:19.998000000 -0400
-+++ b/java/org/apache/coyote/http2/Stream_1.java 2019-06-11 21:26:18.329000000 -0400
-@@ -221,7 +221,7 @@ class Stream extends AbstractStream impl
- if (windowSize == 0) {
- String msg = sm.getString("stream.writeTimeout");
- StreamException se = new StreamException(
-- msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
-+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdentifier().intValue());
- // Prevent the application making further writes
- streamOutputBuffer.closed = true;
- // Prevent Tomcat's error handling trying to write
-@@ -908,7 +908,7 @@ class Stream extends AbstractStream impl
- if (inBuffer.position() == 0 && isActive() && !isInputFinished()) {
- String msg = sm.getString("stream.inputBuffer.readTimeout");
- StreamException se = new StreamException(
-- msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
-+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdentifier().intValue());
- // Trigger a reset once control returns to Tomcat
- coyoteResponse.setError();
- streamOutputBuffer.reset = se;
-
diff --git a/CVE-2019-0199-2.patch b/CVE-2019-0199-2.patch
deleted file mode 100644
index c1c1fda..0000000
--- a/CVE-2019-0199-2.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/catalina/connector/OutputBuffer.java apache-tomcat-9.0.10-src-bak/java/org/apache/catalina/connector/OutputBuffer.java
---- apache-tomcat-9.0.10-src/java/org/apache/catalina/connector/OutputBuffer.java 2018-06-20 13:35:33.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/catalina/connector/OutputBuffer.java 2019-06-09 20:28:02.836000000 -0400
-@@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletRes
-
- import org.apache.catalina.Globals;
- import org.apache.coyote.ActionCode;
-+import org.apache.coyote.CloseNowException;
- import org.apache.coyote.Response;
- import org.apache.tomcat.util.buf.C2BConverter;
- import org.apache.tomcat.util.res.StringManager;
-@@ -326,6 +327,13 @@ public class OutputBuffer extends Writer
- // real write to the adapter
- try {
- coyoteResponse.doWrite(buf);
-+ } catch (CloseNowException e) {
-+ // Catch this sub-class as it requires specific handling.
-+ // Examples where this exception is thrown:
-+ // - HTTP/2 stream timeout
-+ // Prevent further output for this response
-+ closed = true;
-+ throw e;
- } catch (IOException e) {
- // An IOException on a write is almost always due to
- // the remote client aborting the request. Wrap this
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/catalina/core/StandardWrapperValve.java apache-tomcat-9.0.10-src-bak/java/org/apache/catalina/core/StandardWrapperValve.java
---- apache-tomcat-9.0.10-src/java/org/apache/catalina/core/StandardWrapperValve.java 2018-06-20 13:35:34.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/catalina/core/StandardWrapperValve.java 2019-06-09 20:33:27.596000000 -0400
-@@ -36,6 +36,7 @@ import org.apache.catalina.connector.Cli
- import org.apache.catalina.connector.Request;
- import org.apache.catalina.connector.Response;
- import org.apache.catalina.valves.ValveBase;
-+import org.apache.coyote.CloseNowException;
- import org.apache.tomcat.util.ExceptionUtils;
- import org.apache.tomcat.util.buf.MessageBytes;
- import org.apache.tomcat.util.log.SystemLogHandler;
-@@ -201,7 +202,7 @@ final class StandardWrapperValve
- }
-
- }
-- } catch (ClientAbortException e) {
-+ } catch (ClientAbortException | CloseNowException e) {
- throwable = e;
- exception(request, response, e);
- } catch (IOException e) {
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/LocalStrings.properties apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/LocalStrings.properties
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/LocalStrings.properties 2018-06-20 13:35:35.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/LocalStrings.properties 2019-06-09 20:34:32.307000000 -0400
-@@ -93,6 +93,7 @@ stream.reset.fail=Connection [{0}], Stre
- stream.reset.receive=Connection [{0}], Stream [{1}], Reset received due to [{2}]
- stream.reset.send=Connection [{0}], Stream [{1}], Reset sent due to [{2}]
- stream.trailerHeader.noEndOfStream=Connection [{0}], Stream [{1}], The trailer headers did not include the end of stream flag
-+stream.writeTimeout=Timeout waiting for client to increase flow control window to permit stream data to be written
-
- stream.inputBuffer.copy=Copying [{0}] bytes from inBuffer to outBuffer
- stream.inputBuffer.dispatch=Data added to inBuffer when read interest is registered. Triggering a read dispatch
-@@ -149,4 +150,4 @@ upgradeHandler.writeHeaders=Connection [
- upgradeHandler.writePushHeaders=Connection [{0}], Stream [{1}], Pushed stream [{2}], EndOfStream [{3}]
-
- writeStateMachine.endWrite.ise=It is illegal to specify [{0}] for the new state once a write has completed
--writeStateMachine.ise=It is illegal to call [{0}()] in state [{1}]
-\ No newline at end of file
-+writeStateMachine.ise=It is illegal to call [{0}()] in state [{1}]
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java 2018-06-20 13:35:35.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java 2019-06-09 20:38:30.109000000 -0400
-@@ -211,7 +211,21 @@ class Stream extends AbstractStream impl
- }
- try {
- if (block) {
-- wait();
-+ wait(handler.getProtocol().getStreamWriteTimeout());
-+ windowSize = getWindowSize();
-+ if (windowSize == 0) {
-+ String msg = sm.getString("stream.writeTimeout");
-+ StreamException se = new StreamException(
-+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
-+ // Prevent the application making further writes
-+ streamOutputBuffer.closed = true;
-+ // Prevent Tomcat's error handling trying to write
-+ coyoteResponse.setError();
-+ coyoteResponse.setErrorReported();
-+ // Trigger a reset once control returns to Tomcat
-+ streamOutputBuffer.reset = se;
-+ throw new CloseNowException(msg, se);
-+ }
- } else {
- return 0;
- }
-@@ -221,7 +235,6 @@ class Stream extends AbstractStream impl
- // Stream.
- throw new IOException(e);
- }
-- windowSize = getWindowSize();
- }
- int allocation;
- if (windowSize < reservation) {
-@@ -660,6 +673,9 @@ class Stream extends AbstractStream impl
- return !streamOutputBuffer.endOfStreamSent;
- }
-
-+ StreamException getResetException() {
-+ return streamOutputBuffer.reset;
-+ }
-
- private static void push(final Http2UpgradeHandler handler, final Request request,
- final Stream stream) throws IOException {
-@@ -707,6 +723,7 @@ class Stream extends AbstractStream impl
- private final ByteBuffer buffer = ByteBuffer.allocate(8 * 1024);
- private volatile long written = 0;
- private volatile boolean closed = false;
-+ private volatile StreamException reset = null;
- private volatile boolean endOfStreamSent = false;
-
- /* The write methods are synchronized to ensure that only one thread at
-@@ -800,9 +817,14 @@ class Stream extends AbstractStream impl
-
- @Override
- public final void end() throws IOException {
-- closed = true;
-- flush(true);
-- writeTrailers();
-+ if (reset != null) {
-+ throw new CloseNowException(reset);
-+ }
-+ if (!closed) {
-+ closed = true;
-+ flush(true);
-+ writeTrailers();
-+ }
- }
-
- /**
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/StreamProcessor.java apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/StreamProcessor.java
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/StreamProcessor.java 2018-06-20 13:35:35.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/StreamProcessor.java 2019-06-09 20:40:08.789000000 -0400
-@@ -78,10 +78,13 @@ class StreamProcessor extends AbstractPr
- stream.getIdentifier()), Http2Error.INTERNAL_ERROR);
- stream.close(ce);
- } else if (!getErrorState().isIoAllowed()) {
-- StreamException se = new StreamException(sm.getString(
-- "streamProcessor.error.stream", stream.getConnectionId(),
-- stream.getIdentifier()), Http2Error.INTERNAL_ERROR,
-- stream.getIdentifier().intValue());
-+ StreamException se = stream.getResetException();
-+ if (se == null) {
-+ se = new StreamException(sm.getString(
-+ "streamProcessor.error.stream", stream.getConnectionId(),
-+ stream.getIdentifier()), Http2Error.INTERNAL_ERROR,
-+ stream.getIdentifier().intValue());
-+ }
- stream.close(se);
- }
- }
-diff -Nurp apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/Http2TestBase.java apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/Http2TestBase.java
---- apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/Http2TestBase.java 2018-06-20 13:35:38.000000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/Http2TestBase.java 2019-06-09 20:41:45.113000000 -0400
-@@ -486,8 +486,10 @@ public abstract class Http2TestBase exte
- Http2Protocol http2Protocol = new Http2Protocol();
- // Short timeouts for now. May need to increase these for CI systems.
- http2Protocol.setReadTimeout(2000);
-- http2Protocol.setKeepAliveTimeout(5000);
- http2Protocol.setWriteTimeout(2000);
-+ http2Protocol.setKeepAliveTimeout(5000);
-+ http2Protocol.setStreamReadTimeout(1000);
-+ http2Protocol.setStreamWriteTimeout(1000);
- http2Protocol.setMaxConcurrentStreams(maxConcurrentStreams);
- connector.addUpgradeProtocol(http2Protocol);
- }
-diff -Nurp apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/TestHttp2Timeouts.java apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/TestHttp2Timeouts.java
---- apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/TestHttp2Timeouts.java 1969-12-31 19:00:00.000000000 -0500
-+++ apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/TestHttp2Timeouts.java 2019-06-09 20:42:38.095000000 -0400
-@@ -0,0 +1,73 @@
-+/*
-+ * 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.coyote.http2;
-+
-+import org.junit.Assert;
-+import org.junit.Before;
-+import org.junit.Test;
-+
-+public class TestHttp2Timeouts extends Http2TestBase {
-+
-+ @Override
-+ @Before
-+ public void http2Connect() throws Exception {
-+ super.http2Connect();
-+ sendSettings(0, false, new SettingValue(Setting.INITIAL_WINDOW_SIZE.getId(), 0));
-+ }
-+
-+
-+ /*
-+ * Simple request won't fill buffer so timeout will occur in Tomcat internal
-+ * code during response completion.
-+ */
-+ @Test
-+ public void testClientWithEmptyWindow() throws Exception {
-+ sendSimpleGetRequest(3);
-+
-+ // Settings
-+ parser.readFrame(false);
-+ // Headers
-+ parser.readFrame(false);
-+
-+ output.clearTrace();
-+
-+ parser.readFrame(false);
-+ Assert.assertEquals("3-RST-[11]\n", output.getTrace());
-+ }
-+
-+
-+ /*
-+ * Large request will fill buffer so timeout will occur in application code
-+ * during response write (when Tomcat commits the response and flushes the
-+ * buffer as a result of the buffer filling).
-+ */
-+ @Test
-+ public void testClientWithEmptyWindowLargeResponse() throws Exception {
-+ sendLargeGetRequest(3);
-+
-+ // Settings
-+ parser.readFrame(false);
-+ // Headers
-+ parser.readFrame(false);
-+
-+ output.clearTrace();
-+
-+ parser.readFrame(false);
-+ Assert.assertEquals("3-RST-[11]\n", output.getTrace());
-+ }
-+
-+}
diff --git a/CVE-2019-0199-3.patch b/CVE-2019-0199-3.patch
deleted file mode 100644
index 0494f3b..0000000
--- a/CVE-2019-0199-3.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/LocalStrings.properties apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/LocalStrings.properties
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/LocalStrings.properties 2019-06-09 20:45:15.320000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/LocalStrings.properties 2019-06-09 20:46:36.793000000 -0400
-@@ -98,6 +98,7 @@ stream.writeTimeout=Timeout waiting for
- stream.inputBuffer.copy=Copying [{0}] bytes from inBuffer to outBuffer
- stream.inputBuffer.dispatch=Data added to inBuffer when read interest is registered. Triggering a read dispatch
- stream.inputBuffer.empty=The Stream input buffer is empty. Waiting for more data
-+stream.inputBuffer.readTimeout=Timeout waiting to read data from client
- stream.inputBuffer.reset=Stream reset
- stream.inputBuffer.signal=Data added to inBuffer when read thread is waiting. Signalling that thread to continue
-
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java 2019-06-09 20:45:15.321000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java 2019-06-09 20:48:21.509000000 -0400
-@@ -888,10 +888,22 @@ class Stream extends AbstractStream impl
- if (log.isDebugEnabled()) {
- log.debug(sm.getString("stream.inputBuffer.empty"));
- }
-- inBuffer.wait();
-+
-+ inBuffer.wait(handler.getProtocol().getStreamReadTimeout());
-+
- if (reset) {
- throw new IOException(sm.getString("stream.inputBuffer.reset"));
- }
-+
-+ if (inBuffer.position() == 0) {
-+ String msg = sm.getString("stream.inputBuffer.readTimeout");
-+ StreamException se = new StreamException(
-+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdAsInt());
-+ // Trigger a reset once control returns to Tomcat
-+ coyoteResponse.setError();
-+ streamOutputBuffer.reset = se;
-+ throw new CloseNowException(msg, se);
-+ }
- } catch (InterruptedException e) {
- // Possible shutdown / rst or similar. Use an
- // IOException to signal to the client that further I/O
-diff -Nurp apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/Http2TestBase.java apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/Http2TestBase.java
---- apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/Http2TestBase.java 2019-06-09 20:45:15.323000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/Http2TestBase.java 2019-06-09 20:53:54.809000000 -0400
-@@ -28,6 +28,7 @@ import java.nio.charset.StandardCharsets
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Locale;
-+import java.util.Map;
- import java.util.Random;
-
- import javax.net.SocketFactory;
-@@ -300,6 +301,22 @@ public abstract class Http2TestBase exte
- }
- }
-
-+ protected void sendParameterPostRequest(int streamId, byte[] padding, String body,
-+ long contentLength, boolean useExpectation) throws IOException {
-+ byte[] headersFrameHeader = new byte[9];
-+ ByteBuffer headersPayload = ByteBuffer.allocate(128);
-+ byte[] dataFrameHeader = new byte[9];
-+ ByteBuffer dataPayload = ByteBuffer.allocate(128);
-+
-+ buildPostRequest(headersFrameHeader, headersPayload, useExpectation,
-+ "application/x-www-form-urlencoded", contentLength, "/parameter", dataFrameHeader,
-+ dataPayload, padding, null, null, streamId);
-+ writeFrame(headersFrameHeader, headersPayload);
-+ if (body != null) {
-+ dataPayload.put(body.getBytes(StandardCharsets.ISO_8859_1));
-+ writeFrame(dataFrameHeader, dataPayload);
-+ }
-+ }
-
- protected void buildPostRequest(byte[] headersFrameHeader, ByteBuffer headersPayload,
- boolean useExpectation, byte[] dataFrameHeader, ByteBuffer dataPayload, byte[] padding,
-@@ -311,14 +328,29 @@ public abstract class Http2TestBase exte
- protected void buildPostRequest(byte[] headersFrameHeader, ByteBuffer headersPayload,
- boolean useExpectation, byte[] dataFrameHeader, ByteBuffer dataPayload, byte[] padding,
- byte[] trailersFrameHeader, ByteBuffer trailersPayload, int streamId) {
-+ buildPostRequest(headersFrameHeader, headersPayload, useExpectation, null, -1, "/simple",
-+ dataFrameHeader, dataPayload, padding, trailersFrameHeader, trailersPayload, streamId);
-+ }
-+
-+ protected void buildPostRequest(byte[] headersFrameHeader, ByteBuffer headersPayload,
-+ boolean useExpectation, String contentType, long contentLength, String path,
-+ byte[] dataFrameHeader, ByteBuffer dataPayload, byte[] padding,
-+ byte[] trailersFrameHeader, ByteBuffer trailersPayload, int streamId) {
-+
- MimeHeaders headers = new MimeHeaders();
- headers.addValue(":method").setString("POST");
- headers.addValue(":scheme").setString("http");
-- headers.addValue(":path").setString("/simple");
-+ headers.addValue(":path").setString(path);
- headers.addValue(":authority").setString("localhost:" + getPort());
- if (useExpectation) {
- headers.addValue("expect").setString("100-continue");
- }
-+ if (contentType != null) {
-+ headers.addValue("content-type").setString(contentType);
-+ }
-+ if (contentLength > -1) {
-+ headers.addValue("content-length").setLong(contentLength);
-+ }
- hpackEncoder.encode(headers, headersPayload);
-
- headersPayload.flip();
-@@ -507,6 +539,8 @@ public abstract class Http2TestBase exte
- ctxt.addServletMappingDecoded("/large", "large");
- Tomcat.addServlet(ctxt, "cookie", new CookieServlet());
- ctxt.addServletMappingDecoded("/cookie", "cookie");
-+ Tomcat.addServlet(ctxt, "parameter", new ParameterServlet());
-+ ctxt.addServletMappingDecoded("/parameter", "parameter");
-
- tomcat.start();
- }
-@@ -1205,6 +1239,24 @@ public abstract class Http2TestBase exte
- }
- }
-
-+
-+ static class ParameterServlet extends HttpServlet {
-+
-+ private static final long serialVersionUID = 1L;
-+
-+ @Override
-+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
-+ throws ServletException, IOException {
-+
-+ Map params = req.getParameterMap();
-+
-+ resp.setContentType("text/plain");
-+ resp.setCharacterEncoding("UTF-8");
-+
-+ resp.getWriter().print(params.size());
-+ }
-+ }
-+
-
- static class SettingValue {
- private final int setting;
-diff -Nurp apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/TestHttp2Timeouts.java apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/TestHttp2Timeouts.java
---- apache-tomcat-9.0.10-src/test/org/apache/coyote/http2/TestHttp2Timeouts.java 2019-06-09 20:45:15.323000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/test/org/apache/coyote/http2/TestHttp2Timeouts.java 2019-06-09 20:57:22.652000000 -0400
-@@ -26,7 +26,6 @@ public class TestHttp2Timeouts extends H
- @Before
- public void http2Connect() throws Exception {
- super.http2Connect();
-- sendSettings(0, false, new SettingValue(Setting.INITIAL_WINDOW_SIZE.getId(), 0));
- }
-
-
-@@ -36,7 +35,7 @@ public class TestHttp2Timeouts extends H
- */
- @Test
- public void testClientWithEmptyWindow() throws Exception {
-- sendSimpleGetRequest(3);
-+ sendSettings(0, false, new SettingValue(Setting.INITIAL_WINDOW_SIZE.getId(), 0));
-
- // Settings
- parser.readFrame(false);
-@@ -57,6 +56,7 @@ public class TestHttp2Timeouts extends H
- */
- @Test
- public void testClientWithEmptyWindowLargeResponse() throws Exception {
-+ sendSettings(0, false, new SettingValue(Setting.INITIAL_WINDOW_SIZE.getId(), 0));
- sendLargeGetRequest(3);
-
- // Settings
-@@ -70,4 +70,36 @@ public class TestHttp2Timeouts extends H
- Assert.assertEquals("3-RST-[11]\n", output.getTrace());
- }
-
-+ /*
-+ * Timeout with app reading request body directly.
-+ */
-+ @Test
-+ public void testClientPostsNoBody() throws Exception {
-+ sendSimplePostRequest(3, null, false);
-+
-+ // Headers
-+ parser.readFrame(false);
-+ output.clearTrace();
-+
-+ parser.readFrame(false);
-+
-+ Assert.assertEquals("3-RST-[11]\n", output.getTrace());
-+ }
-+
-+
-+ /*
-+ * Timeout with app processing parameters.
-+ */
-+ @Test
-+ public void testClientPostsNoParameters() throws Exception {
-+ sendParameterPostRequest(3, null, null, 10, false);
-+
-+ // Headers
-+ parser.readFrame(false);
-+ output.clearTrace();
-+
-+ parser.readFrame(false);
-+
-+ Assert.assertEquals("3-RST-[11]\n", output.getTrace());
-+ }
- }
diff --git a/CVE-2019-0199-4.patch b/CVE-2019-0199-4.patch
deleted file mode 100644
index 78e7858..0000000
--- a/CVE-2019-0199-4.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:14 1852700
-+++ tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:18 1852701
-@@ -41,9 +41,9 @@
-
- public class Http2Protocol implements UpgradeProtocol {
-
-- static final long DEFAULT_READ_TIMEOUT = 10000;
-- static final long DEFAULT_WRITE_TIMEOUT = 10000;
-- static final long DEFAULT_KEEP_ALIVE_TIMEOUT = -1;
-+ static final long DEFAULT_READ_TIMEOUT = 5000;
-+ static final long DEFAULT_WRITE_TIMEOUT = 5000;
-+ static final long DEFAULT_KEEP_ALIVE_TIMEOUT = 20000;
- static final long DEFAULT_STREAM_READ_TIMEOUT = 20000;
- static final long DEFAULT_STREAM_WRITE_TIMEOUT = 20000;
- // The HTTP/2 specification recommends a minimum default of 100
---- tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:14 1852700
-+++ tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:18 1852701
-@@ -329,9 +329,16 @@
- }
- }
- }
-- // No more frames to read so switch to the keep-alive
-- // timeout.
-- socketWrapper.setReadTimeout(protocol.getKeepAliveTimeout());
-+
-+ if (activeRemoteStreamCount.get() == 0) {
-+ // No streams currently active. Use the keep-alive
-+ // timeout for the connection.
-+ socketWrapper.setReadTimeout(protocol.getKeepAliveTimeout());
-+ } else {
-+ // Streams currently active. Individual streams have
-+ // timeouts so keep the connection open.
-+ socketWrapper.setReadTimeout(-1);
-+ }
- } catch (Http2Exception ce) {
- // Really ConnectionException
- if (log.isDebugEnabled()) {
-
diff --git a/CVE-2019-0199-5.patch b/CVE-2019-0199-5.patch
deleted file mode 100644
index a21d1a3..0000000
--- a/CVE-2019-0199-5.patch
+++ /dev/null
@@ -1,143 +0,0 @@
---- tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:18 1852701
-+++ tomcat/java/org/apache/coyote/http2/Http2Protocol.java 2019/02/01 10:28:22 1852702
-@@ -54,6 +54,8 @@
- // This default is defined by the HTTP/2 specification
- static final int DEFAULT_INITIAL_WINDOW_SIZE = (1 << 16) - 1;
-
-+ static final int DEFAULT_OVERHEAD_COUNT_FACTOR = 1;
-+
- private static final String HTTP_UPGRADE_NAME = "h2c";
- private static final String ALPN_NAME = "h2";
- private static final byte[] ALPN_IDENTIFIER = ALPN_NAME.getBytes(StandardCharsets.UTF_8);
-@@ -79,6 +81,8 @@
- private int maxHeaderSize = Constants.DEFAULT_MAX_HEADER_SIZE;
- private int maxTrailerCount = Constants.DEFAULT_MAX_TRAILER_COUNT;
- private int maxTrailerSize = Constants.DEFAULT_MAX_TRAILER_SIZE;
-+ private int overheadCountFactor = DEFAULT_OVERHEAD_COUNT_FACTOR;
-+
- private boolean initiatePingDisabled = false;
- private boolean useSendfile = true;
- // Compression
-@@ -306,6 +310,16 @@
- }
-
-
-+ public int getOverheadCountFactor() {
-+ return overheadCountFactor;
-+ }
-+
-+
-+ public void setOverheadCountFactor(int overheadCountFactor) {
-+ this.overheadCountFactor = overheadCountFactor;
-+ }
-+
-+
- public void setInitiatePingDisabled(boolean initiatePingDisabled) {
- this.initiatePingDisabled = initiatePingDisabled;
- }
---- tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:18 1852701
-+++ tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:22 1852702
-@@ -30,6 +30,7 @@
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentLinkedQueue;
- import java.util.concurrent.atomic.AtomicInteger;
-+import java.util.concurrent.atomic.AtomicLong;
- import java.util.concurrent.atomic.AtomicReference;
-
- import javax.servlet.http.WebConnection;
-@@ -139,6 +140,9 @@
- private AtomicInteger streamConcurrency = null;
- private Queue queuedRunnable = null;
-
-+ // Track 'overhead' frames vs 'request/response' frames
-+ private final AtomicLong overheadCount = new AtomicLong(-10);
-+
-
- Http2UpgradeHandler(Http2Protocol protocol, Adapter adapter, Request coyoteRequest) {
- super (STREAM_ID_ZERO);
-@@ -330,6 +334,10 @@
- }
- }
-
-+ if (overheadCount.get() > 0) {
-+ throw new ConnectionException("Too much overhead", Http2Error.ENHANCE_YOUR_CALM);
-+ }
-+
- if (activeRemoteStreamCount.get() == 0) {
- // No streams currently active. Use the keep-alive
- // timeout for the connection.
-@@ -638,6 +646,9 @@
- log.debug(sm.getString("upgradeHandler.writeBody", connectionId, stream.getIdentifier(),
- Integer.toString(len)));
- }
-+
-+ reduceOverheadCount();
-+
- // Need to check this now since sending end of stream will change this.
- boolean writeable = stream.canWrite();
- byte[] header = new byte[9];
-@@ -1193,6 +1204,16 @@
- }
-
-
-+ private void reduceOverheadCount() {
-+ overheadCount.decrementAndGet();
-+ }
-+
-+
-+ private void increaseOverheadCount() {
-+ overheadCount.addAndGet(getProtocol().getOverheadCountFactor());
-+ }
-+
-+
- // ----------------------------------------------- Http2Parser.Input methods
-
- @Override
-@@ -1247,6 +1268,7 @@
-
- @Override
- public ByteBuffer startRequestBodyFrame(int streamId, int payloadSize) throws Http2Exception {
-+ reduceOverheadCount();
- Stream stream = getStream(streamId, true);
- stream.checkState(FrameType.DATA);
- stream.receivedData(payloadSize);
-@@ -1291,6 +1313,8 @@
- // determines if a new stream is created or if this stream is ignored.
- checkPauseState();
-
-+ reduceOverheadCount();
-+
- if (connectionState.get().isNewStreamAllowed()) {
- Stream stream = getStream(streamId, false);
- if (stream == null) {
-@@ -1340,6 +1364,9 @@
- throw new ConnectionException(sm.getString("upgradeHandler.dependency.invalid",
- getConnectionId(), Integer.valueOf(streamId)), Http2Error.PROTOCOL_ERROR);
- }
-+
-+ increaseOverheadCount();
-+
- Stream stream = getStream(streamId, false);
- if (stream == null) {
- stream = createRemoteStream(streamId);
-@@ -1384,6 +1411,9 @@
-
- @Override
- public void setting(Setting setting, long value) throws ConnectionException {
-+
-+ increaseOverheadCount();
-+
- // Special handling required
- if (setting == Setting.INITIAL_WINDOW_SIZE) {
- long oldValue = remoteSettings.getInitialWindowSize();
-@@ -1425,6 +1455,9 @@
-
- @Override
- public void pingReceive(byte[] payload, boolean ack) throws IOException {
-+ if (!ack) {
-+ increaseOverheadCount();
-+ }
- pingManager.receivePing(payload, ack);
- }
-
-
diff --git a/CVE-2019-0199-6.patch b/CVE-2019-0199-6.patch
deleted file mode 100644
index ef1ed8d..0000000
--- a/CVE-2019-0199-6.patch
+++ /dev/null
@@ -1,51 +0,0 @@
---- tomcat/webapps/docs/config/http2.xml 2019/02/01 10:28:22 1852702
-+++ tomcat/webapps/docs/config/http2.xml 2019/02/01 10:28:26 1852703
-@@ -125,9 +125,9 @@
-
-
-
The time, in milliseconds, that Tomcat will wait between HTTP/2 frames
-- before closing the connection. Negative values will be treated as an
-- infinite timeout. If not specified, a default value of -1
-- will be used.
-+ when there is no active Stream before closing the connection. Negative
-+ values will be treated as an infinite timeout. If not specified, a default
-+ value of 20000 will be used.
-
-
-
-@@ -192,7 +192,24 @@
-
The time, in milliseconds, that Tomcat will wait for additional data
- when a partial HTTP/2 frame has been received. Negative values will be
- treated as an infinite timeout. If not specified, a default value of
-- 10000 will be used.
-+ 5000 will be used.
-+
-+
-+
-+
The time, in milliseconds, that Tomcat will wait for additional data
-+ frames to arrive for the stream when an application is performing a
-+ blocking I/O read and additional data is required. Negative values will be
-+ treated as an infinite timeout. If not specified, a default value of
-+ 20000 will be used.
-+
-+
-+
-+
The time, in milliseconds, that Tomcat will wait for additional window
-+ update frames to arrive for the stream and/or conenction when an
-+ application is performing a blocking I/O write and the stream and/or
-+ connection flow control window is too small for the write to complete.
-+ Negative values will be treated as an infinite timeout. If not specified,
-+ a default value of 20000 will be used.
-
-
-
-@@ -204,7 +221,7 @@
-
The time, in milliseconds, that Tomcat will wait to write additional
- data when an HTTP/2 frame has been partially written. Negative values will
- be treated as an infinite timeout. If not specified, a default value of
-- 10000 will be used.
-+ 5000 will be used.
-
-
-
-
diff --git a/CVE-2019-0199-7.patch b/CVE-2019-0199-7.patch
deleted file mode 100644
index 0369108..0000000
--- a/CVE-2019-0199-7.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-diff -Nurp apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java
---- apache-tomcat-9.0.10-src/java/org/apache/coyote/http2/Stream.java 2019-06-09 20:59:53.027000000 -0400
-+++ apache-tomcat-9.0.10-src-bak/java/org/apache/coyote/http2/Stream.java 2019-06-09 21:02:31.878000000 -0400
-@@ -211,7 +211,12 @@ class Stream extends AbstractStream impl
- }
- try {
- if (block) {
-- wait(handler.getProtocol().getStreamWriteTimeout());
-+ long writeTimeout = handler.getProtocol().getStreamWriteTimeout();
-+ if (writeTimeout < 0) {
-+ wait();
-+ } else {
-+ wait(writeTimeout);
-+ }
- windowSize = getWindowSize();
- if (windowSize == 0) {
- String msg = sm.getString("stream.writeTimeout");
-@@ -889,7 +894,12 @@ class Stream extends AbstractStream impl
- log.debug(sm.getString("stream.inputBuffer.empty"));
- }
-
-- inBuffer.wait(handler.getProtocol().getStreamReadTimeout());
-+ long readTimeout = handler.getProtocol().getStreamReadTimeout();
-+ if (readTimeout < 0) {
-+ inBuffer.wait();
-+ } else {
-+ inBuffer.wait(readTimeout);
-+ }
-
- if (reset) {
- throw new IOException(sm.getString("stream.inputBuffer.reset"));
-
diff --git a/CVE-2019-0199-8.patch b/CVE-2019-0199-8.patch
deleted file mode 100644
index f921ed2..0000000
--- a/CVE-2019-0199-8.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:30 1852704
-+++ tomcat/java/org/apache/coyote/http2/Http2UpgradeHandler.java 2019/02/01 10:28:34 1852705
-@@ -335,7 +335,9 @@
- }
-
- if (overheadCount.get() > 0) {
-- throw new ConnectionException("Too much overhead", Http2Error.ENHANCE_YOUR_CALM);
-+ throw new ConnectionException(
-+ sm.getString("upgradeHandler.tooMuchOverhead", connectionId),
-+ Http2Error.ENHANCE_YOUR_CALM);
- }
-
- if (activeRemoteStreamCount.get() == 0) {
---- tomcat/java/org/apache/coyote/http2/LocalStrings.properties 2019/02/01 10:28:30 1852704
-+++ tomcat/java/org/apache/coyote/http2/LocalStrings.properties 2019/02/01 10:28:34 1852705
-@@ -141,6 +141,7 @@
- upgradeHandler.stream.notWritable=Connection [{0}], Stream [{1}], This stream is not writable
- upgradeHandler.stream.old=A new remote stream ID of [{0}] was requested but the most recent stream was [{1}]
- upgradeHandler.tooManyRemoteStreams=The client attempted to use more than [{0}] active streams
-+upgradeHandler.tooMuchOverhead=Connection [{0}], Too much overhead so the connection will be closed
- upgradeHandler.unexpectedAck=Connection [{0}], Stream [{1}], A settings acknowledgement was received when not expected
- upgradeHandler.unexpectedEos=Unexpected end of stream
- upgradeHandler.upgrade=Connection [{0}], HTTP/1.1 upgrade to stream [1]
-
diff --git a/CVE-2019-0199-9.patch b/CVE-2019-0199-9.patch
deleted file mode 100644
index 78c22a1..0000000
--- a/CVE-2019-0199-9.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- tomcat/webapps/docs/config/http2.xml 2019/02/01 10:28:34 1852705
-+++ tomcat/webapps/docs/config/http2.xml 2019/02/01 10:28:38 1852706
-@@ -188,6 +188,20 @@
- The default value is an empty String (regexp matching disabled).
-
-
-+
-+
The factor to apply when counting overhead frames to determine if a
-+ connection has too high an overhead and should be closed. The overhead
-+ count starts at -10. The count is decreased for each
-+ data frame sent or received and each headers frame received. The count is
-+ increased by the overheadCountFactorfor each setting
-+ received, priority frame received and ping received. If the overhead count
-+ exceeds zero, the connection is closed. A value of less than
-+ 1 disables this protection. In normal usage a value of
-+ 3 or more will close the connection before any streams can
-+ complete. If not specified, a default value of 1 will be
-+ used.
-+
-+
-
-
The time, in milliseconds, that Tomcat will wait for additional data
- when a partial HTTP/2 frame has been received. Negative values will be
-
diff --git a/CVE-2019-0221.patch b/CVE-2019-0221.patch
deleted file mode 100644
index cc2c366..0000000
--- a/CVE-2019-0221.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From 15fcd166ea2c1bb79e8541b8e1a43da9c452ceea Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Mon, 11 Mar 2019 11:33:03 +0000
-Subject: [PATCH] Escape debug output to aid readability
-
-reason: Escape debug output to aid readability, fix CVE CVE-2019-0221
-https://github.com/apache/tomcat/commit/15fcd16
-
----
- java/org/apache/catalina/ssi/SSIPrintenv.java | 3 +--
- webapps/docs/changelog.xml | 3 +++
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/java/org/apache/catalina/ssi/SSIPrintenv.java b/java/org/apache/catalina/ssi/SSIPrintenv.java
-index 97470b2..092542f 100644
---- a/java/org/apache/catalina/ssi/SSIPrintenv.java
-+++ b/java/org/apache/catalina/ssi/SSIPrintenv.java
-@@ -41,8 +41,7 @@ public class SSIPrintenv implements SSICommand {
- } else {
- Collection variableNames = ssiMediator.getVariableNames();
- for (String variableName : variableNames) {
-- String variableValue = ssiMediator
-- .getVariableValue(variableName);
-+ String variableValue = ssiMediator.getVariableValue(variableName, "entity");
- //This shouldn't happen, since all the variable names must
- // have values
- if (variableValue == null) {
-diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
-index 697cf07..cbd3961 100644
---- a/webapps/docs/changelog.xml
-+++ b/webapps/docs/changelog.xml
-@@ -52,6 +52,9 @@
- Expires header as required by HTTP specification
- (RFC 7231, 7234). (kkolinko)
-
-+
-+ Encode the output of the SSI printenv command. (markt)
-+
-
-
-
---
-1.8.3.1
-
diff --git a/CVE-2019-10072-1.patch b/CVE-2019-10072-1.patch
deleted file mode 100644
index 93ea148..0000000
--- a/CVE-2019-10072-1.patch
+++ /dev/null
@@ -1,129 +0,0 @@
-From 7f748eb6bfaba5207c89dbd7d5adf50fae847145 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Tue, 30 Apr 2019 22:18:12 +0100
-Subject: [PATCH] Expand HTTP/2 timeout handling to connection window
- exhaustion on write.
-
-https://github.com/apache/tomcat/commit/7f748eb
----
- .../coyote/http2/Http2UpgradeHandler.java | 32 +++++++++++++++++--
- java/org/apache/coyote/http2/Stream.java | 27 +++++++++-------
- webapps/docs/changelog.xml | 4 +++
- 3 files changed, 50 insertions(+), 13 deletions(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index 1d8770a..ab0369a 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -794,7 +794,26 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- }
- if (allocation == 0) {
- try {
-- stream.wait();
-+ // Connection level window is empty. Although this
-+ // request is for a stream, use the connection
-+ // timeout
-+ long writeTimeout = protocol.getWriteTimeout();
-+ if (writeTimeout < 0) {
-+ stream.wait();
-+ } else {
-+ stream.wait(writeTimeout);
-+ }
-+ // Has this stream been granted an allocation
-+ int[] value = backLogStreams.get(stream);
-+ if (value[1] == 0) {
-+ // No allocation
-+ // Close the connection. Do this first since
-+ // closing the stream will raise an exception
-+ close();
-+ // Close the stream (in app code so need to
-+ // signal to app stream is closing)
-+ stream.doWriteTimeout();
-+ }
- } catch (InterruptedException e) {
- throw new IOException(sm.getString(
- "upgradeHandler.windowSizeReservationInterrupted", connectionId,
-@@ -985,11 +1004,20 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
-
-
- private void close() {
-- connectionState.set(ConnectionState.CLOSED);
-+ ConnectionState previous = connectionState.getAndSet(ConnectionState.CLOSED);
-+ if (previous == ConnectionState.CLOSED) {
-+ // Already closed
-+ return;
-+ }
-+
- for (Stream stream : streams.values()) {
- // The connection is closing. Close the associated streams as no
- // longer required.
- stream.receiveReset(Http2Error.CANCEL.getCode());
-+ // Release any streams waiting for an allocation
-+ synchronized (stream) {
-+ stream.notifyAll();
-+ }
- }
- try {
- socketWrapper.close();
-diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java
-index 2c4f67e..8b87b12 100644
---- a/java/org/apache/coyote/http2/Stream.java
-+++ b/java/org/apache/coyote/http2/Stream.java
-@@ -219,17 +219,7 @@ class Stream extends AbstractStream implements HeaderEmitter {
- }
- windowSize = getWindowSize();
- if (windowSize == 0) {
-- String msg = sm.getString("stream.writeTimeout");
-- StreamException se = new StreamException(
-- msg, Http2Error.ENHANCE_YOUR_CALM, getIdentifier().intValue());
-- // Prevent the application making further writes
-- streamOutputBuffer.closed = true;
-- // Prevent Tomcat's error handling trying to write
-- coyoteResponse.setError();
-- coyoteResponse.setErrorReported();
-- // Trigger a reset once control returns to Tomcat
-- streamOutputBuffer.reset = se;
-- throw new CloseNowException(msg, se);
-+ doWriteTimeout();
- }
- } else {
- return 0;
-@@ -252,6 +242,21 @@ class Stream extends AbstractStream implements HeaderEmitter {
- }
-
-
-+ void doWriteTimeout() throws CloseNowException {
-+ String msg = sm.getString("stream.writeTimeout");
-+ StreamException se = new StreamException(
-+ msg, Http2Error.ENHANCE_YOUR_CALM, getIdentifier().intValue());
-+ // Prevent the application making further writes
-+ streamOutputBuffer.closed = true;
-+ // Prevent Tomcat's error handling trying to write
-+ coyoteResponse.setError();
-+ coyoteResponse.setErrorReported();
-+ // Trigger a reset once control returns to Tomcat
-+ streamOutputBuffer.reset = se;
-+ throw new CloseNowException(msg, se);
-+ }
-+
-+
- @Override
- public final void emitHeader(String name, String value) throws HpackException {
- if (log.isDebugEnabled()) {
-diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
-index a8abf2d..5665df4 100644
---- a/webapps/docs/changelog.xml
-+++ b/webapps/docs/changelog.xml
-@@ -362,6 +362,10 @@
-
- Update the internal fork of Commons DBCP 2 to 2.4.0. (markt)
-
-+
-+ Expand HTTP/2 timeout handling to include connection window exhaustion
-+ on write. (markt)
-+
-
-
-
---
-2.19.1
diff --git a/CVE-2019-10072-2.patch b/CVE-2019-10072-2.patch
deleted file mode 100644
index 4619c59..0000000
--- a/CVE-2019-10072-2.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From ada725a50a60867af3422c8e612aecaeea856a9a Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Fri, 3 May 2019 21:52:41 +0100
-Subject: [PATCH] Fix test failures. Handle full allocation case.
-
-https://github.com/apache/tomcat/commit/ada725a
----
- java/org/apache/coyote/http2/Http2UpgradeHandler.java | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index ab0369a..cadae44 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -804,8 +804,10 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- stream.wait(writeTimeout);
- }
- // Has this stream been granted an allocation
-+ // Note: If the stream in not in this Map then the
-+ // requested write has been fully allocated
- int[] value = backLogStreams.get(stream);
-- if (value[1] == 0) {
-+ if (value != null && value[1] == 0) {
- // No allocation
- // Close the connection. Do this first since
- // closing the stream will raise an exception
---
-2.19.1
diff --git a/CVE-2019-12418.patch b/CVE-2019-12418.patch
deleted file mode 100644
index c373c43..0000000
--- a/CVE-2019-12418.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 1fc9f589dbdd8295cf313b2667ab041c425f99c3 Mon Sep 17 00:00:00 2001
-From: remm
-Date: Thu, 14 Nov 2019 13:39:31 +0100
-Subject: [PATCH] Refactor JMX remote RMI registry creation
-
----
- .../mbeans/JmxRemoteLifecycleListener.java | 65 ++++++++++++++-----
- 1 file changed, 49 insertions(+), 16 deletions(-)
-
-diff --git a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-index ae04294..e832935 100644
---- a/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-+++ b/java/org/apache/catalina/mbeans/JmxRemoteLifecycleListener.java
-@@ -25,10 +25,11 @@ import java.net.MalformedURLException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.net.UnknownHostException;
-+import java.rmi.AccessException;
- import java.rmi.AlreadyBoundException;
-+import java.rmi.NotBoundException;
-+import java.rmi.Remote;
- import java.rmi.RemoteException;
--import java.rmi.registry.LocateRegistry;
--import java.rmi.registry.Registry;
- import java.rmi.server.RMIClientSocketFactory;
- import java.rmi.server.RMIServerSocketFactory;
- import java.security.NoSuchAlgorithmException;
-@@ -301,18 +302,6 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
- RMIClientSocketFactory registryCsf, RMIServerSocketFactory registrySsf,
- RMIClientSocketFactory serverCsf, RMIServerSocketFactory serverSsf) {
-
-- // Create the RMI registry
-- Registry registry;
-- try {
-- registry = LocateRegistry.createRegistry(
-- theRmiRegistryPort, registryCsf, registrySsf);
-- } catch (RemoteException e) {
-- log.error(sm.getString(
-- "jmxRemoteLifecycleListener.createRegistryFailed",
-- serverName, Integer.toString(theRmiRegistryPort)), e);
-- return null;
-- }
--
- if (bindAddress == null) {
- bindAddress = "localhost";
- }
-@@ -333,11 +322,20 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
- cs = new RMIConnectorServer(serviceUrl, theEnv, server,
- ManagementFactory.getPlatformMBeanServer());
- cs.start();
-- registry.bind("jmxrmi", server.toStub());
-+ Remote jmxServer = server.toStub();
-+ // Create the RMI registry
-+ try {
-+ new JmxRegistry(theRmiRegistryPort, registryCsf, registrySsf, "jmxrmi", jmxServer);
-+ } catch (RemoteException e) {
-+ log.error(sm.getString(
-+ "jmxRemoteLifecycleListener.createRegistryFailed",
-+ serverName, Integer.toString(theRmiRegistryPort)), e);
-+ return null;
-+ }
- log.info(sm.getString("jmxRemoteLifecycleListener.start",
- Integer.toString(theRmiRegistryPort),
- Integer.toString(theRmiServerPort), serverName));
-- } catch (IOException | AlreadyBoundException e) {
-+ } catch (IOException e) {
- log.error(sm.getString(
- "jmxRemoteLifecycleListener.createServerFailed",
- serverName), e);
-@@ -493,4 +491,39 @@ public class JmxRemoteLifecycleListener implements LifecycleListener {
- return true;
- }
- }
-+
-+
-+ private static class JmxRegistry extends sun.rmi.registry.RegistryImpl {
-+ private static final long serialVersionUID = -3772054804656428217L;
-+ private final String jmxName;
-+ private final Remote jmxServer;
-+ public JmxRegistry(int port, RMIClientSocketFactory csf,
-+ RMIServerSocketFactory ssf, String jmxName, Remote jmxServer) throws RemoteException {
-+ super(port, csf, ssf);
-+ this.jmxName = jmxName;
-+ this.jmxServer = jmxServer;
-+ }
-+ @Override
-+ public Remote lookup(String name)
-+ throws RemoteException, NotBoundException {
-+ return (jmxName.equals(name)) ? jmxServer : null;
-+ }
-+ @Override
-+ public void bind(String name, Remote obj)
-+ throws RemoteException, AlreadyBoundException, AccessException {
-+ }
-+ @Override
-+ public void unbind(String name)
-+ throws RemoteException, NotBoundException, AccessException {
-+ }
-+ @Override
-+ public void rebind(String name, Remote obj)
-+ throws RemoteException, AccessException {
-+ }
-+ @Override
-+ public String[] list() throws RemoteException {
-+ return new String[] { jmxName };
-+ }
-+ }
-+
- }
---
-2.23.0
-
diff --git a/CVE-2019-17563.patch b/CVE-2019-17563.patch
deleted file mode 100644
index 97f569d..0000000
--- a/CVE-2019-17563.patch
+++ /dev/null
@@ -1,137 +0,0 @@
-From fabfa49abf917e126dbcf299fed40a1ab96d6f7a Mon Sep 17 00:00:00 2001
-From: wang_yue111
-Date: Fri, 15 May 2020 17:17:57 +0800
-Subject: [PATCH] 2
-
----
- .../authenticator/AuthenticatorBase.java | 7 ++--
- .../catalina/authenticator/Constants.java | 3 ++
- .../authenticator/FormAuthenticator.java | 36 +++++--------------
- 3 files changed, 16 insertions(+), 30 deletions(-)
-
-diff --git a/java/org/apache/catalina/authenticator/AuthenticatorBase.java b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
-index 880ebde..47d562b 100644
---- a/java/org/apache/catalina/authenticator/AuthenticatorBase.java
-+++ b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
-@@ -1021,10 +1021,11 @@ public abstract class AuthenticatorBase extends ValveBase
- }
-
- // Cache the authentication information in our session, if any
-- if (cache) {
-- if (session != null) {
-+ if (session != null) {
-+ if (cache) {
- session.setAuthType(authType);
- session.setPrincipal(principal);
-+ } else {
- if (username != null) {
- session.setNote(Constants.SESS_USERNAME_NOTE, username);
- } else {
-diff --git a/java/org/apache/catalina/authenticator/Constants.java b/java/org/apache/catalina/authenticator/Constants.java
-index 452a4f0..c9580d6 100644
---- a/java/org/apache/catalina/authenticator/Constants.java
-+++ b/java/org/apache/catalina/authenticator/Constants.java
-@@ -93,7 +93,10 @@ public class Constants {
-
- /**
- * The previously authenticated principal (if caching is disabled).
-+ *
-+ * @deprecated Unused. Will be removed in Tomcat 10.
- */
-+ @Deprecated
- public static final String FORM_PRINCIPAL_NOTE =
- "org.apache.catalina.authenticator.PRINCIPAL";
-
-diff --git a/java/org/apache/catalina/authenticator/FormAuthenticator.java b/java/org/apache/catalina/authenticator/FormAuthenticator.java
-index 1b54ddd..44c783e 100644
---- a/java/org/apache/catalina/authenticator/FormAuthenticator.java
-+++ b/java/org/apache/catalina/authenticator/FormAuthenticator.java
-@@ -133,10 +133,6 @@ public class FormAuthenticator
- protected boolean doAuthenticate(Request request, HttpServletResponse response)
- throws IOException {
-
-- if (checkForCachedAuthentication(request, response, true)) {
-- return true;
-- }
--
- // References to objects we will need later
- Session session = null;
- Principal principal = null;
-@@ -158,11 +154,8 @@ public class FormAuthenticator
- principal =
- context.getRealm().authenticate(username, password);
- if (principal != null) {
-- session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
-+ register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password);
- if (!matchRequest(request)) {
-- register(request, response, principal,
-- HttpServletRequest.FORM_AUTH,
-- username, password);
- return true;
- }
- }
-@@ -181,17 +174,6 @@ public class FormAuthenticator
- + session.getIdInternal()
- + "'");
- }
-- principal = (Principal)
-- session.getNote(Constants.FORM_PRINCIPAL_NOTE);
-- register(request, response, principal, HttpServletRequest.FORM_AUTH,
-- (String) session.getNote(Constants.SESS_USERNAME_NOTE),
-- (String) session.getNote(Constants.SESS_PASSWORD_NOTE));
-- // If we're caching principals we no longer need the username
-- // and password in the session, so remove them
-- if (cache) {
-- session.removeNote(Constants.SESS_USERNAME_NOTE);
-- session.removeNote(Constants.SESS_PASSWORD_NOTE);
-- }
- if (restoreRequest(request, session)) {
- if (log.isDebugEnabled()) {
- log.debug("Proceed to restored request");
-@@ -206,6 +188,12 @@ public class FormAuthenticator
- }
- }
-
-+ // This check has to be after the previous check for a matching request
-+ // because that matching request may also include a cached Principal.
-+ if (checkForCachedAuthentication(request, response, true)) {
-+ return true;
-+ }
-+
- // Acquire references to objects we will need to evaluate
- String contextPath = request.getContextPath();
- String requestURI = request.getDecodedRequestURI();
-@@ -297,12 +285,7 @@ public class FormAuthenticator
- return false;
- }
-
-- // Save the authenticated Principal in our session
-- session.setNote(Constants.FORM_PRINCIPAL_NOTE, principal);
--
-- // Save the username and password as well
-- session.setNote(Constants.SESS_USERNAME_NOTE, username);
-- session.setNote(Constants.SESS_PASSWORD_NOTE, password);
-+ register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password);
-
- // Redirect the user to the original request URI (which will cause
- // the original request to be restored)
-@@ -510,7 +493,7 @@ public class FormAuthenticator
- }
-
- // Is there a saved principal?
-- if (session.getNote(Constants.FORM_PRINCIPAL_NOTE) == null) {
-+ if (cache && session.getPrincipal() == null || !cache && request.getPrincipal() == null) {
- return false;
- }
-
-@@ -541,7 +524,6 @@ public class FormAuthenticator
- SavedRequest saved = (SavedRequest)
- session.getNote(Constants.FORM_REQUEST_NOTE);
- session.removeNote(Constants.FORM_REQUEST_NOTE);
-- session.removeNote(Constants.FORM_PRINCIPAL_NOTE);
- if (saved == null) {
- return false;
- }
---
-2.23.0
-
diff --git a/CVE-2020-11996.patch b/CVE-2020-11996.patch
deleted file mode 100644
index 62ce447..0000000
--- a/CVE-2020-11996.patch
+++ /dev/null
@@ -1,100 +0,0 @@
-From 9a0231683a77e2957cea0fdee88b193b30b0c976 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Fri, 22 May 2020 11:27:49 +0100
-Subject: [PATCH] Fix BZ 64467. Improve performance of closing idle streams
-
----
- .../coyote/http2/Http2UpgradeHandler.java | 10 +++---
- .../coyote/http2/TestHttp2Section_5_1.java | 31 ++++++++++++++++---
- webapps/docs/changelog.xml | 4 +++
- 3 files changed, 36 insertions(+), 9 deletions(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index bd836940fb..f0d5f27bda 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -1343,11 +1343,11 @@ public HeaderEmitter headersStart(int streamId, boolean headersEndStream)
- }
-
-
-- private void closeIdleStreams(int newMaxActiveRemoteStreamId) throws Http2Exception {
-- for (int i = maxActiveRemoteStreamId + 2; i < newMaxActiveRemoteStreamId; i += 2) {
-- Stream stream = getStream(i, false);
-- if (stream != null) {
-- stream.closeIfIdle();
-+ private void closeIdleStreams(int newMaxActiveRemoteStreamId) {
-+ for (Entry entry : streams.entrySet()) {
-+ if (entry.getKey().intValue() > maxActiveRemoteStreamId &&
-+ entry.getKey().intValue() < newMaxActiveRemoteStreamId) {
-+ entry.getValue().closeIfIdle();
- }
- }
- maxActiveRemoteStreamId = newMaxActiveRemoteStreamId;
-diff --git a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-index 2a466814e1..f878653ecf 100644
---- a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-+++ b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-@@ -147,21 +147,44 @@ public void testClientSendOldStream() throws Exception {
-
- @Test
- public void testImplicitClose() throws Exception {
-+ doTestImplicitClose(5);
-+ }
-+
-+
-+ // https://bz.apache.org/bugzilla/show_bug.cgi?id=64467
-+ @Test
-+ public void testImplicitCloseLargeId() throws Exception {
-+ doTestImplicitClose(Integer.MAX_VALUE - 8);
-+ }
-+
-+
-+ private void doTestImplicitClose(int lastStreamId) throws Exception {
-+
-+ long startFirst = System.nanoTime();
- http2Connect();
-+ long durationFirst = System.nanoTime() - startFirst;
-
- sendPriority(3, 0, 16);
-- sendPriority(5, 0, 16);
-+ sendPriority(lastStreamId, 0, 16);
-
-- sendSimpleGetRequest(5);
-+ long startSecond = System.nanoTime();
-+ sendSimpleGetRequest(lastStreamId);
- readSimpleGetResponse();
-- Assert.assertEquals(getSimpleResponseTrace(5), output.getTrace());
-+ long durationSecond = System.nanoTime() - startSecond;
-+
-+ Assert.assertEquals(getSimpleResponseTrace(lastStreamId), output.getTrace());
- output.clearTrace();
-
-+ // Allow second request to take up to 5 times first request or up to 1 second - whichever is the larger - mainly
-+ // to allow for CI systems under load that can exhibit significant timing variation.
-+ Assert.assertTrue("First request took [" + durationFirst/1000000 + "ms], second request took [" +
-+ durationSecond/1000000 + "ms]", durationSecond < 1000000000 || durationSecond < durationFirst * 3);
-+
- // Should trigger an error since stream 3 should have been implicitly
- // closed.
- sendSimpleGetRequest(3);
-
-- handleGoAwayResponse(5);
-+ handleGoAwayResponse(lastStreamId);
- }
-
-
-diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
-index 5665df4..7b81937 100644
---- a/webapps/docs/changelog.xml
-+++ b/webapps/docs/changelog.xml
-@@ -1803,6 +1803,10 @@
- HTTP 205 responses. Additional fix to r1795278. Based on a patch
- provided by Alexandr Saperov. (violetagg)
-
-+
-+ 64467: Improve performance of closing idle HTTP/2 streams.
-+ (markt)
-+
-
- 61345: Add a server listener that can be used to do system
- property replacement from the property source configured in the
diff --git a/CVE-2020-13934.patch b/CVE-2020-13934.patch
deleted file mode 100644
index 96ada00..0000000
--- a/CVE-2020-13934.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 172977f04a5215128f1e278a688983dcd230f399 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Fri, 26 Jun 2020 12:49:50 +0100
-Subject: [PATCH] Ensure HTTP/1.1 processor is recycled after a direct h2c
- connection
-
----
- java/org/apache/coyote/AbstractProtocol.java | 9 ++++++---
- webapps/docs/changelog.xml | 4 ++++
- 2 files changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/java/org/apache/coyote/AbstractProtocol.java b/java/org/apache/coyote/AbstractProtocol.java
-index cb326dc12e..5bc2212549 100644
---- a/java/org/apache/coyote/AbstractProtocol.java
-+++ b/java/org/apache/coyote/AbstractProtocol.java
-@@ -772,8 +772,10 @@ public SocketState process(SocketWrapperBase wrapper, SocketEvent status) {
- // Assume direct HTTP/2 connection
- UpgradeProtocol upgradeProtocol = getProtocol().getUpgradeProtocol("h2c");
- if (upgradeProtocol != null) {
-- processor = upgradeProtocol.getProcessor(
-- wrapper, getProtocol().getAdapter());
-+ // Release the Http11 processor to be re-used
-+ release(processor);
-+ // Create the upgrade processor
-+ processor = upgradeProtocol.getProcessor(wrapper, getProtocol().getAdapter());
- wrapper.unRead(leftOverInput);
- // Associate with the processor with the connection
- connections.put(socket, processor);
-@@ -785,7 +785,8 @@ public SocketState process(SocketWrapperBase wrapper, SocketEvent status) {
- "abstractConnectionHandler.negotiatedProcessor.fail",
- "h2c"));
- }
-- return SocketState.CLOSED;
-+ // Exit loop and trigger appropriate clean-up
-+ state = SocketState.CLOSED;
- }
- } else {
- HttpUpgradeHandler httpUpgradeHandler = upgradeToken.getHttpUpgradeHandler();
-diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
-index 5665df4..60cd317 100644
---- a/webapps/docs/changelog.xml
-+++ b/webapps/docs/changelog.xml
-@@ -232,6 +236,10 @@
-
- Avoid unnecessary processing of async timeouts. (markt)
-
-+
-+ Ensure that the HTTP/1.1 processor is correctly recycled when a direct
-+ connection to h2c is made. (markt)
-+
-
-
-
diff --git a/CVE-2020-13935.patch b/CVE-2020-13935.patch
deleted file mode 100644
index d8ccc08..0000000
--- a/CVE-2020-13935.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-From 40fa74c74822711ab878079d0a69f7357926723d Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Mon, 29 Jun 2020 14:02:59 +0100
-Subject: [PATCH] Fix BZ 64563 - additional payload length validation
-
-https://bz.apache.org/bugzilla/show_bug.cgi?id=64563
----
- java/org/apache/tomcat/websocket/LocalStrings.properties | 1 +
- java/org/apache/tomcat/websocket/WsFrameBase.java | 7 +++++++
- webapps/docs/changelog.xml | 8 ++++++++
- 3 files changed, 16 insertions(+)
-
-diff --git a/java/org/apache/tomcat/websocket/LocalStrings.properties b/java/org/apache/tomcat/websocket/LocalStrings.properties
-index 9412ffeb61..929822d94c 100644
---- a/java/org/apache/tomcat/websocket/LocalStrings.properties
-+++ b/java/org/apache/tomcat/websocket/LocalStrings.properties
-@@ -70,6 +70,7 @@ wsFrame.noContinuation=A new message was started when a continuation frame was e
- wsFrame.notMasked=The client frame was not masked but all client frames must be masked
- wsFrame.oneByteCloseCode=The client sent a close frame with a single byte payload which is not valid
- wsFrame.partialHeaderComplete=WebSocket frame received. fin [{0}], rsv [{1}], OpCode [{2}], payload length [{3}]
-+wsFrame.payloadMsbInvalid=An invalid WebSocket frame was received - the most significant bit of a 64-bit payload was illegally set
- wsFrame.sessionClosed=The client data cannot be processed because the session has already been closed
- wsFrame.suspendRequested=Suspend of the message receiving has already been requested.
- wsFrame.textMessageTooBig=The decoded text message was too big for the output buffer and the endpoint does not support partial messages
-diff --git a/java/org/apache/tomcat/websocket/WsFrameBase.java b/java/org/apache/tomcat/websocket/WsFrameBase.java
-index 28cdc30036..4afad67534 100644
---- a/java/org/apache/tomcat/websocket/WsFrameBase.java
-+++ b/java/org/apache/tomcat/websocket/WsFrameBase.java
-@@ -261,6 +261,13 @@ private boolean processRemainingHeader() throws IOException {
- } else if (payloadLength == 127) {
- payloadLength = byteArrayToLong(inputBuffer.array(),
- inputBuffer.arrayOffset() + inputBuffer.position(), 8);
-+ // The most significant bit of those 8 bytes is required to be zero
-+ // (see RFC 6455, section 5.2). If the most significant bit is set,
-+ // the resulting payload length will be negative so test for that.
-+ if (payloadLength < 0) {
-+ throw new WsIOException(
-+ new CloseReason(CloseCodes.PROTOCOL_ERROR, sm.getString("wsFrame.payloadMsbInvalid")));
-+ }
- inputBuffer.position(inputBuffer.position() + 8);
- }
- if (Util.isControl(opCode)) {
-diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
-index e75f367171..1d1a735c7e 100644
---- a/webapps/docs/changelog.xml
-+++ b/webapps/docs/changelog.xml
-@@ -127,6 +127,14 @@
-
-
-
-+
-+
-+
-+ 64563: Add additional validation of payload length for
-+ WebSocket messages. (markt)
-+
-+
-+
-
-
-
diff --git a/CVE-2020-13943-1.patch b/CVE-2020-13943-1.patch
deleted file mode 100644
index e2aa440..0000000
--- a/CVE-2020-13943-1.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 863b18e34f12085820ad02e86ca0ef7e961bb471 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Wed, 7 Aug 2019 18:59:07 +0100
-Subject: [PATCH 1/5] Extend the timeout functionality to internal upgrade
- processors
-
----
- .../coyote/http11/upgrade/InternalHttpUpgradeHandler.java | 2 ++
- .../coyote/http11/upgrade/UpgradeProcessorInternal.java | 6 ++++++
- java/org/apache/coyote/http2/Http2UpgradeHandler.java | 6 ++++++
- .../tomcat/websocket/server/WsHttpUpgradeHandler.java | 6 ++++++
- .../coyote/http11/upgrade/TestUpgradeInternalHandler.java | 5 +++++
- 5 files changed, 25 insertions(+)
-
-diff --git a/java/org/apache/coyote/http11/upgrade/InternalHttpUpgradeHandler.java b/java/org/apache/coyote/http11/upgrade/InternalHttpUpgradeHandler.java
-index 936784e20c..426b1bdb89 100644
---- a/java/org/apache/coyote/http11/upgrade/InternalHttpUpgradeHandler.java
-+++ b/java/org/apache/coyote/http11/upgrade/InternalHttpUpgradeHandler.java
-@@ -32,6 +32,8 @@ public interface InternalHttpUpgradeHandler extends HttpUpgradeHandler {
-
- SocketState upgradeDispatch(SocketEvent status);
-
-+ void timeoutAsync(long now);
-+
- void setSocketWrapper(SocketWrapperBase> wrapper);
-
- void setSslSupport(SSLSupport sslSupport);
-diff --git a/java/org/apache/coyote/http11/upgrade/UpgradeProcessorInternal.java b/java/org/apache/coyote/http11/upgrade/UpgradeProcessorInternal.java
-index 6397a72a53..f0f546072d 100644
---- a/java/org/apache/coyote/http11/upgrade/UpgradeProcessorInternal.java
-+++ b/java/org/apache/coyote/http11/upgrade/UpgradeProcessorInternal.java
-@@ -73,6 +73,12 @@ public class UpgradeProcessorInternal extends UpgradeProcessorBase {
- }
-
-
-+ @Override
-+ public void timeoutAsync(long now) {
-+ internalHttpUpgradeHandler.timeoutAsync(now);
-+ }
-+
-+
- // --------------------------------------------------- AutoCloseable methods
-
- @Override
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index 6206f5f5f2..da724652aa 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -388,6 +388,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- }
-
-
-+ @Override
-+ public void timeoutAsync(long now) {
-+ // TODO: Implement improved connection timeouts
-+ }
-+
-+
- ConnectionSettingsRemote getRemoteSettings() {
- return remoteSettings;
- }
-diff --git a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
-index 0cde0e3672..5dd1c5a68c 100644
---- a/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
-+++ b/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java
-@@ -189,6 +189,12 @@ public class WsHttpUpgradeHandler implements InternalHttpUpgradeHandler {
- }
-
-
-+ @Override
-+ public void timeoutAsync(long now) {
-+ // NO-OP
-+ }
-+
-+
- @Override
- public void pause() {
- // NO-OP
-diff --git a/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java b/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java
-index 367f06f5b3..183a8dac7f 100644
---- a/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java
-+++ b/test/org/apache/coyote/http11/upgrade/TestUpgradeInternalHandler.java
-@@ -256,6 +256,11 @@ public class TestUpgradeInternalHandler extends TomcatBaseTest {
- return SocketState.UPGRADED;
- }
-
-+ @Override
-+ public void timeoutAsync(long now) {
-+ // NO-OP
-+ }
-+
- @Override
- public void setSocketWrapper(SocketWrapperBase> wrapper) {
- this.wrapper = wrapper;
---
-2.23.0
-
diff --git a/CVE-2020-13943-2.patch b/CVE-2020-13943-2.patch
deleted file mode 100644
index d29bf38..0000000
--- a/CVE-2020-13943-2.patch
+++ /dev/null
@@ -1,82 +0,0 @@
-From 38ef1f624aaf045458b6fe055742fa680a96a9e1 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Thu, 7 Mar 2019 10:50:05 +0000
-Subject: [PATCH 2/5] Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63223
-
----
- java/org/apache/coyote/http2/Http2UpgradeHandler.java | 8 ++++++++
- java/org/apache/coyote/http2/Stream.java | 5 +++++
- java/org/apache/coyote/http2/StreamStateMachine.java | 8 +++++++-
- 3 files changed, 20 insertions(+), 1 deletion(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index da724652aa..2330d12e09 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -555,6 +555,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- synchronized (socketWrapper) {
- doWriteHeaders(stream, pushedStreamId, mimeHeaders, endOfStream, payloadSize);
- }
-+ stream.sentHeaders();
- if (endOfStream) {
- stream.sentEndOfStream();
- }
-@@ -1178,6 +1179,13 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
-
-
- void push(Request request, Stream associatedStream) throws IOException {
-+ if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
-+ // If there are too many open streams, simply ignore the push
-+ // request.
-+ activeRemoteStreamCount.decrementAndGet();
-+ return;
-+ }
-+
- Stream pushStream;
-
- // Synchronized since PUSH_PROMISE frames have to be sent in order. Once
-diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java
-index 43aee9d656..629d0210b4 100644
---- a/java/org/apache/coyote/http2/Stream.java
-+++ b/java/org/apache/coyote/http2/Stream.java
-@@ -561,6 +561,11 @@ class Stream extends AbstractStream implements HeaderEmitter {
- }
-
-
-+ final void sentHeaders() {
-+ state.sentHeaders();
-+ }
-+
-+
- final void sentEndOfStream() {
- streamOutputBuffer.endOfStreamSent = true;
- state.sentEndOfStream();
-diff --git a/java/org/apache/coyote/http2/StreamStateMachine.java b/java/org/apache/coyote/http2/StreamStateMachine.java
-index 3b67f865d3..d19bb0a255 100644
---- a/java/org/apache/coyote/http2/StreamStateMachine.java
-+++ b/java/org/apache/coyote/http2/StreamStateMachine.java
-@@ -53,6 +53,12 @@ class StreamStateMachine {
- }
-
-
-+ final synchronized void sentHeaders() {
-+ // No change if currently OPEN
-+ stateChange(State.RESERVED_LOCAL, State.HALF_CLOSED_REMOTE);
-+ }
-+
-+
- final synchronized void receivedStartOfHeaders() {
- stateChange(State.IDLE, State.OPEN);
- stateChange(State.RESERVED_REMOTE, State.HALF_CLOSED_LOCAL);
-@@ -170,7 +176,7 @@ class StreamStateMachine {
- Http2Error.PROTOCOL_ERROR, FrameType.PRIORITY,
- FrameType.RST,
- FrameType.WINDOW_UPDATE),
-- RESERVED_REMOTE (false, false, true, true,
-+ RESERVED_REMOTE (false, true, true, true,
- Http2Error.PROTOCOL_ERROR, FrameType.HEADERS,
- FrameType.PRIORITY,
- FrameType.RST),
---
-2.23.0
-
diff --git a/CVE-2020-13943-3.patch b/CVE-2020-13943-3.patch
deleted file mode 100644
index a52ab3c..0000000
--- a/CVE-2020-13943-3.patch
+++ /dev/null
@@ -1,220 +0,0 @@
-From 5d7f2eac857cc75757cfc58d003fbf17a23c2720 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Wed, 7 Aug 2019 17:02:37 +0100
-Subject: [PATCH 3/5] Improve HTTP/2 connection timeout handling
-
----
- .../http2/Http2AsyncUpgradeHandler.java | 6 +-
- .../coyote/http2/Http2UpgradeHandler.java | 93 ++++++++++++++-----
- 2 files changed, 73 insertions(+), 26 deletions(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
-index ba49986b5b..107d4bedd2 100644
---- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
-@@ -191,7 +191,7 @@ public class Http2AsyncUpgradeHandler extends Http2UpgradeHandler {
- header[4] = FLAG_END_OF_STREAM;
- stream.sentEndOfStream();
- if (!stream.isActive()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- }
- }
- if (writeable) {
-@@ -297,7 +297,7 @@ public class Http2AsyncUpgradeHandler extends Http2UpgradeHandler {
- header[4] = FLAG_END_OF_STREAM;
- sendfile.stream.sentEndOfStream();
- if (!sendfile.stream.isActive()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- }
- }
- if (writeable) {
-@@ -358,7 +358,7 @@ public class Http2AsyncUpgradeHandler extends Http2UpgradeHandler {
- header[4] = FLAG_END_OF_STREAM;
- sendfile.stream.sentEndOfStream();
- if (!sendfile.stream.isActive()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- }
- }
- if (writeable) {
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index 2330d12e09..9c18bf0ca8 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -133,6 +133,9 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- // Tracking for when the connection is blocked (windowSize < 1)
- private final Map backLogStreams = new ConcurrentHashMap<>();
- private long backLogSize = 0;
-+ // The time at which the connection will timeout unless data arrives before
-+ // then. -1 means no timeout.
-+ private volatile long connectionTimeout = -1;
-
- // Stream concurrency control
- private AtomicInteger streamConcurrency = null;
-@@ -313,8 +316,10 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- case OPEN_READ:
- try {
- // There is data to read so use the read timeout while
-- // reading frames.
-+ // reading frames ...
- socketWrapper.setReadTimeout(protocol.getReadTimeout());
-+ // ... and disable the connection timeout
-+ setConnectionTimeout(-1);
- while (true) {
- try {
- if (!parser.readFrame(false)) {
-@@ -330,23 +335,22 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- stream.close(se);
- }
- }
-+ if (overheadCount.get() > 0) {
-+ throw new ConnectionException(
-+ sm.getString("upgradeHandler.tooMuchOverhead", connectionId),
-+ Http2Error.ENHANCE_YOUR_CALM);
-+ }
- }
-
-- if (overheadCount.get() > 0) {
-- throw new ConnectionException(
-- sm.getString("upgradeHandler.tooMuchOverhead", connectionId),
-- Http2Error.ENHANCE_YOUR_CALM);
-- }
-+ // Need to know the correct timeout before starting the read
-+ // but that may not be known at this time if one or more
-+ // requests are currently being processed so don't set a
-+ // timeout for the socket...
-+ socketWrapper.setReadTimeout(-1);
-+
-+ // ...set a timeout on the connection
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.get());
-
-- if (activeRemoteStreamCount.get() == 0) {
-- // No streams currently active. Use the keep-alive
-- // timeout for the connection.
-- socketWrapper.setReadTimeout(protocol.getKeepAliveTimeout());
-- } else {
-- // Streams currently active. Individual streams have
-- // timeouts so keep the connection open.
-- socketWrapper.setReadTimeout(-1);
-- }
- } catch (Http2Exception ce) {
- // Really ConnectionException
- if (log.isDebugEnabled()) {
-@@ -367,9 +371,12 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- result = SocketState.UPGRADED;
- break;
-
-+ case TIMEOUT:
-+ closeConnection(null);
-+ break;
-+
- case DISCONNECT:
- case ERROR:
-- case TIMEOUT:
- case STOP:
- close();
- break;
-@@ -388,9 +395,41 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- }
-
-
-+ /*
-+ * Sets the connection timeout based on the current number of active
-+ * streams.
-+ */
-+ protected void setConnectionTimeoutForStreamCount(int streamCount) {
-+ if (streamCount == 0) {
-+ // No streams currently active. Use the keep-alive
-+ // timeout for the connection.
-+ long keepAliveTimeout = protocol.getKeepAliveTimeout();
-+ if (keepAliveTimeout == -1) {
-+ setConnectionTimeout(-1);
-+ } else {
-+ setConnectionTimeout(System.currentTimeMillis() + keepAliveTimeout);
-+ }
-+ } else {
-+ // Streams currently active. Individual streams have
-+ // timeouts so keep the connection open.
-+ setConnectionTimeout(-1);
-+ }
-+ }
-+
-+
-+ private void setConnectionTimeout(long connectionTimeout) {
-+ this.connectionTimeout = connectionTimeout;
-+ }
-+
-+
- @Override
- public void timeoutAsync(long now) {
-- // TODO: Implement improved connection timeouts
-+ long connectionTimeout = this.connectionTimeout;
-+ if (now == -1 || connectionTimeout > -1 && now > connectionTimeout) {
-+ // Have to dispatch as this will be executed from a non-container
-+ // thread.
-+ socketWrapper.processSocket(SocketEvent.TIMEOUT, true);
-+ }
- }
-
-
-@@ -499,9 +538,17 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
-
-
- void closeConnection(Http2Exception ce) {
-+ long code;
-+ byte[] msg;
-+ if (ce == null) {
-+ code = Http2Error.NO_ERROR.getCode();
-+ msg = null;
-+ } else {
-+ code = ce.getError().getCode();
-+ msg = ce.getMessage().getBytes(StandardCharsets.UTF_8);
-+ }
- try {
-- writeGoAwayFrame(maxProcessedStreamId, ce.getError().getCode(),
-- ce.getMessage().getBytes(StandardCharsets.UTF_8));
-+ writeGoAwayFrame(maxProcessedStreamId, code, msg);
- } catch (IOException ioe) {
- // Ignore. GOAWAY is sent on a best efforts basis and the original
- // error has already been logged.
-@@ -665,7 +712,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- header[4] = FLAG_END_OF_STREAM;
- stream.sentEndOfStream();
- if (!stream.isActive()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- }
- }
- if (writeable) {
-@@ -1182,7 +1229,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
- // If there are too many open streams, simply ignore the push
- // request.
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- return;
- }
-
-@@ -1301,7 +1348,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- if (stream != null) {
- stream.receivedEndOfStream();
- if (!stream.isActive()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- }
- }
- }
-@@ -1340,7 +1387,7 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- stream.receivedStartOfHeaders(headersEndStream);
- closeIdleStreams(streamId);
- if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
-- activeRemoteStreamCount.decrementAndGet();
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
- throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
- Long.toString(localSettings.getMaxConcurrentStreams())),
- Http2Error.REFUSED_STREAM, streamId);
---
-2.23.0
-
diff --git a/CVE-2020-13943-4.patch b/CVE-2020-13943-4.patch
deleted file mode 100644
index b10cb40..0000000
--- a/CVE-2020-13943-4.patch
+++ /dev/null
@@ -1,114 +0,0 @@
-From 902356dc34097b50eb6ca3a74443be466e991a77 Mon Sep 17 00:00:00 2001
-From: wangxiao65 <287608437@qq.com>
-Date: Wed, 2 Dec 2020 11:07:21 +0800
-Subject: [PATCH] CVE-2020-13943
-
----
- java/org/apache/coyote/http2/Http2Parser.java | 2 +-
- .../coyote/http2/Http2UpgradeHandler.java | 20 ++++++++++++-------
- .../coyote/http2/TestHttp2Section_5_1.java | 20 ++++++++++++-------
- 3 files changed, 27 insertions(+), 15 deletions(-)
-
-diff --git a/java/org/apache/coyote/http2/Http2Parser.java b/java/org/apache/coyote/http2/Http2Parser.java
-index f5e19865b2..6ec659d1e0 100644
---- a/java/org/apache/coyote/http2/Http2Parser.java
-+++ b/java/org/apache/coyote/http2/Http2Parser.java
-@@ -721,7 +721,7 @@ class Http2Parser {
- // Header frames
- HeaderEmitter headersStart(int streamId, boolean headersEndStream)
- throws Http2Exception, IOException;
-- void headersEnd(int streamId) throws ConnectionException;
-+ void headersEnd(int streamId) throws Http2Exception;
-
- // Priority frames (also headers)
- void reprioritise(int streamId, int parentStreamId, boolean exclusive, int weight)
-diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-index 9c18bf0ca8..af10cd0838 100644
---- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
-@@ -1386,12 +1386,6 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
- stream.checkState(FrameType.HEADERS);
- stream.receivedStartOfHeaders(headersEndStream);
- closeIdleStreams(streamId);
-- if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
-- setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
-- throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
-- Long.toString(localSettings.getMaxConcurrentStreams())),
-- Http2Error.REFUSED_STREAM, streamId);
-- }
- return stream;
- } else {
- if (log.isDebugEnabled()) {
-@@ -1439,12 +1433,24 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
-
-
- @Override
-- public void headersEnd(int streamId) throws ConnectionException {
-+ public void headersEnd(int streamId) throws Http2Exception {
- Stream stream = getStream(streamId, connectionState.get().isNewStreamAllowed());
- if (stream != null) {
- setMaxProcessedStream(streamId);
- if (stream.isActive()) {
- if (stream.receivedEndOfHeaders()) {
-+
-+ if (localSettings.getMaxConcurrentStreams() < activeRemoteStreamCount.incrementAndGet()) {
-+ setConnectionTimeoutForStreamCount(activeRemoteStreamCount.decrementAndGet());
-+ // Ignoring maxConcurrentStreams increases the overhead count
-+ increaseOverheadCount();
-+ throw new StreamException(sm.getString("upgradeHandler.tooManyRemoteStreams",
-+ Long.toString(localSettings.getMaxConcurrentStreams())),
-+ Http2Error.REFUSED_STREAM, streamId);
-+ }
-+ // Valid new stream reduces the overhead count
-+ reduceOverheadCount();
-+
- processStreamOnContainerThread(stream);
- }
- }
-diff --git a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-index f878653ecf..0b937a9fb9 100644
---- a/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-+++ b/test/org/apache/coyote/http2/TestHttp2Section_5_1.java
-@@ -222,11 +222,11 @@ public class TestHttp2Section_5_1 extends Http2TestBase {
- // Expecting
- // 1 * headers
- // 56k-1 of body (7 * ~8k)
-- // 1 * error (could be in any order)
-- for (int i = 0; i < 8; i++) {
-+ // 1 * error
-+ // for a total of 9 frames (could be in any order)
-+ for (int i = 0; i < 9; i++) {
- parser.readFrame(true);
- }
-- parser.readFrame(true);
-
- Assert.assertTrue(output.getTrace(),
- output.getTrace().contains("5-RST-[" +
-@@ -238,14 +238,20 @@ public class TestHttp2Section_5_1 extends Http2TestBase {
-
- // Release the remaining body
- sendWindowUpdate(0, (1 << 31) - 2);
-- // Allow for the 8k still in the stream window
-+ // Allow for the ~8k still in the stream window
- sendWindowUpdate(3, (1 << 31) - 8193);
-
-- // 192k of body (24 * 8k)
-- // 1 * error (could be in any order)
-- for (int i = 0; i < 24; i++) {
-+ // Read until the end of stream 3
-+ while (!output.getTrace().contains("3-EndOfStream")) {
- parser.readFrame(true);
- }
-+ output.clearTrace();
-+
-+ // Confirm another request can be sent once concurrency falls back below limit
-+ sendSimpleGetRequest(7);
-+ parser.readFrame(true);
-+ parser.readFrame(true);
-+ Assert.assertEquals(getSimpleResponseTrace(7), output.getTrace());
- }
-
-
---
-2.23.0
-
diff --git a/CVE-2020-17527.patch b/CVE-2020-17527.patch
deleted file mode 100644
index f1fafa3..0000000
--- a/CVE-2020-17527.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From d56293f816d6dc9e2b47107f208fa9e95db58c65 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Mon, 9 Nov 2020 19:23:12 +0000
-Subject: [PATCH] Fix BZ 64830 - concurrency issue in HPACK decoder
-
-https://bz.apache.org/bugzilla/show_bug.cgi?id=64830
----
- java/org/apache/coyote/http2/HpackDecoder.java | 12 ++++--------
- 1 files changed, 4 insertions(+), 8 deletions(-)
-
-diff --git a/java/org/apache/coyote/http2/HpackDecoder.java b/java/org/apache/coyote/http2/HpackDecoder.java
-index 551101b33a..517dc0b4ae 100644
---- a/java/org/apache/coyote/http2/HpackDecoder.java
-+++ b/java/org/apache/coyote/http2/HpackDecoder.java
-@@ -72,8 +72,6 @@
- private volatile boolean countedCookie;
- private volatile int headerSize = 0;
-
-- private final StringBuilder stringBuilder = new StringBuilder();
--
- HpackDecoder(int maxMemorySize) {
- this.maxMemorySizeHard = maxMemorySize;
- this.maxMemorySizeSoft = maxMemorySize;
-@@ -222,19 +220,17 @@ private String readHpackString(ByteBuffer buffer) throws HpackException {
- if (huffman) {
- return readHuffmanString(length, buffer);
- }
-+ StringBuilder stringBuilder = new StringBuilder(length);
- for (int i = 0; i < length; ++i) {
- stringBuilder.append((char) buffer.get());
- }
-- String ret = stringBuilder.toString();
-- stringBuilder.setLength(0);
-- return ret;
-+ return stringBuilder.toString();
- }
-
- private String readHuffmanString(int length, ByteBuffer buffer) throws HpackException {
-+ StringBuilder stringBuilder = new StringBuilder(length);
- HPackHuffman.decode(buffer, length, stringBuilder);
-- String ret = stringBuilder.toString();
-- stringBuilder.setLength(0);
-- return ret;
-+ return stringBuilder.toString();
- }
-
- private String handleIndexedHeaderName(int index) throws HpackException {
diff --git a/CVE-2020-1935.patch b/CVE-2020-1935.patch
deleted file mode 100644
index 033c655..0000000
--- a/CVE-2020-1935.patch
+++ /dev/null
@@ -1,443 +0,0 @@
-From 8bfb0ff7f25fe7555a5eb2f7984f73546c11aa26 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Mon, 6 Jan 2020 20:53:25 +0000
-Subject: [PATCH] Stricter header value parsing
-
----
- .../coyote/http11/AbstractHttp11Protocol.java | 51 ++++++++++---
- .../coyote/http11/Http11InputBuffer.java | 51 +++++++++----
- .../apache/coyote/http11/Http11Processor.java | 2 +-
- .../apache/tomcat/util/http/MimeHeaders.java | 2 +-
- .../tomcat/util/http/parser/HttpParser.java | 11 +++
- .../coyote/http11/TestHttp11InputBuffer.java | 74 +++++++++++++++----
- webapps/docs/config/http.xml | 11 ++-
- 8 files changed, 164 insertions(+), 43 deletions(-)
-
-diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
-index e5ab885..9d10cbf 100644
---- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
-+++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
-@@ -136,27 +136,56 @@ public abstract class AbstractHttp11Protocol extends AbstractProtocol {
- }
-
-
-- private boolean rejectIllegalHeaderName = true;
-+ private boolean rejectIllegalHeader = true;
- /**
-- * If an HTTP request is received that contains an illegal header name (i.e.
-- * the header name is not a token) will the request be rejected (with a 400
-- * response) or will the illegal header be ignored.
-+ * If an HTTP request is received that contains an illegal header name or
-+ * value (e.g. the header name is not a token) will the request be rejected
-+ * (with a 400 response) or will the illegal header be ignored?
- *
- * @return {@code true} if the request will be rejected or {@code false} if
- * the header will be ignored
- */
-- public boolean getRejectIllegalHeaderName() { return rejectIllegalHeaderName; }
-+ public boolean getRejectIllegalHeader() { return rejectIllegalHeader; }
- /**
-- * If an HTTP request is received that contains an illegal header name (i.e.
-- * the header name is not a token) should the request be rejected (with a
-- * 400 response) or should the illegal header be ignored.
-+ * If an HTTP request is received that contains an illegal header name or
-+ * value (e.g. the header name is not a token) should the request be
-+ * rejected (with a 400 response) or should the illegal header be ignored?
-+ *
-+ * @param rejectIllegalHeader {@code true} to reject requests with illegal
-+ * header names or values, {@code false} to
-+ * ignore the header
-+ */
-+ public void setRejectIllegalHeader(boolean rejectIllegalHeader) {
-+ this.rejectIllegalHeader = rejectIllegalHeader;
-+ }
-+ /**
-+ * If an HTTP request is received that contains an illegal header name or
-+ * value (e.g. the header name is not a token) will the request be rejected
-+ * (with a 400 response) or will the illegal header be ignored?
-+ *
-+ * @return {@code true} if the request will be rejected or {@code false} if
-+ * the header will be ignored
-+ *
-+ * @deprecated Now an alias for {@link #getRejectIllegalHeader()}. Will be
-+ * removed in Tomcat 10 onwards.
-+ */
-+ @Deprecated
-+ public boolean getRejectIllegalHeaderName() { return rejectIllegalHeader; }
-+ /**
-+ * If an HTTP request is received that contains an illegal header name or
-+ * value (e.g. the header name is not a token) should the request be
-+ * rejected (with a 400 response) or should the illegal header be ignored?
- *
- * @param rejectIllegalHeaderName {@code true} to reject requests with
-- * illegal header names, {@code false} to
-- * ignore the header
-+ * illegal header names or values,
-+ * {@code false} to ignore the header
-+ *
-+ * @deprecated Now an alias for {@link #setRejectIllegalHeader(boolean)}.
-+ * Will be removed in Tomcat 10 onwards.
- */
-+ @Deprecated
- public void setRejectIllegalHeaderName(boolean rejectIllegalHeaderName) {
-- this.rejectIllegalHeaderName = rejectIllegalHeaderName;
-+ this.rejectIllegalHeader = rejectIllegalHeaderName;
- }
-
-
-diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java b/java/org/apache/coyote/http11/Http11InputBuffer.java
-index 2dc7c17..57c670e 100644
---- a/java/org/apache/coyote/http11/Http11InputBuffer.java
-+++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
-@@ -64,7 +64,7 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- private final MimeHeaders headers;
-
-
-- private final boolean rejectIllegalHeaderName;
-+ private final boolean rejectIllegalHeader;
-
- /**
- * State.
-@@ -150,13 +150,13 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- // ----------------------------------------------------------- Constructors
-
- public Http11InputBuffer(Request request, int headerBufferSize,
-- boolean rejectIllegalHeaderName, HttpParser httpParser) {
-+ boolean rejectIllegalHeader, HttpParser httpParser) {
-
- this.request = request;
- headers = request.getMimeHeaders();
-
- this.headerBufferSize = headerBufferSize;
-- this.rejectIllegalHeaderName = rejectIllegalHeaderName;
-+ this.rejectIllegalHeader = rejectIllegalHeader;
- this.httpParser = httpParser;
-
- filterLibrary = new InputFilter[0];
-@@ -752,6 +752,8 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- //
-
- byte chr = 0;
-+ byte prevChr = 0;
-+
- while (headerParsePos == HeaderParsePosition.HEADER_START) {
-
- // Read new bytes if needed
-@@ -762,17 +764,23 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- }
- }
-
-+ prevChr = chr;
- chr = byteBuffer.get();
-
-- if (chr == Constants.CR) {
-- // Skip
-- } else if (chr == Constants.LF) {
-+ if (chr == Constants.CR && prevChr != Constants.CR) {
-+ // Possible start of CRLF - process the next byte.
-+ } else if (prevChr == Constants.CR && chr == Constants.LF) {
- return HeaderParseStatus.DONE;
- } else {
-- byteBuffer.position(byteBuffer.position() - 1);
-+ if (prevChr == 0) {
-+ // Must have only read one byte
-+ byteBuffer.position(byteBuffer.position() - 1);
-+ } else {
-+ // Must have read two bytes (first was CR, second was not LF)
-+ byteBuffer.position(byteBuffer.position() - 2);
-+ }
- break;
- }
--
- }
-
- if (headerParsePos == HeaderParsePosition.HEADER_START) {
-@@ -868,11 +876,22 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- }
- }
-
-+ prevChr = chr;
- chr = byteBuffer.get();
- if (chr == Constants.CR) {
-- // Skip
-- } else if (chr == Constants.LF) {
-+ // Possible start of CRLF - process the next byte.
-+ } else if (prevChr == Constants.CR && chr == Constants.LF) {
- eol = true;
-+ } else if (prevChr == Constants.CR) {
-+ // Invalid value
-+ // Delete the header (it will be the most recent one)
-+ headers.removeHeader(headers.size() - 1);
-+ return skipLine();
-+ } else if (chr != Constants.HT && HttpParser.isControl(chr)) {
-+ // Invalid value
-+ // Delete the header (it will be the most recent one)
-+ headers.removeHeader(headers.size() - 1);
-+ return skipLine();
- } else if (chr == Constants.SP || chr == Constants.HT) {
- byteBuffer.put(headerData.realPos, chr);
- headerData.realPos++;
-@@ -924,6 +943,9 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- headerParsePos = HeaderParsePosition.HEADER_SKIPLINE;
- boolean eol = false;
-
-+ byte chr = 0;
-+ byte prevChr = 0;
-+
- // Reading bytes until the end of the line
- while (!eol) {
-
-@@ -935,21 +957,22 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
- }
-
- int pos = byteBuffer.position();
-- byte chr = byteBuffer.get();
-+ prevChr = chr;
-+ chr = byteBuffer.get();
- if (chr == Constants.CR) {
- // Skip
-- } else if (chr == Constants.LF) {
-+ } else if (prevChr == Constants.CR && chr == Constants.LF) {
- eol = true;
- } else {
- headerData.lastSignificantChar = pos;
- }
- }
-- if (rejectIllegalHeaderName || log.isDebugEnabled()) {
-+ if (rejectIllegalHeader || log.isDebugEnabled()) {
- String message = sm.getString("iib.invalidheader",
- new String(byteBuffer.array(), headerData.start,
- headerData.lastSignificantChar - headerData.start + 1,
- StandardCharsets.ISO_8859_1));
-- if (rejectIllegalHeaderName) {
-+ if (rejectIllegalHeader) {
- throw new IllegalArgumentException(message);
- }
- log.debug(message);
-diff --git a/java/org/apache/coyote/http11/Http11Processor.java b/java/org/apache/coyote/http11/Http11Processor.java
-index df002e0..86556ec 100644
---- a/java/org/apache/coyote/http11/Http11Processor.java
-+++ b/java/org/apache/coyote/http11/Http11Processor.java
-@@ -153,7 +153,7 @@ public class Http11Processor extends AbstractProcessor {
- protocol.getRelaxedQueryChars());
-
- inputBuffer = new Http11InputBuffer(request, protocol.getMaxHttpHeaderSize(),
-- protocol.getRejectIllegalHeaderName(), httpParser);
-+ protocol.getRejectIllegalHeader(), httpParser);
- request.setInputBuffer(inputBuffer);
-
- outputBuffer = new Http11OutputBuffer(response, protocol.getMaxHttpHeaderSize());
-diff --git a/java/org/apache/tomcat/util/http/MimeHeaders.java b/java/org/apache/tomcat/util/http/MimeHeaders.java
-index 59504ee..b76b274 100644
---- a/java/org/apache/tomcat/util/http/MimeHeaders.java
-+++ b/java/org/apache/tomcat/util/http/MimeHeaders.java
-@@ -396,7 +396,7 @@ public class MimeHeaders {
- * reset and swap with last header
- * @param idx the index of the header to remove.
- */
-- private void removeHeader(int idx) {
-+ public void removeHeader(int idx) {
- MimeHeaderField mh = headers[idx];
-
- mh.recycle();
-diff --git a/java/org/apache/tomcat/util/http/parser/HttpParser.java b/java/org/apache/tomcat/util/http/parser/HttpParser.java
-index 827f2c5..644b1d1 100644
---- a/java/org/apache/tomcat/util/http/parser/HttpParser.java
-+++ b/java/org/apache/tomcat/util/http/parser/HttpParser.java
-@@ -317,6 +317,17 @@ public class HttpParser {
- }
-
-
-+ public static boolean isControl(int c) {
-+ // Fast for valid control characters, slower for some incorrect
-+ // ones
-+ try {
-+ return IS_CONTROL[c];
-+ } catch (ArrayIndexOutOfBoundsException ex) {
-+ return false;
-+ }
-+ }
-+
-+
- // Skip any LWS and position to read the next character. The next character
- // is returned as being able to 'peek()' it allows a small optimisation in
- // some cases.
-diff --git a/test/org/apache/coyote/http11/TestHttp11InputBuffer.java b/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
-index 131fa21..e60a474 100644
---- a/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
-+++ b/test/org/apache/coyote/http11/TestHttp11InputBuffer.java
-@@ -163,13 +163,13 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
-
-
- @Test
-- public void testBug51557Separators() throws Exception {
-+ public void testBug51557SeparatorsInName() throws Exception {
- char httpSeparators[] = new char[] {
- '\t', ' ', '\"', '(', ')', ',', '/', ':', ';', '<',
- '=', '>', '?', '@', '[', '\\', ']', '{', '}' };
-
- for (char s : httpSeparators) {
-- doTestBug51557Char(s);
-+ doTestBug51557CharInName(s);
- tearDown();
- setUp();
- }
-@@ -177,13 +177,38 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
-
-
- @Test
-- public void testBug51557Ctl() throws Exception {
-+ public void testBug51557CtlInName() throws Exception {
- for (int i = 0; i < 31; i++) {
-- doTestBug51557Char((char) i);
-+ doTestBug51557CharInName((char) i);
-+ tearDown();
-+ setUp();
-+ }
-+ doTestBug51557CharInName((char) 127);
-+ }
-+
-+
-+ @Test
-+ public void testBug51557CtlInValue() throws Exception {
-+ for (int i = 0; i < 31; i++) {
-+ if (i == '\t') {
-+ // TAB is allowed
-+ continue;
-+ }
-+ doTestBug51557InvalidCharInValue((char) i);
-+ tearDown();
-+ setUp();
-+ }
-+ doTestBug51557InvalidCharInValue((char) 127);
-+ }
-+
-+
-+ @Test
-+ public void testBug51557ObsTextInValue() throws Exception {
-+ for (int i = 128; i < 255; i++) {
-+ doTestBug51557ValidCharInValue((char) i);
- tearDown();
- setUp();
- }
-- doTestBug51557Char((char) 127);
- }
-
-
-@@ -226,7 +251,7 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
- }
-
-
-- private void doTestBug51557Char(char s) {
-+ private void doTestBug51557CharInName(char s) {
- Bug51557Client client =
- new Bug51557Client("X-Bug" + s + "51557", "invalid");
-
-@@ -236,6 +261,29 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
- Assert.assertTrue(client.isResponseBodyOK());
- }
-
-+
-+ private void doTestBug51557InvalidCharInValue(char s) {
-+ Bug51557Client client =
-+ new Bug51557Client("X-Bug51557-Invalid", "invalid" + s + "invalid");
-+
-+ client.doRequest();
-+ Assert.assertTrue("Testing [" + (int) s + "]", client.isResponse200());
-+ Assert.assertEquals("Testing [" + (int) s + "]", "abcd", client.getResponseBody());
-+ Assert.assertTrue(client.isResponseBodyOK());
-+ }
-+
-+
-+ private void doTestBug51557ValidCharInValue(char s) {
-+ Bug51557Client client =
-+ new Bug51557Client("X-Bug51557-Valid", "valid" + s + "valid");
-+
-+ client.doRequest();
-+ Assert.assertTrue("Testing [" + (int) s + "]", client.isResponse200());
-+ Assert.assertEquals("Testing [" + (int) s + "]", "valid" + s + "validabcd", client.getResponseBody());
-+ Assert.assertTrue(client.isResponseBodyOK());
-+ }
-+
-+
- /**
- * Bug 51557 test client.
- */
-@@ -243,12 +291,12 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
-
- private final String headerName;
- private final String headerLine;
-- private final boolean rejectIllegalHeaderName;
-+ private final boolean rejectIllegalHeader;
-
- public Bug51557Client(String headerName) {
- this.headerName = headerName;
- this.headerLine = headerName;
-- this.rejectIllegalHeaderName = false;
-+ this.rejectIllegalHeader = false;
- }
-
- public Bug51557Client(String headerName, String headerValue) {
-@@ -256,10 +304,10 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
- }
-
- public Bug51557Client(String headerName, String headerValue,
-- boolean rejectIllegalHeaderName) {
-+ boolean rejectIllegalHeader) {
- this.headerName = headerName;
- this.headerLine = headerName + ": " + headerValue;
-- this.rejectIllegalHeaderName = rejectIllegalHeaderName;
-+ this.rejectIllegalHeader = rejectIllegalHeader;
- }
-
- private Exception doRequest() {
-@@ -273,8 +321,8 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
-
- try {
- Connector connector = tomcat.getConnector();
-- connector.setProperty("rejectIllegalHeaderName",
-- Boolean.toString(rejectIllegalHeaderName));
-+ connector.setProperty("rejectIllegalHeader",
-+ Boolean.toString(rejectIllegalHeader));
- tomcat.start();
- setPort(connector.getLocalPort());
-
-@@ -548,7 +596,7 @@ public class TestHttp11InputBuffer extends TomcatBaseTest {
-
- try {
- Connector connector = tomcat.getConnector();
-- connector.setProperty("rejectIllegalHeaderName", "false");
-+ connector.setProperty("rejectIllegalHeader", "false");
- tomcat.start();
- setPort(connector.getLocalPort());
-
-diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
-index ebb277d..3902c9a 100644
---- a/webapps/docs/config/http.xml
-+++ b/webapps/docs/config/http.xml
-@@ -551,14 +551,19 @@
- expected concurrent requests (synchronous and asynchronous).
-
-
--
--
If an HTTP request is received that contains an illegal header name
-- (i.e. the header name is not a token) this setting determines if the
-+
-+
If an HTTP request is received that contains an illegal header name or
-+ value (e.g. the header name is not a token) this setting determines if the
- request will be rejected with a 400 response (true) or if the
- illegal header be ignored (false). The default value is
- true which will cause the request to be rejected.
-
-
-+
-+
This attribute is deprecated. It will be removed in Tomcat 10 onwards.
-+ It is now an alias for rejectIllegalHeader.
-+
-+
-
-
The HTTP/1.1
- specification requires that certain characters are %nn encoded when
---
-2.23.0
-
diff --git a/CVE-2020-1938-1.patch b/CVE-2020-1938-1.patch
deleted file mode 100644
index c2feb27..0000000
--- a/CVE-2020-1938-1.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-From 0e8a50f0a5958744bea1fd6768c862e04d3b7e75 Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Tue, 21 Jan 2020 13:02:13 +0000
-Subject: [PATCH] Change the default bind address for AJP to the loopback
- address
-
----
- java/org/apache/coyote/ajp/AbstractAjpProtocol.java | 4 ++++
- webapps/docs/changelog.xml | 4 ++++
- webapps/docs/config/ajp.xml | 5 +----
- 3 files changed, 9 insertions(+), 4 deletions(-)
-
-diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-index 2500abd7ad..8e0593b771 100644
---- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-+++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-@@ -16,6 +16,8 @@
- */
- package org.apache.coyote.ajp;
-
-+import java.net.InetAddress;
-+
- import org.apache.coyote.AbstractProtocol;
- import org.apache.coyote.Processor;
- import org.apache.coyote.UpgradeProtocol;
-@@ -46,6 +48,8 @@ public AbstractAjpProtocol(AbstractEndpoint endpoint) {
- setConnectionTimeout(Constants.DEFAULT_CONNECTION_TIMEOUT);
- // AJP does not use Send File
- getEndpoint().setUseSendfile(false);
-+ // AJP listens on loopback by default
-+ getEndpoint().setAddress(InetAddress.getLoopbackAddress());
- ConnectionHandler cHandler = new ConnectionHandler<>(this);
- setHandler(cHandler);
- getEndpoint().setHandler(cHandler);
-diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
-index c70af91eae..5535a062e7 100644
---- a/webapps/docs/config/ajp.xml
-+++ b/webapps/docs/config/ajp.xml
-@@ -308,10 +308,7 @@
-
-
For servers with more than one IP address, this attribute
- specifies which address will be used for listening on the specified
-- port. By default, this port will be used on all IP addresses
-- associated with the server. A value of 127.0.0.1
-- indicates that the Connector will only listen on the loopback
-- interface.
-+ port. By default, the loopback address will be used.
-
-
-
diff --git a/CVE-2020-1938-2.patch b/CVE-2020-1938-2.patch
deleted file mode 100644
index cb57232..0000000
--- a/CVE-2020-1938-2.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-From 9ac90532e9a7d239f90952edb229b07c80a9a3eb Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Tue, 21 Jan 2020 14:24:33 +0000
-Subject: [PATCH] Rename requiredSecret to secret and add secretRequired
-
-AJP Connector will not start if secretRequired="true" and secret is set
-to null or zero length String.
----
- .../coyote/ajp/AbstractAjpProtocol.java | 49 +++++++++++++++++--
- java/org/apache/coyote/ajp/AjpProcessor.java | 12 ++---
- .../apache/coyote/ajp/LocalStrings.properties | 1 +
- webapps/docs/config/ajp.xml | 12 ++++-
- 5 files changed, 72 insertions(+), 10 deletions(-)
-
-diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-index 8e0593b771..81da7da6d1 100644
---- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-+++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-@@ -143,17 +143,48 @@ public void setTomcatAuthorization(boolean tomcatAuthorization) {
- }
-
-
-- private String requiredSecret = null;
-+ private String secret = null;
-+ /**
-+ * Set the secret that must be included with every request.
-+ *
-+ * @param secret The required secret
-+ */
-+ public void setSecret(String secret) {
-+ this.secret = secret;
-+ }
-+ protected String getSecret() {
-+ return secret;
-+ }
- /**
- * Set the required secret that must be included with every request.
- *
- * @param requiredSecret The required secret
-+ *
-+ * @deprecated Replaced by {@link #setSecret(String)}.
-+ * Will be removed in Tomcat 11 onwards
- */
-+ @Deprecated
- public void setRequiredSecret(String requiredSecret) {
-- this.requiredSecret = requiredSecret;
-+ setSecret(requiredSecret);
- }
-+ /**
-+ * @return The current secret
-+ *
-+ * @deprecated Replaced by {@link #getSecret()}.
-+ * Will be removed in Tomcat 11 onwards
-+ */
-+ @Deprecated
- protected String getRequiredSecret() {
-- return requiredSecret;
-+ return getSecret();
-+ }
-+
-+
-+ private boolean secretRequired = true;
-+ public void setSecretRequired(boolean secretRequired) {
-+ this.secretRequired = secretRequired;
-+ }
-+ public boolean getSecretRequired() {
-+ return secretRequired;
- }
-
-
-@@ -210,4 +241,16 @@ protected Processor createUpgradeProcessor(SocketWrapperBase> socket,
- throw new IllegalStateException(sm.getString("ajpprotocol.noUpgradeHandler",
- upgradeToken.getHttpUpgradeHandler().getClass().getName()));
- }
-+
-+
-+ @Override
-+ public void init() throws Exception {
-+ if (getSecretRequired()) {
-+ String secret = getSecret();
-+ if (secret == null || secret.length() == 0) {
-+ throw new IllegalArgumentException(sm.getString("ajpprotocol.nosecret"));
-+ }
-+ }
-+ super.init();
-+ }
- }
-diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java
-index a3e628d2eb..d466de2c09 100644
---- a/java/org/apache/coyote/ajp/AjpProcessor.java
-+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
-@@ -698,8 +698,8 @@ private void prepareRequest() {
- }
-
- // Decode extra attributes
-- String requiredSecret = protocol.getRequiredSecret();
-- boolean secret = false;
-+ String secret = protocol.getSecret();
-+ boolean secretPresentInRequest = false;
- byte attributeCode;
- while ((attributeCode = requestHeaderMessage.getByte())
- != Constants.SC_A_ARE_DONE) {
-@@ -801,9 +801,9 @@ private void prepareRequest() {
-
- case Constants.SC_A_SECRET:
- requestHeaderMessage.getBytes(tmpMB);
-- if (requiredSecret != null) {
-- secret = true;
-- if (!tmpMB.equals(requiredSecret)) {
-+ if (secret != null) {
-+ secretPresentInRequest = true;
-+ if (!tmpMB.equals(secret)) {
- response.setStatus(403);
- setErrorState(ErrorState.CLOSE_CLEAN, null);
- }
-@@ -819,7 +819,7 @@ private void prepareRequest() {
- }
-
- // Check if secret was submitted if required
-- if ((requiredSecret != null) && !secret) {
-+ if ((secret != null) && !secretPresentInRequest) {
- response.setStatus(403);
- setErrorState(ErrorState.CLOSE_CLEAN, null);
- }
-diff --git a/java/org/apache/coyote/ajp/LocalStrings.properties b/java/org/apache/coyote/ajp/LocalStrings.properties
-index 9b569bbc6e..01de92a424 100644
---- a/java/org/apache/coyote/ajp/LocalStrings.properties
-+++ b/java/org/apache/coyote/ajp/LocalStrings.properties
-@@ -28,6 +28,7 @@ ajpprocessor.request.prepare=Error preparing request
- # limitations under the License.
-
- ajpprotocol.noSSL=SSL is not supported with AJP. The SSL host configuration for [{0}] was ignored
-+ajpprotocol.nosecret=The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.
- ajpprotocol.noUpgrade=Upgrade is not supported with AJP. The UpgradeProtocol configuration for [{0}] was ignored
- ajpprotocol.noUpgradeHandler=Upgrade is not supported with AJP. The HttpUpgradeHandler [{0}] can not be processed
-
-diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
-index 5535a062e7..3999a13e66 100644
---- a/webapps/docs/config/ajp.xml
-+++ b/webapps/docs/config/ajp.xml
-@@ -428,8 +428,18 @@
- expected concurrent requests (synchronous and asynchronous).
-
-
--
-+
-
Only requests from workers with this secret keyword will be accepted.
-+ The default value is null. This attrbute must be specified
-+ with a non-null, non-zero length value unless
-+ secretRequired is explicitly configured to be
-+ false.
-+
-+
-+
-+
If this attribute is true, the AJP Connector will only
-+ start if the secret attribute is configured with a
-+ non-null, non-zero length value. The default value is true.
-
-
-
diff --git a/CVE-2020-1938-3.patch b/CVE-2020-1938-3.patch
deleted file mode 100644
index dc152a7..0000000
--- a/CVE-2020-1938-3.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From 64fa5b99442589ef0bf2a7fcd71ad2bc68b35fad Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Tue, 21 Jan 2020 15:04:12 +0000
-Subject: [PATCH] Add new AJP attribute allowedArbitraryRequestAttributes
-
-Requests with unrecognised attributes will be blocked with a 403
----
- .../coyote/ajp/AbstractAjpProtocol.java | 13 +++++++
- java/org/apache/coyote/ajp/AjpProcessor.java | 36 ++++++++++++++++++-
- webapps/docs/config/ajp.xml | 19 ++++++++++
- 4 files changed, 72 insertions(+), 1 deletion(-)
-
-diff --git a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-index 81da7da6d1..a2f5e2844a 100644
---- a/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-+++ b/java/org/apache/coyote/ajp/AbstractAjpProtocol.java
-@@ -17,6 +17,7 @@
- package org.apache.coyote.ajp;
-
- import java.net.InetAddress;
-+import java.util.regex.Pattern;
-
- import org.apache.coyote.AbstractProtocol;
- import org.apache.coyote.Processor;
-@@ -188,6 +189,18 @@ public boolean getSecretRequired() {
- }
-
-
-+ private Pattern allowedArbitraryRequestAttributesPattern;
-+ public void setAllowedArbitraryRequestAttributes(String allowedArbitraryRequestAttributes) {
-+ this.allowedArbitraryRequestAttributesPattern = Pattern.compile(allowedArbitraryRequestAttributes);
-+ }
-+ public String getAllowedArbitraryRequestAttributes() {
-+ return allowedArbitraryRequestAttributesPattern.pattern();
-+ }
-+ protected Pattern getAllowedArbitraryRequestAttributesPattern() {
-+ return allowedArbitraryRequestAttributesPattern;
-+ }
-+
-+
- /**
- * AJP packet size.
- */
-diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java
-index d466de2c09..f3d783f546 100644
---- a/java/org/apache/coyote/ajp/AjpProcessor.java
-+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
-@@ -25,6 +25,11 @@
- import java.security.NoSuchProviderException;
- import java.security.cert.CertificateFactory;
- import java.security.cert.X509Certificate;
-+import java.util.Collections;
-+import java.util.HashSet;
-+import java.util.Set;
-+import java.util.regex.Matcher;
-+import java.util.regex.Pattern;
-
- import javax.servlet.http.HttpServletResponse;
-
-@@ -78,6 +83,9 @@
- private static final byte[] pongMessageArray;
-
-
-+ private static final Set javaxAttributes;
-+
-+
- static {
- // Allocate the end message array
- AjpMessage endMessage = new AjpMessage(16);
-@@ -118,6 +126,14 @@
- pongMessageArray = new byte[pongMessage.getLen()];
- System.arraycopy(pongMessage.getBuffer(), 0, pongMessageArray,
- 0, pongMessage.getLen());
-+
-+ // Build the Set of javax attributes
-+ Set s = new HashSet<>();
-+ s.add("javax.servlet.request.cipher_suite");
-+ s.add("javax.servlet.request.key_size");
-+ s.add("javax.servlet.request.ssl_session");
-+ s.add("javax.servlet.request.X509Certificate");
-+ javaxAttributes= Collections.unmodifiableSet(s);
- }
-
-
-@@ -728,8 +744,26 @@ private void prepareRequest() {
- }
- } else if(n.equals(Constants.SC_A_SSL_PROTOCOL)) {
- request.setAttribute(SSLSupport.PROTOCOL_VERSION_KEY, v);
-+ } else if (n.equals("JK_LB_ACTIVATION")) {
-+ request.setAttribute(n, v);
-+ } else if (javaxAttributes.contains(n)) {
-+ request.setAttribute(n, v);
- } else {
-- request.setAttribute(n, v );
-+ // All 'known' attributes will be processed by the previous
-+ // blocks. Any remaining attribute is an 'arbitrary' one.
-+ Pattern pattern = protocol.getAllowedArbitraryRequestAttributesPattern();
-+ if (pattern == null) {
-+ response.setStatus(403);
-+ setErrorState(ErrorState.CLOSE_CLEAN, null);
-+ } else {
-+ Matcher m = pattern.matcher(n);
-+ if (m.matches()) {
-+ request.setAttribute(n, v);
-+ } else {
-+ response.setStatus(403);
-+ setErrorState(ErrorState.CLOSE_CLEAN, null);
-+ }
-+ }
- }
- break;
-
-diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
-index 3999a13e66..69348a18e2 100644
---- a/webapps/docs/config/ajp.xml
-+++ b/webapps/docs/config/ajp.xml
-@@ -311,6 +311,25 @@
- port. By default, the loopback address will be used.
-
-
-+
-+
The AJP protocol passes some information from the reverse proxy to the
-+ AJP connector using request attributes. These attributes are:
-+
-+
javax.servlet.request.cipher_suite
-+
javax.servlet.request.key_size
-+
javax.servlet.request.ssl_session
-+
javax.servlet.request.X509Certificate
-+
AJP_LOCAL_ADDR
-+
AJP_REMOTE_PORT
-+
AJP_SSL_PROTOCOL
-+
JK_LB_ACTIVATION
-+
-+
The AJP protocol supports the passing of arbitrary request attributes.
-+ Requests containing arbitrary request attributes will be rejected with a
-+ 403 response unless the entire attribute name matches this regular
-+ expression. If not specified, the default value is null.
-+
-+
-
-
Controls when the socket used by the connector is bound. By default it
- is bound when the connector is initiated and unbound when the connector is
diff --git a/CVE-2020-1938-4.patch b/CVE-2020-1938-4.patch
deleted file mode 100644
index e5e6108..0000000
--- a/CVE-2020-1938-4.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 5716044b61cb5b638d8f0de848ac64df03184bc7 Mon Sep 17 00:00:00 2001
-From: wang_yue111
-Date: Mon, 18 May 2020 15:23:19 +0800
-Subject: [PATCH] 3
-
----
- conf/server.xml | 5 ++++-
- .../apache/coyote/ajp/AbstractAjpProtocol.java | 18 +++++++++---------
- java/org/apache/coyote/ajp/AjpProcessor.java | 2 +-
- webapps/docs/config/ajp.xml | 2 +-
- 4 files changed, 15 insertions(+), 12 deletions(-)
-
-diff --git a/conf/server.xml b/conf/server.xml
-index fce8922..81a4e16 100644
---- a/conf/server.xml
-+++ b/conf/server.xml
-@@ -113,7 +113,10 @@
- -->
-
-
--
-+
-
-
-
-+
-+
-+
-+ Update the internal fork of Apache Commons FileUpload to 34eb241
-+ (2023-01-03, 2.0-SNAPSHOT). (markt)
-+
-+
-+
-
-
-
-diff --git a/webapps/docs/config/ajp.xml b/webapps/docs/config/ajp.xml
-index 622e7ca..38c5269 100644
---- a/webapps/docs/config/ajp.xml
-+++ b/webapps/docs/config/ajp.xml
-@@ -114,12 +114,15 @@
-
-
-
--
The maximum number of parameter and value pairs (GET plus POST) which
-- will be automatically parsed by the container. Parameter and value pairs
-- beyond this limit will be ignored. A value of less than 0 means no limit.
-- If not specified, a default of 10000 is used. Note that
-- FailedRequestFilterfilter can be
-- used to reject requests that hit the limit.
-+
The maximum total number of request parameters (including uploaded
-+ files) obtained from the query string and, for POST requests, the request
-+ body if the content type is
-+ application/x-www-form-urlencoded or
-+ multipart/form-data. Request parameters beyond this limit
-+ will be ignored. A value of less than 0 means no limit. If not specified,
-+ a default of 10000 is used. Note that FailedRequestFilter
-+ filter can be used to reject requests that
-+ exceed the limit.
The maximum number of parameter and value pairs (GET plus POST) which
-- will be automatically parsed by the container. Parameter and value pairs
-- beyond this limit will be ignored. A value of less than 0 means no limit.
-- If not specified, a default of 10000 is used. Note that
-- FailedRequestFilterfilter can be
-- used to reject requests that hit the limit.
-+
The maximum total number of request parameters (including uploaded
-+ files) obtained from the query string and, for POST requests, the request
-+ body if the content type is
-+ application/x-www-form-urlencoded or
-+ multipart/form-data. Request parameters beyond this limit
-+ will be ignored. A value of less than 0 means no limit. If not specified,
-+ a default of 10000 is used. Note that FailedRequestFilter
-+ filter can be used to reject requests that
-+ exceed the limit.
-
-
-
---
-2.33.0
diff --git a/CVE-2023-28708-pre.patch b/CVE-2023-28708-pre.patch
deleted file mode 100644
index 01ed17b..0000000
--- a/CVE-2023-28708-pre.patch
+++ /dev/null
@@ -1,238 +0,0 @@
-From 09e214c09c78a48ea96b0137555b3c2a98a1bfab Mon Sep 17 00:00:00 2001
-From: Mark Thomas
-Date: Tue, 31 Mar 2020 14:03:17 +0100
-Subject: [PATCH] Make the HTTP/2 connection ID and stream Id available to
- applications
-Origin: https://github.com/apache/tomcat/commit/09e214c09c78a48ea96b0137555b3c2a98a1bfab
-
----
- java/org/apache/catalina/Globals.java | 16 ++++++++
- .../apache/catalina/connector/Request.java | 27 +++++++++++++
- java/org/apache/coyote/AbstractProcessor.java | 39 +++++++++++++++++++
- java/org/apache/coyote/ActionCode.java | 14 ++++++-
- .../apache/coyote/http2/StreamProcessor.java | 12 ++++++
- webapps/docs/changelog.xml | 5 +++
- webapps/docs/config/http2.xml | 9 +++++
- 7 files changed, 121 insertions(+), 1 deletion(-)
-
-diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java
-index 994902b..c19d69c 100644
---- a/java/org/apache/catalina/Globals.java
-+++ b/java/org/apache/catalina/Globals.java
-@@ -112,6 +112,22 @@ public final class Globals {
- "org.apache.catalina.NAMED";
-
-
-+ /**
-+ * The request attribute used to expose the current connection ID associated
-+ * with the request, if any. Used with multiplexing protocols such as
-+ * HTTTP/2.
-+ */
-+ public static final String CONNECTION_ID = "org.apache.coyote.connectionID";
-+
-+
-+ /**
-+ * The request attribute used to expose the current stream ID associated
-+ * with the request, if any. Used with multiplexing protocols such as
-+ * HTTTP/2.
-+ */
-+ public static final String STREAM_ID = "org.apache.coyote.streamID";
-+
-+
- /**
- * The servlet context attribute under which we store a flag used
- * to mark this request as having been processed by the SSIServlet.
-diff --git a/java/org/apache/catalina/connector/Request.java b/java/org/apache/catalina/connector/Request.java
-index c4cc26a..94065ef 100644
---- a/java/org/apache/catalina/connector/Request.java
-+++ b/java/org/apache/catalina/connector/Request.java
-@@ -40,6 +40,7 @@ import java.util.TimeZone;
- import java.util.TreeMap;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.atomic.AtomicBoolean;
-+import java.util.concurrent.atomic.AtomicReference;
-
- import javax.naming.NamingException;
- import javax.security.auth.Subject;
-@@ -3487,6 +3488,32 @@ public class Request implements HttpServletRequest {
- // NO-OP
- }
- });
-+ specialAttributes.put(Globals.CONNECTION_ID,
-+ new SpecialAttributeAdapter() {
-+ @Override
-+ public Object get(Request request, String name) {
-+ AtomicReference