This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 6f874083c0 Add tests for trailing header size limit written by CoPilot
/ GPT-5.4
6f874083c0 is described below
commit 6f874083c0d52f064430290ddc1f19a24d990c9b
Author: Mark Thomas <[email protected]>
AuthorDate: Fri Jun 5 19:15:37 2026 +0100
Add tests for trailing header size limit written by CoPilot / GPT-5.4
---
.../http11/filters/TestChunkedInputFilter.java | 108 +++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
b/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
index 0ca664b7e3..54f569cd64 100644
--- a/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
+++ b/test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java
@@ -46,6 +46,7 @@ import org.apache.catalina.startup.TomcatBaseTest;
public class TestChunkedInputFilter extends TomcatBaseTest {
private static final int EXT_SIZE_LIMIT = 10;
+ private static final int TRAILER_SIZE_LIMIT = 8 * 1024;
@Test
public void testChunkHeaderCRLF() throws Exception {
@@ -186,6 +187,71 @@ public class TestChunkedInputFilter extends TomcatBaseTest
{
}
+ @Test
+ public void testTrailingHeadersSizeLimitReadByServletOver8k() throws
Exception {
+ Tomcat tomcat = getTomcatInstance();
+
+ Context ctx = getProgrammaticRootContext();
+
+ BodyReadServlet servlet = new BodyReadServlet(false,
Integer.MAX_VALUE);
+ Tomcat.addServlet(ctx, "servlet", servlet);
+ ctx.addServletMappingDecoded("/", "servlet");
+
+ tomcat.start();
+
+ TrailerClient client = new
TrailerClient(tomcat.getConnector().getLocalPort());
+
client.setRequest(createChunkedRequest(createTrailerHeader(TRAILER_SIZE_LIMIT +
1), true));
+
+ client.connect();
+ Exception processException = null;
+ try {
+ client.processRequest();
+ } catch (Exception e) {
+ processException = e;
+ }
+
+ Assert.assertEquals(7, servlet.getCountRead());
+ Assert.assertTrue(servlet.getExceptionDuringRead());
+ if (processException == null) {
+ Assert.assertTrue(client.getResponseLine(),
client.isResponse500());
+ }
+ }
+
+
+ @Test
+ public void testTrailingHeadersSizeLimitSwallowedOver8k() throws Exception
{
+ Tomcat tomcat = getTomcatInstance();
+
+ Context ctx = getProgrammaticRootContext();
+
+ Tomcat.addServlet(ctx, "servlet", new CommitResponseServlet());
+ ctx.addServletMappingDecoded("/", "servlet");
+
+ tomcat.start();
+
+ TrailerClient client = new
TrailerClient(tomcat.getConnector().getLocalPort());
+ client.setUseContentLength(true);
+
client.setRequest(createChunkedRequest(createTrailerHeader(TRAILER_SIZE_LIMIT +
1), false));
+
+ client.connect();
+ client.sendRequest();
+ client.readResponse(true);
+
+ Assert.assertTrue(client.getResponseLine(), client.isResponse200());
+ Assert.assertEquals("OK", client.getResponseBody());
+
+ client.resetResponse();
+ try {
+ client.sendRequest();
+ client.readResponse(true);
+ } catch (IOException ioe) {
+ // Ignore - in case the read fails due to a closed connection
+ }
+
+ Assert.assertNull(client.getResponseLine());
+ }
+
+
/*
* This test uses the fact that the header is simply concatenated to
insert a pipelined request. The pipelined
* request should not trigger the trailing header size limit. Note that 19
is just enough for the first request.
@@ -262,6 +328,35 @@ public class TestChunkedInputFilter extends TomcatBaseTest
{
}
+ private String[] createChunkedRequest(String trailerHeader, boolean
closeConnection) {
+ String connectionHeader = closeConnection ? "Connection: close" + CRLF
: "";
+
+ // @formatter:off
+ return new String[] {
+ "POST / HTTP/1.1" + CRLF +
+ "Host: localhost" + CRLF +
+ "Transfer-encoding: chunked" + CRLF +
+
SimpleHttpClient.HTTP_HEADER_CONTENT_TYPE_FORM_URL_ENCODING +
+ connectionHeader +
+ CRLF +
+ "3" + CRLF +
+ "a=0" + CRLF +
+ "4" + CRLF +
+ "&b=1" + CRLF +
+ "0" + CRLF +
+ trailerHeader + CRLF +
+ CRLF
+ };
+ // @formatter:on
+ }
+
+
+ private String createTrailerHeader(int totalTrailerSize) {
+ int valueSize = totalTrailerSize - "x-trailer: ".length() - (2 *
CRLF.length());
+ return "x-trailer: " + "x".repeat(valueSize);
+ }
+
+
@Test
public void testExtensionSizeLimitOneBelow() throws Exception {
doTestExtensionSizeLimit(EXT_SIZE_LIMIT - 1, true);
@@ -576,6 +671,19 @@ public class TestChunkedInputFilter extends TomcatBaseTest
{
}
}
+ private static class CommitResponseServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ resp.setContentType("text/plain");
+ resp.setContentLength(2);
+ resp.getWriter().write("OK");
+ resp.flushBuffer();
+ }
+ }
+
private static class EchoHeaderServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]