You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2023/01/30 15:05:20 UTC

[tomcat] branch 10.1.x updated: Fix BZ 66455 - avoid ClassCastException when processing window update

This is an automated email from the ASF dual-hosted git repository.

markt 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 8d2e2967c0 Fix BZ 66455 - avoid ClassCastException when processing window update
8d2e2967c0 is described below

commit 8d2e2967c0a30c250ffa9e4793e8324d2471798e
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Jan 30 11:57:20 2023 +0000

    Fix BZ 66455 - avoid ClassCastException when processing window update
    
    https://bz.apache.org/bugzilla/show_bug.cgi?id=66455
---
 .../apache/coyote/http2/Http2UpgradeHandler.java   |  2 +-
 .../apache/coyote/http2/TestHttp2Section_5_3.java  | 50 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  6 +++
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index 9f1d35aaf6..48d5f449d2 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -1059,13 +1059,13 @@ class Http2UpgradeHandler extends AbstractStream implements InternalHttpUpgradeH
                 if (stream.getConnectionAllocationRequested() > 0) {
                     stream.setConnectionAllocationMade(stream.getConnectionAllocationRequested());
                     stream.setConnectionAllocationRequested(0);
+                    result.add(stream);
                 }
             }
             remaining -= backLogSize;
             backLogSize = 0;
             super.incrementWindowSize(remaining);
 
-            result.addAll(backLogStreams);
             backLogStreams.clear();
         } else {
             allocate(this, remaining);
diff --git a/test/org/apache/coyote/http2/TestHttp2Section_5_3.java b/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
index 32fdb9fed6..4a50528dd6 100644
--- a/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
+++ b/test/org/apache/coyote/http2/TestHttp2Section_5_3.java
@@ -242,6 +242,56 @@ public class TestHttp2Section_5_3 extends Http2TestBase {
     }
 
 
+    @Test
+    public void testReleaseFullBacklog() throws Exception {
+
+        http2Connect();
+
+        // This test uses small window updates that will trigger the excessive
+        // overhead protection so disable it.
+        http2Protocol.setOverheadWindowUpdateThreshold(0);
+        // May also see (rarely, depends on timing) sequential 1 byte data
+        // frames on the same Stream
+        http2Protocol.setOverheadDataThreshold(0);
+
+
+        // Default connection window size is 64k - 1. Initial request will have
+        // used 8k (56k -1). Increase it to 57k
+        sendWindowUpdate(0, 1 + 1024);
+
+        // Use up 56k of the connection window
+        for (int i = 3; i < 17; i += 2) {
+            sendSimpleGetRequest(i);
+            readSimpleGetResponse();
+        }
+
+        output.clearTrace();
+
+        // At this point the connection window should be 1k and any new stream
+        // should have a window of 64k
+
+        // Create priority tree. This test requires a blocked stream to depend on a closed stream
+        sendPriority(17,  15, 15);
+
+        // Process a request on stream 17.
+        // This should consume the connection window and put streams 15 and 17 in the backlog.
+        sendSimpleGetRequest(17);
+        // 17-headers, 17-1k-body
+        parser.readFrame();
+        parser.readFrame();
+        output.clearTrace();
+
+        // At this point 17 is blocked because the connection window is zero
+
+        // Send a large enough Window update to free the whole backlog
+        sendWindowUpdate(0, 8 * 1024);
+
+        parser.readFrame();
+
+        Assert.assertEquals("17-Body-7168\n17-EndOfStream\n", output.getTrace());
+    }
+
+
     private int[] parseBodyFrame(String output) {
         String[] parts = output.trim().split("-");
         if (parts.length != 3 || !"Body".equals(parts[1])) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 82c6c566a4..4e0077ae51 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -132,6 +132,12 @@
         ensure that the end of stream flag is set on the headers frame and that
         no data frame is sent. (markt)
       </fix>
+      <fix>
+        <bug>66455</bug>: Fix the cause of a potential
+        <code>ClassCastException</code> when processing a
+        <code>WINDOW_UPDATE</code> frame on an HTTP/2 connection where the flow
+        control window for the overall connection has been exhausted. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org